Fixed issues with gamescope not properly launching.
This commit is contained in:
@@ -43,6 +43,8 @@ _X_PROPERTY_NOTIFY = 28
|
||||
_X_PROPERTY_CHANGE_MASK = 1 << 22
|
||||
_X_SUBSTRUCTURE_NOTIFY_MASK = 1 << 19
|
||||
_X_SUBSTRUCTURE_REDIRECT_MASK = 1 << 20
|
||||
_X_WM_STATE_WITHDRAWN = 0
|
||||
_X_WM_STATE_NORMAL = 1
|
||||
_X_WM_STATE_ICONIC = 3
|
||||
_NET_WM_STATE_REMOVE = 0
|
||||
_NET_WM_STATE_SOURCE_APPLICATION = 1
|
||||
@@ -448,6 +450,18 @@ class _X11:
|
||||
return None
|
||||
return values[0]
|
||||
|
||||
def restore_normal_window_state(self, window: int) -> bool:
|
||||
"""Undo a nested iconify request without raising the host window."""
|
||||
|
||||
self._replace_long_property(
|
||||
window,
|
||||
b"WM_STATE",
|
||||
b"WM_STATE",
|
||||
(_X_WM_STATE_NORMAL, 0),
|
||||
)
|
||||
self.library.XSync(self.display, 0)
|
||||
return self.window_state(window) == _X_WM_STATE_NORMAL
|
||||
|
||||
def window_is_borderless(self, window: int) -> bool | None:
|
||||
"""Return whether the client currently requests no Motif decorations."""
|
||||
|
||||
@@ -1463,6 +1477,54 @@ def _repair_gamescope_game_window_focus(mapper: _X11, window: int) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _resolve_gamescope_game_window(
|
||||
mapper: _X11,
|
||||
window: int,
|
||||
*,
|
||||
window_title: str,
|
||||
excluded_window_ids: Collection[int],
|
||||
) -> int | None:
|
||||
"""Return a valid nested client across Wine's login-window transition."""
|
||||
|
||||
try:
|
||||
state = mapper.window_state(window)
|
||||
except Exception:
|
||||
state = None
|
||||
if state == _X_WM_STATE_ICONIC:
|
||||
try:
|
||||
if not mapper.restore_normal_window_state(window):
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
print(
|
||||
"Game login window requested minimization; kept it visible inside "
|
||||
"Gamescope.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
return window
|
||||
if state is not None and state != _X_WM_STATE_WITHDRAWN:
|
||||
return window
|
||||
|
||||
try:
|
||||
found = mapper.find_first_window(
|
||||
window_title,
|
||||
excluded_window_ids=set(excluded_window_ids) | {window},
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
if found is None:
|
||||
return None
|
||||
replacement, title = found
|
||||
_apply_game_window_identity(mapper, replacement)
|
||||
print(
|
||||
f"Game login window changed; following it inside Gamescope: {title}",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
return replacement
|
||||
|
||||
|
||||
def _enable_game_window_scaling(mapper: _X11, window: int) -> bool:
|
||||
"""Enable confirmed resize/maximize actions without risking game startup."""
|
||||
|
||||
@@ -1587,9 +1649,14 @@ def _maintain_gamescope_game_window_focus(
|
||||
mapper: _X11,
|
||||
process: subprocess.Popen[bytes],
|
||||
window: int,
|
||||
*,
|
||||
window_title: str = WINDOW_TITLE,
|
||||
existing_window_ids: Collection[int] = (),
|
||||
) -> int:
|
||||
"""Restore nested keyboard focus after host resize/maximize operations."""
|
||||
"""Keep a valid, focused nested client through login and host resizing."""
|
||||
|
||||
active_window: int = window
|
||||
retired_window_ids = set(existing_window_ids)
|
||||
next_focus_repair_at = (
|
||||
time.monotonic() + GAMESCOPE_FOCUS_REPAIR_INTERVAL_SECONDS
|
||||
)
|
||||
@@ -1598,7 +1665,22 @@ def _maintain_gamescope_game_window_focus(
|
||||
now = time.monotonic()
|
||||
if now < next_focus_repair_at:
|
||||
continue
|
||||
_repair_gamescope_game_window_focus(mapper, window)
|
||||
resolved_window = _resolve_gamescope_game_window(
|
||||
mapper,
|
||||
active_window,
|
||||
window_title=window_title,
|
||||
excluded_window_ids=retired_window_ids,
|
||||
)
|
||||
if resolved_window is None:
|
||||
next_focus_repair_at = (
|
||||
time.monotonic() + GAMESCOPE_FOCUS_REPAIR_INTERVAL_SECONDS
|
||||
)
|
||||
continue
|
||||
resolved_window_id = resolved_window
|
||||
if resolved_window_id != active_window:
|
||||
retired_window_ids.add(active_window)
|
||||
active_window = resolved_window_id
|
||||
_repair_gamescope_game_window_focus(mapper, active_window)
|
||||
next_focus_repair_at = (
|
||||
time.monotonic() + GAMESCOPE_FOCUS_REPAIR_INTERVAL_SECONDS
|
||||
)
|
||||
@@ -1785,6 +1867,8 @@ def run_game_window(
|
||||
mapper,
|
||||
process,
|
||||
game_window,
|
||||
window_title=window_title,
|
||||
existing_window_ids=existing_window_ids,
|
||||
)
|
||||
_prepare_game_window(
|
||||
mapper,
|
||||
|
||||
Reference in New Issue
Block a user