cleaning up fullscreen-toggling and other keyboard shortcuts

This commit is contained in:
Eric 2023-10-16 13:38:40 -07:00
parent c42318cccc
commit 2d8b33ceeb
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
17 changed files with 331 additions and 114 deletions

102
.efrocachemap generated
View File

@ -421,7 +421,7 @@
"build/assets/ba_data/audio/zoeOw.ogg": "74befe45a8417e95b6a2233c51992a26",
"build/assets/ba_data/audio/zoePickup01.ogg": "48ab8cddfcde36a750856f3f81dd20c8",
"build/assets/ba_data/audio/zoeScream01.ogg": "2b468aedfa8741090247f04eb9e6df55",
"build/assets/ba_data/data/langdata.json": "992c5c5ce292132c4f011f39e0d13de8",
"build/assets/ba_data/data/langdata.json": "d21a1b7c9444ae7787944498f3ed6482",
"build/assets/ba_data/data/languages/arabic.json": "d1f900ab5aa2433d402bd46ed1149cc7",
"build/assets/ba_data/data/languages/belarussian.json": "e151808b6b4f6dc159cf55ee62adad3c",
"build/assets/ba_data/data/languages/chinese.json": "8d889accdd49334591209bdaf6eaf02f",
@ -430,12 +430,12 @@
"build/assets/ba_data/data/languages/czech.json": "93c5fe0d884d95435da6c675f64e30e0",
"build/assets/ba_data/data/languages/danish.json": "3fd69080783d5c9dcc0af737f02b6f1e",
"build/assets/ba_data/data/languages/dutch.json": "22b44a33bf81142ba2befad14eb5746e",
"build/assets/ba_data/data/languages/english.json": "b38d54aecf3ac47b8d8ca97d8bab3006",
"build/assets/ba_data/data/languages/english.json": "e70277fc6325126d3d893524c8df03c9",
"build/assets/ba_data/data/languages/esperanto.json": "0e397cfa5f3fb8cef5f4a64f21cda880",
"build/assets/ba_data/data/languages/filipino.json": "347f38524816691170d266708fe25894",
"build/assets/ba_data/data/languages/french.json": "d8527da977a563185de25ef02bacf826",
"build/assets/ba_data/data/languages/german.json": "549754d2a530d825200c6126be56df5c",
"build/assets/ba_data/data/languages/gibberish.json": "837423db378b3e7679683805826aa26e",
"build/assets/ba_data/data/languages/german.json": "450fa41ae264f29a5d1af22143d0d0ad",
"build/assets/ba_data/data/languages/gibberish.json": "7863ceeedb1e87eef46f7769bae5f842",
"build/assets/ba_data/data/languages/greek.json": "a65d78f912e9a89f98de004405167a6a",
"build/assets/ba_data/data/languages/hindi.json": "88ee0cda537bab9ac827def5e236fe1a",
"build/assets/ba_data/data/languages/hungarian.json": "796a290a8c44a1e7635208c2ff5fdc6e",
@ -447,12 +447,12 @@
"build/assets/ba_data/data/languages/polish.json": "e1a1a801851924748ad38fa68216439a",
"build/assets/ba_data/data/languages/portuguese.json": "9fcd6b4da9e5d0dc0e337ab00b5debe2",
"build/assets/ba_data/data/languages/romanian.json": "aeebdd54f65939c2facc6ac50c117826",
"build/assets/ba_data/data/languages/russian.json": "910cf653497654a16d5c4f067d6def22",
"build/assets/ba_data/data/languages/russian.json": "7f1689fff58321fdaa632cb9c45105df",
"build/assets/ba_data/data/languages/serbian.json": "d7452dd72ac0e51680cb39b5ebaa1c69",
"build/assets/ba_data/data/languages/slovak.json": "27962d53dc3f7dd4e877cd40faafeeef",
"build/assets/ba_data/data/languages/spanish.json": "0122b0b24aa111ab259af02bbae9b7b6",
"build/assets/ba_data/data/languages/swedish.json": "77d671f10613291ebf9c71da66f18a18",
"build/assets/ba_data/data/languages/tamil.json": "b9d4b4e107456ea6420ee0f9d9d7a03e",
"build/assets/ba_data/data/languages/tamil.json": "65ab7798d637fa62a703750179eeb723",
"build/assets/ba_data/data/languages/thai.json": "33f63753c9af9a5b238d229a0bf23fbc",
"build/assets/ba_data/data/languages/turkish.json": "9d7e58c9062dc517c3779c255a9b3142",
"build/assets/ba_data/data/languages/ukrainian.json": "f72eb51abfbbb56e27866895d7e947d2",
@ -4056,53 +4056,53 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "8ea626f6dd70d998ee77c58fffc51545",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "d7ad10904fe7c4d4555366ccb1feedcb",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "a9eea92d521e97b1772b5e44b402ce8a",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "57043f40971d800d27ee6d646aae8d61",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "3e4009d7fa4b90abc526f56361ecab05",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "334cdc0688e66a1bc75cd05bae1729c7",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "95278d80378be5b61026253492cbfa70",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "0a3da8e5264a7b733960e83a0e8c4bba",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "a089d4aaa39e18553cf0a70a77b4cfcd",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "e66c4eceb79710b8fda2bfea781e241a",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "6b3021b9a7584da86bbb95324e81e851",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "6fe90d50f905a0da9fa52c39a458d1e3",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "afc7ed826486aec82613832865177570",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "ae8b6dad770793188aad8e2966189bb3",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7622dde1a021152cac42e7db3e803392",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "8a4b1e521bf668cc6ec6a65519defb12",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "9a69c0d4c9ae319595843b16f14795fc",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "89c02260fb4781f5e293658cecbb363f",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3165d4230069c22300abfff8abf1d714",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "41e46dfdbb542e3e823f6aee87e93ac9",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "20cc128ff9d44f9d74e4301c6d49f48f",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "f93bc8f98ee31f39b54ab46264eccb22",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "20cc128ff9d44f9d74e4301c6d49f48f",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "f93bc8f98ee31f39b54ab46264eccb22",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "1565f3b227843827d692cb3ef65847b6",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "d8d74c6c40db43054ccc7d27920cfbfe",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "1565f3b227843827d692cb3ef65847b6",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "d8d74c6c40db43054ccc7d27920cfbfe",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "43bdfa8acd84e9cf2e443ce8e923c229",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "d935dc21becdfd65bec51c5f5b2fd770",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "43bdfa8acd84e9cf2e443ce8e923c229",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "d935dc21becdfd65bec51c5f5b2fd770",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "6d49ad39f194480da458b431405f5a2b",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "c8715c85010ea431d7346f40f5421819",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "49775819d4ba9af15061080d17377a18",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "c8715c85010ea431d7346f40f5421819",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "750c2964308cd3f3e5986fcda9a25706",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "772af7da6a115f53b0b3f6a4afd3baec",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "178c1a53a7ad50297aed68d0ca3a1476",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "b011bc2b6437995f2d33f5215b4ffa36",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a758a4f98336208381b093aacb735878",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "6c86545fab2327105114676a20ca5e68",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "f75525fdc9f7db4a81ca9bae6a79add5",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2e297069baec404d43ccdb18abeef658",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "05edee29f50c1d6bee9d3de307248ea6",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "df3990491fab9ac0538e75f347683a94",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "a7efd60daa1a52b0e30a7a9616cc727a",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "2b964e4df219ccf31d204c701abf8b6e",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "67845ed4ac3307559448f9f323e3408f",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "b5934ad96454b3fb945a388141166f17",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "cfec3ecd22fa9467a65f8878efa2b911",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "e748d9e8a1f9b9287194f03a5a9f66d2",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "f3897d23722ab9cf60614dea1abace10",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "74881b34024a827de91dc4e302123548",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "82b5a5410419a738ffb1007f736644c2",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "f732999c2601cf656b850f5f3e9570f4",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "0da70003570c3f392a0f87a823c2adc3",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "1535ddde4b8532a412df37567a1a29a3",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "e04124a9110037eabe1aac45a98891db",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "c07e02b94aa9f50f21bb6571d3a2d5e5",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "ce594cf55f33b80664e5e2c9d59a4ba1",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "26e0fec05e2813fa3e41aa36e3b43df3",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "3957607929916c7ea7f8cde6487e2101",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "96680b806f2997e75904b4222a1e0536",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "80ff019ab0715f68dc4cae15c7a9fdab",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "bbe53e6685130822cbba276f63b76dcb",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "80ff019ab0715f68dc4cae15c7a9fdab",
"build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "bbe53e6685130822cbba276f63b76dcb",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "0d0737d71a7efe201e5ebadeb5f12c71",
"build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "895099e15bad328666f71869f6f09b79",
"build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "0d0737d71a7efe201e5ebadeb5f12c71",
"build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "895099e15bad328666f71869f6f09b79",
"build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "79e38e7d6eb4a5810bbb22e94d4e87ee",
"build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "2cf7ef381bc7408c21f4ea444815233e",
"build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "79e38e7d6eb4a5810bbb22e94d4e87ee",
"build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "2cf7ef381bc7408c21f4ea444815233e",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "5d457e3b58015c9da26a7911a6c8ed5a",
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "70d5ec6b86c91c787a182da729737951",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "444861c2242f3f0b9e09046b6cbf0245",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "70d5ec6b86c91c787a182da729737951",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "4c37ef02c9d97ebf58e9cd4055b557a7",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "5450d7efd2aec4481be61a1315d78af2",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "42a5fefe21fdffdfb62a0f236b33193e",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "d8f2d5d50cfedfff5b1ce1c9c7c52ef4",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "f19d0d8db9b776291dc3bc99f402608e",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c1dea4974ce3723ded4391eca5ae2bfc",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "cf3bbe5f15e76197937e67cfaf2f0a32",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2b8c93e04d1876a787b2a8befbbde004",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "28323912b56ec07701eda3d41a6a4101",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "ba8ce3ca3858b4c2d20db68f99b788b2",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "bb96031e3f844704fcc9a0549a6d2c41",
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "00f81f9bd92386ec12a6e60170678a98",
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "3ceb412513963f0818ab39c58bf292e3",
"src/ballistica/core/mgen/pyembed/binding_core.inc": "9d0a3c9636138e35284923e0c8311c69",

View File

@ -1,4 +1,4 @@
### 1.7.28 (build 21465, api 8, 2023-10-14)
### 1.7.28 (build 21468, api 8, 2023-10-16)
- Massively cleaned up code related to rendering and window systems (OpenGL,
SDL, etc). This code had been growing into a nasty tangle for 15 years
@ -146,7 +146,8 @@
rates are high.
- Added a proper graceful shutdown process for the audio server. This should
result in fewer ugly pops and warning messages when the app is quit.
- Tidied up some keyboard shortcuts to be more platform-appropriate. For
example, toggling fullscreen on Windows is now Alt+Enter or F11.
### 1.7.27 (build 21282, api 8, 2023-08-30)

View File

@ -27,7 +27,10 @@ from _babase import (
apptime,
apptimer,
AppTimer,
can_toggle_fullscreen,
fullscreen_control_available,
fullscreen_control_get,
fullscreen_control_key_shortcut,
fullscreen_control_set,
charstr,
clipboard_get_text,
clipboard_has_text,
@ -200,7 +203,10 @@ __all__ = [
'apptimer',
'AppTimer',
'Call',
'can_toggle_fullscreen',
'fullscreen_control_available',
'fullscreen_control_get',
'fullscreen_control_key_shortcut',
'fullscreen_control_set',
'charstr',
'clipboard_get_text',
'clipboard_has_text',

View File

@ -895,10 +895,18 @@ class App:
import asyncio
# Spin and wait for anything blocking shutdown to complete.
starttime = _babase.apptime()
_babase.lifecyclelog('shutdown-suppress wait begin')
while _babase.shutdown_suppress_count() > 0:
await asyncio.sleep(0.001)
_babase.lifecyclelog('shutdown-suppress wait end')
duration = _babase.apptime() - starttime
if duration > 1.0:
logging.warning(
'Shutdown-suppressions delayed shutdown longer than ideal '
'(%.2f seconds).',
duration,
)
async def _fade_and_shutdown_graphics(self) -> None:
import asyncio

View File

@ -33,18 +33,30 @@ def reset_to_main_menu() -> None:
logging.warning('reset_to_main_menu: no-op due to classic not present.')
def set_config_fullscreen_on() -> None:
def store_config_fullscreen_on() -> None:
"""The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = True
_babase.app.config.commit()
def set_config_fullscreen_off() -> None:
def store_config_fullscreen_off() -> None:
"""The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = False
_babase.app.config.commit()
def set_config_fullscreen_on() -> None:
"""Set and store fullscreen state"""
_babase.app.config['Fullscreen'] = True
_babase.app.config.apply_and_commit()
def set_config_fullscreen_off() -> None:
"""The OS has changed our fullscreen state and we should take note."""
_babase.app.config['Fullscreen'] = False
_babase.app.config.apply_and_commit()
def not_signed_in_screen_message() -> None:
from babase._language import Lstr

View File

@ -40,7 +40,7 @@ if TYPE_CHECKING:
# the last load. Either way, however, multiple execs will happen in some
# form.
#
# So we need to do a few things to handle that situation gracefully.
# To handle that situation gracefully, we need to do a few things:
#
# - First, we need to store any mutable global state in the __main__
# module; not in ourself. This way, alternate versions of ourself will
@ -48,11 +48,11 @@ if TYPE_CHECKING:
#
# - Second, we should avoid the use of isinstance and similar calls for
# our types. An EnvConfig we create would technically be a different
# type than that created by an alternate baenv.
# type than an EnvConfig created by an alternate baenv.
# Build number and version of the ballistica binary we expect to be
# using.
TARGET_BALLISTICA_BUILD = 21465
TARGET_BALLISTICA_BUILD = 21468
TARGET_BALLISTICA_VERSION = '1.7.28'

View File

@ -31,7 +31,10 @@ from babase import (
apptimer,
AppTimer,
Call,
can_toggle_fullscreen,
fullscreen_control_available,
fullscreen_control_get,
fullscreen_control_key_shortcut,
fullscreen_control_set,
charstr,
clipboard_is_supported,
clipboard_set_text,
@ -139,7 +142,10 @@ __all__ = [
'buttonwidget',
'Call',
'can_show_ad',
'can_toggle_fullscreen',
'fullscreen_control_available',
'fullscreen_control_get',
'fullscreen_control_key_shortcut',
'fullscreen_control_set',
'charstr',
'checkboxwidget',
'clipboard_is_supported',

View File

@ -52,7 +52,7 @@ class GraphicsSettingsWindow(bui.Window):
self._show_fullscreen = False
fullscreen_spacing_top = spacing * 0.2
fullscreen_spacing = spacing * 1.2
if bui.can_toggle_fullscreen():
if bui.fullscreen_control_available():
self._show_fullscreen = True
height += fullscreen_spacing + fullscreen_spacing_top
@ -122,21 +122,29 @@ class GraphicsSettingsWindow(bui.Window):
self._fullscreen_checkbox: bui.Widget | None = None
if self._show_fullscreen:
v -= fullscreen_spacing_top
self._fullscreen_checkbox = ConfigCheckBox(
# Fullscreen control does not necessarily talk to the
# app config so we have to wrangle it manually instead of
# using a config-checkbox.
label = bui.Lstr(resource=f'{self._r}.fullScreenText')
# Show keyboard shortcut alongside the control if they
# provide one.
shortcut = bui.fullscreen_control_key_shortcut()
if shortcut is not None:
label = bui.Lstr(
value='$(NAME) [$(SHORTCUT)]',
subs=[('$(NAME)', label), ('$(SHORTCUT)', shortcut)],
)
self._fullscreen_checkbox = bui.checkboxwidget(
parent=self._root_widget,
position=(100, v),
maxwidth=200,
value=bui.fullscreen_control_get(),
on_value_change_call=bui.fullscreen_control_set,
maxwidth=250,
size=(300, 30),
configkey='Fullscreen',
displayname=bui.Lstr(
resource=self._r
+ (
'.fullScreenCmdText'
if app.classic.platform == 'mac'
else '.fullScreenCtrlText'
)
),
).widget
text=label,
)
if not self._have_selected_child:
bui.containerwidget(
edit=self._root_widget,
@ -528,8 +536,10 @@ class GraphicsSettingsWindow(bui.Window):
and bui.apptime() - self._last_max_fps_set_time > 1.0
):
self._apply_max_fps()
if self._show_fullscreen:
# Keep the fullscreen checkbox up to date with the current value.
bui.checkboxwidget(
edit=self._fullscreen_checkbox,
value=bui.app.config.resolve('Fullscreen'),
value=bui.fullscreen_control_get(),
)

View File

@ -15,6 +15,8 @@
#include "ballistica/base/networking/network_reader.h"
#include "ballistica/base/networking/networking.h"
#include "ballistica/base/platform/base_platform.h"
#include "ballistica/base/python/base_python.h"
#include "ballistica/base/support/app_config.h"
#include "ballistica/base/support/stress_test.h"
#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/foundation/event_loop.h"
@ -239,7 +241,7 @@ void AppAdapter::DoExitMainThreadEventLoop() {
FatalError("DoExitMainThreadEventLoop is not implemented here.");
}
auto AppAdapter::CanToggleFullscreen() -> bool const { return false; }
auto AppAdapter::FullscreenControlAvailable() const -> bool { return false; }
auto AppAdapter::SupportsVSync() -> bool const { return false; }
@ -253,6 +255,29 @@ void AppAdapter::DoPushGraphicsContextRunnable(Runnable* runnable) {
DoPushMainThreadRunnable(runnable);
}
auto AppAdapter::FullscreenControlGet() const -> bool {
assert(g_base->InLogicThread());
// By default, just go through config (assume we have full control over
// the fullscreen state ourself).
return g_base->app_config->Resolve(AppConfig::BoolID::kFullscreen);
}
void AppAdapter::FullscreenControlSet(bool fullscreen) {
assert(g_base->InLogicThread());
// By default, just set these in the config and apply it (assumes config
// changes get plugged into actual fullscreen state).
g_base->python->objs()
.Get(fullscreen ? BasePython::ObjID::kSetConfigFullscreenOnCall
: BasePython::ObjID::kSetConfigFullscreenOffCall)
.Call();
}
auto AppAdapter::FullscreenControlKeyShortcut() const
-> std::optional<std::string> {
return {};
}
void AppAdapter::CursorPositionForDraw(float* x, float* y) {
assert(x && y);
@ -271,9 +296,7 @@ auto AppAdapter::ShouldUseCursor() -> bool { return true; }
auto AppAdapter::HasHardwareCursor() -> bool { return false; }
void AppAdapter::SetHardwareCursorVisible(bool visible) {
printf("SHOULD SET VIS %d\n", static_cast<int>(visible));
}
void AppAdapter::SetHardwareCursorVisible(bool visible) {}
auto AppAdapter::CanSoftQuit() -> bool { return false; }
auto AppAdapter::CanBackQuit() -> bool { return false; }

View File

@ -113,9 +113,27 @@ class AppAdapter {
auto app_suspended() const { return app_suspended_; }
/// Return whether this AppAdapter supports a 'fullscreen' toggle for its
/// display. This currently will simply affect whether that option is
/// available in display settings or via a hotkey.
virtual auto CanToggleFullscreen() -> bool const;
/// display. This will affect whether that option is available in display
/// settings or via a hotkey. Must be called from the logic thread.
virtual auto FullscreenControlAvailable() const -> bool;
/// AppAdapters supporting a 'fullscreen' control should return the
/// current fullscreen state here. By default this simply returns the
/// app-config fullscreen value (so assumes the actual state is synced to
/// that). Must be called from the logic thread.
virtual auto FullscreenControlGet() const -> bool;
/// AppAdapters supporting a 'fullscreen' control should set the
/// current fullscreen state here. By default this simply sets the
/// app-config fullscreen value (so assumes the actual state is synced to
/// that). Must be called from the logic thread.
virtual void FullscreenControlSet(bool fullscreen);
/// AppAdapters supporting a 'fullscreen' control can return a key name
/// here to display if they support toggling via key ('ctrl-F', etc.).
/// Must be called from the logic thread.
virtual auto FullscreenControlKeyShortcut() const
-> std::optional<std::string>;
/// Return whether this AppAdapter supports vsync controls for its display.
virtual auto SupportsVSync() -> bool const;

View File

@ -363,8 +363,10 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
// If they hit the window close button, skip the confirm.
g_base->QuitApp(false);
} else {
// By default, confirm before quitting.
g_base->QuitApp(true);
// For all other quits we might want to default to a confirm dialog.
// Update: going to try without confirm for a bit and see how that
// feels.
g_base->QuitApp(false);
}
break;
@ -394,7 +396,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
fullscreen_ = true;
g_base->logic->event_loop()->PushCall([] {
g_base->python->objs()
.Get(BasePython::ObjID::kSetConfigFullscreenOnCall)
.Get(BasePython::ObjID::kStoreConfigFullscreenOnCall)
.Call();
});
}
@ -407,7 +409,7 @@ void AppAdapterSDL::HandleSDLEvent_(const SDL_Event& event) {
fullscreen_ = false;
g_base->logic->event_loop()->PushCall([] {
g_base->python->objs()
.Get(BasePython::ObjID::kSetConfigFullscreenOffCall)
.Get(BasePython::ObjID::kStoreConfigFullscreenOffCall)
.Call();
});
}
@ -818,7 +820,28 @@ void AppAdapterSDL::CursorPositionForDraw(float* x, float* y) {
*y = immediate_y;
}
auto AppAdapterSDL::CanToggleFullscreen() -> bool const { return true; }
auto AppAdapterSDL::FullscreenControlAvailable() const -> bool { return true; }
auto AppAdapterSDL::FullscreenControlKeyShortcut() const
-> std::optional<std::string> {
if (g_buildconfig.ostype_windows()) {
// On Windows we support F11 and Alt+Enter to toggle fullscreen. Let's
// mention Alt+Enter which seems like it might be more commonly used
return "Alt+Enter";
}
if (g_buildconfig.ostype_macos()) {
// The Mac+SDL situation is a bit of a mess. By default, there is 'Enter
// Full Screen' in the window menu which is mapped to fn-F, but that
// will only work if a window was created in SDL as windowed. If we
// fullscreen that window and restart the app, we'll then have a *real*
// fullscreen sdl window and that shortcut won't work anymore. So to
// keep things consistent we advertise ctrl-f which we always handle
// ourselves. Maybe this situation will be cleaned up in SDL 3, but its
// not a huge deal anyway since our Cocoa Mac version behaves cleanly.
return "Ctrl+F";
}
return {};
};
auto AppAdapterSDL::SupportsVSync() -> bool const { return true; }
auto AppAdapterSDL::SupportsMaxFPS() -> bool const { return true; }

View File

@ -34,7 +34,9 @@ class AppAdapterSDL : public AppAdapter {
auto TryRender() -> bool;
auto CanToggleFullscreen() -> bool const override;
auto FullscreenControlAvailable() const -> bool override;
auto FullscreenControlKeyShortcut() const
-> std::optional<std::string> override;
auto SupportsVSync() -> bool const override;
auto SupportsMaxFPS() -> bool const override;

View File

@ -15,6 +15,7 @@
#include "ballistica/base/support/app_config.h"
#include "ballistica/base/ui/dev_console.h"
#include "ballistica/base/ui/ui.h"
#include "ballistica/shared/buildconfig/buildconfig_common.h"
#include "ballistica/shared/foundation/event_loop.h"
#include "ballistica/shared/generic/utils.h"
@ -997,10 +998,26 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
}
}
// Command-F or Control-F toggles full-screen if the app-adapter supports it.
if (g_base->app_adapter->CanToggleFullscreen()) {
if (!repeat_press && keysym.sym == SDLK_f
&& ((keysym.mod & KMOD_CTRL) || (keysym.mod & KMOD_GUI))) {
// Explicitly handle fullscreen-toggles in some cases.
if (g_base->app_adapter->FullscreenControlAvailable()) {
bool do_toggle{};
// On our Mac SDL builds we support ctrl+F for toggling fullscreen.
// On our nice Cocoa build, fullscreening happens magically through the
// view menu fullscreen controls.
if (g_buildconfig.ostype_macos() && !g_buildconfig.xcode_build()) {
if (!repeat_press && keysym.sym == SDLK_f && ((keysym.mod & KMOD_CTRL))) {
do_toggle = true;
}
}
// On Windows we support both F11 and Alt+Enter for toggling fullscreen.
if (g_buildconfig.ostype_windows()) {
if (!repeat_press
&& (keysym.sym == SDLK_F11
|| (keysym.sym == SDLK_RETURN && ((keysym.mod & KMOD_ALT))))) {
do_toggle = true;
}
}
if (do_toggle) {
g_base->python->objs()
.Get(BasePython::ObjID::kToggleFullscreenCall)
.Call();
@ -1008,12 +1025,15 @@ void Input::HandleKeyPress_(const SDL_Keysym& keysym) {
}
}
// Control-Q quits. On Mac, the usual Cmd-Q gets handled
// by the app-adapter implicitly.
if (!repeat_press && keysym.sym == SDLK_q && (keysym.mod & KMOD_CTRL)) {
g_base->QuitApp(true);
return;
}
// Control-Q quits. On Mac, the usual Cmd-Q gets handled implicitly by the
// app-adapter.
// UPDATE: Disabling this for now. Looks like standard OS shortcuts like
// Alt+F4 on windows or Cmd-Q on Mac are doing the right thing with SDL
// builds these days so these are not needed.
// if (!repeat_press && keysym.sym == SDLK_q && (keysym.mod & KMOD_CTRL)) {
// g_base->QuitApp(true);
// return;
// }
// Let the console intercept stuff if it wants at this point.
if (auto* console = g_base->ui->dev_console()) {

View File

@ -38,6 +38,8 @@ class BasePython {
kConfig,
kAppOnNativeBootstrappingCompleteCall,
kResetToMainMenuCall,
kStoreConfigFullscreenOnCall,
kStoreConfigFullscreenOffCall,
kSetConfigFullscreenOnCall,
kSetConfigFullscreenOffCall,
kNotSignedInScreenMessageCall,

View File

@ -12,6 +12,7 @@
#include "ballistica/base/python/support/python_context_call_runnable.h"
#include "ballistica/core/core.h"
#include "ballistica/core/platform/core_platform.h"
#include "ballistica/shared/foundation/macros.h"
#include "ballistica/shared/generic/utils.h"
#include "ballistica/shared/python/python.h"
#include "ballistica/shared/python/python_sys.h"
@ -345,8 +346,7 @@ static PyMethodDef PySafeColorDef = {
// ------------------------ get_max_graphics_quality ---------------------------
static auto PyGetMaxGraphicsQuality(PyObject* self, PyObject* args)
-> PyObject* {
static auto PyGetMaxGraphicsQuality(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
if (g_base->graphics
&& g_base->graphics->has_supports_high_quality_graphics_value()
@ -359,9 +359,9 @@ static auto PyGetMaxGraphicsQuality(PyObject* self, PyObject* args)
}
static PyMethodDef PyGetMaxGraphicsQualityDef = {
"get_max_graphics_quality", // name
PyGetMaxGraphicsQuality, // method
METH_VARARGS, // flags
"get_max_graphics_quality", // name
(PyCFunction)PyGetMaxGraphicsQuality, // method
METH_NOARGS, // flags
"get_max_graphics_quality() -> str\n"
"\n"
@ -619,24 +619,105 @@ static PyMethodDef PyGetDisplayResolutionDef = {
"display. Returns None if resolutions cannot be directly set.",
};
// ------------------------- can_toggle_fullscreen ----------------------------
// ---------------------- fullscreen_control_available -------------------------
static auto PyCanToggleFullscreen(PyObject* self) -> PyObject* {
static auto PyFullscreenControlAvailable(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
if (g_base->app_adapter->CanToggleFullscreen()) {
BA_PRECONDITION(g_base->InLogicThread());
if (g_base->app_adapter->FullscreenControlAvailable()) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyCanToggleFullscreenDef = {
"can_toggle_fullscreen", // name
(PyCFunction)PyCanToggleFullscreen, // method
METH_NOARGS, // flags
static PyMethodDef PyFullscreenControlAvailableDef = {
"fullscreen_control_available", // name
(PyCFunction)PyFullscreenControlAvailable, // method
METH_NOARGS, // flags
"can_toggle_fullscreen() -> bool\n"
"fullscreen_control_available() -> bool\n"
"\n"
"(internal)\n",
};
// --------------------- fullscreen_control_key_shortcut -----------------------
static auto PyFullscreenControlKeyShortcut(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base->InLogicThread());
BA_PRECONDITION(g_base->app_adapter->FullscreenControlAvailable());
auto val = g_base->app_adapter->FullscreenControlKeyShortcut();
if (val.has_value()) {
return PyUnicode_FromString(val->c_str());
}
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyFullscreenControlKeyShortcutDef = {
"fullscreen_control_key_shortcut", // name
(PyCFunction)PyFullscreenControlKeyShortcut, // method
METH_NOARGS, // flags
"fullscreen_control_key_shortcut() -> str | None\n"
"\n"
"(internal)\n",
};
// ------------------------ fullscreen_control_get -----------------------------
static auto PyFullscreenControlGet(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base->InLogicThread());
if (g_base->app_adapter->FullscreenControlGet()) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyFullscreenControlGetDef = {
"fullscreen_control_get", // name
(PyCFunction)PyFullscreenControlGet, // method
METH_NOARGS, // flags
"fullscreen_control_get() -> bool\n"
"\n"
"(internal)\n",
};
// ------------------------ fullscreen_control_set -----------------------------
static auto PyFullscreenControlSet(PyObject* self, PyObject* args,
PyObject* keywds) -> PyObject* {
BA_PYTHON_TRY;
BA_PRECONDITION(g_base->InLogicThread());
int val{};
static const char* kwlist[] = {"val", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "p",
const_cast<char**>(kwlist), &val)) {
return nullptr;
}
g_base->app_adapter->FullscreenControlSet(val);
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}
static PyMethodDef PyFullscreenControlSetDef = {
"fullscreen_control_set", // name
(PyCFunction)PyFullscreenControlSet, // method
METH_VARARGS | METH_KEYWORDS, // flags
"fullscreen_control_set(val: bool) -> None\n"
"\n"
"(internal)\n",
};
@ -728,10 +809,13 @@ auto PythonMethodsGraphics::GetMethods() -> std::vector<PyMethodDef> {
PyGetMaxGraphicsQualityDef,
PySafeColorDef,
PyCharStrDef,
PyCanToggleFullscreenDef,
PyFullscreenControlAvailableDef,
PySupportsVSyncDef,
PySupportsMaxFPSDef,
PyShowProgressBarDef,
PyFullscreenControlKeyShortcutDef,
PyFullscreenControlGetDef,
PyFullscreenControlSetDef,
};
}

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21465;
const int kEngineBuildNumber = 21468;
const char* kEngineVersion = "1.7.28";
const int kEngineApiVersion = 8;

View File

@ -21,6 +21,8 @@ from babase import (
# The C++ layer looks for this variable:
values = [
_hooks.reset_to_main_menu, # kResetToMainMenuCall
_hooks.store_config_fullscreen_on, # kStoreConfigFullscreenOnCall
_hooks.store_config_fullscreen_off, # kStoreConfigFullscreenOffCall
_hooks.set_config_fullscreen_on, # kSetConfigFullscreenOnCall
_hooks.set_config_fullscreen_off, # kSetConfigFullscreenOffCall
_hooks.not_signed_in_screen_message, # kNotSignedInScreenMessageCall