Skip to content

Commit

Permalink
Merge pull request #419 from RedBearAK/dev_beta
Browse files Browse the repository at this point in the history
Correct handling of window closed state event
  • Loading branch information
RedBearAK authored Oct 6, 2024
2 parents 2803fcf + 029bfcc commit 8b516f4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 29 deletions.
31 changes: 18 additions & 13 deletions cosmic-dbus-service/toshy_cosmic_dbus_service.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
__version__ = '20241003'
__version__ = '20241005'

# Reference for generating the protocol modules with pywayland scanner:
# https://github.com/flacjacket/pywayland/issues/8#issuecomment-987040284
Expand Down Expand Up @@ -252,16 +252,16 @@ def handle_toplevel_event_v2(self,
self.cosmic_to_foreign_map[cosmic_toplvl_handle] = foreign_toplvl_handle

# Event listeners for the foreign toplevel handle
# (cosmic toplevel handle will never emit these)
# (cosmic toplevel handle will never emit these events now, they are deprecated since v2)
foreign_toplvl_handle.dispatcher['title'] = self.handle_title_change
foreign_toplvl_handle.dispatcher['app_id'] = self.handle_app_id_change
foreign_toplvl_handle.dispatcher['closed'] = self.handle_window_closed

# Event listeners for v2 cosmic toplevel handle
# (foreign toplevel handle does not have these events)
cosmic_toplvl_handle.dispatcher['closed'] = self.handle_window_closed
# (foreign toplevel handle does not have the state events)
cosmic_toplvl_handle.dispatcher['state'] = self.handle_state_change

self.display.roundtrip()
# self.display.roundtrip() # Not sure if this is necessary or helpful here

except KeyError as e:
print(f"Error sending get_cosmic_toplevel request: {e}")
Expand All @@ -286,19 +286,24 @@ def handle_title_change(self, handle, title):

def handle_window_closed(self, handle):
"""Remove window from local state."""
foreign_handle: ExtForeignToplevelHandleV1 = None

if self.cosmic_protocol_ver >= 2:
if handle in self.cosmic_to_foreign_map:
foreign_handle = self.cosmic_to_foreign_map.pop(handle, None)
if foreign_handle and foreign_handle in self.wdw_handles_dct:
del self.wdw_handles_dct[foreign_handle]
print(f"Window {foreign_handle} has been closed.")
# Using list() as a wrapper creates a copy of dictionary.items() (which
# produces a dynamic "view object") to iterate over without risking an
# iteration error from modifying the dictionary underlying the items()
# view object.
for cosmic_handle, foreign_handle in list(self.cosmic_to_foreign_map.items()):
if foreign_handle is handle:
del self.cosmic_to_foreign_map[cosmic_handle]
break
if handle and handle in self.wdw_handles_dct:
del self.wdw_handles_dct[handle]
print(f"Window has been closed:\n {handle}")

elif self.cosmic_protocol_ver == 1:
if handle in self.wdw_handles_dct:
if handle and handle in self.wdw_handles_dct:
del self.wdw_handles_dct[handle]
print(f"Window {handle} has been closed.")
print(f"Window has been closed:\n {handle}")

def handle_state_change(self, handle, states_bytes):
"""Track active window app class and title based on state changes."""
Expand Down
41 changes: 25 additions & 16 deletions wlroots-dev/query_cosmic_topl_mgmt_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def cleanup(self):

def print_running_applications(self):
"""Print a complete list of running applications."""
print("\nFull list of running application classes (not windows):")
print("\nFull list of open application windows:")
print(f"{'App ID':<30} {'Title':<50}")
print("-" * 80)
for handle, info in self.wdw_handles_dct.items():
Expand All @@ -112,28 +112,37 @@ def handle_app_id_change(self, handle, app_id):

def handle_window_closed(self, handle):
"""Remove window from local state."""
foreign_handle: ExtForeignToplevelHandleV1 = None

if self.cosmic_protocol_ver >= 2:
if handle in self.cosmic_to_foreign_map:
foreign_handle = self.cosmic_to_foreign_map.pop(handle, None)
if foreign_handle and foreign_handle in self.wdw_handles_dct:
del self.wdw_handles_dct[foreign_handle]
print(f"Window {foreign_handle} has been closed.")
# Using list() as a wrapper creates a copy of dictionary.items() (which
# produces a dynamic "view object") to iterate over without risking an
# iteration error from modifying the dictionary underlying the items()
# view object.
for cosmic_handle, foreign_handle in list(self.cosmic_to_foreign_map.items()):
if foreign_handle is handle:
del self.cosmic_to_foreign_map[cosmic_handle]
break
if handle and handle in self.wdw_handles_dct:
del self.wdw_handles_dct[handle]
print(f"Window has been closed:\n {handle}")

elif self.cosmic_protocol_ver == 1:
if handle in self.wdw_handles_dct:
if handle and handle in self.wdw_handles_dct:
del self.wdw_handles_dct[handle]
print(f"Window {handle} has been closed.")
print(f"Window has been closed:\n {handle}")

def handle_state_change(self, handle, states_bytes):
"""Track active window app class and title based on state changes."""

# Filter out empty state updates (why do these even happen?)
# Filter out empty state events (why do these even happen?)
# Filter out the all-zeroes state (reset event?) before converting
if not states_bytes or states_bytes == b'\x00\x00\x00\x00':
if states_bytes == b'':
print()
print("Received empty bytes value or all-zeroes 4-byte state event, ignoring.")
print(f">>>> Received empty bytes value state event, ignoring: {states_bytes}")
return
elif states_bytes == b'\x00\x00\x00\x00':
print()
print(f">>>> Received all-zeroes 4-byte state event, ignoring: {states_bytes}")
return

# Process states_bytes as an array of 4-byte (32-bit) integers
Expand Down Expand Up @@ -209,16 +218,16 @@ def handle_toplevel_event_v2(self,
self.cosmic_to_foreign_map[cosmic_toplvl_handle] = foreign_toplvl_handle

# Event listeners for the foreign toplevel handle
# (cosmic toplevel handle will never emit these)
# (cosmic toplevel handle will never emit these events now, they are deprecated since v2)
foreign_toplvl_handle.dispatcher['title'] = self.handle_title_change
foreign_toplvl_handle.dispatcher['app_id'] = self.handle_app_id_change
foreign_toplvl_handle.dispatcher['closed'] = self.handle_window_closed

# Event listeners for v2 cosmic toplevel handle
# (foreign toplevel handle does not have these events)
cosmic_toplvl_handle.dispatcher['closed'] = self.handle_window_closed
# (foreign toplevel handle does not have the state events)
cosmic_toplvl_handle.dispatcher['state'] = self.handle_state_change

self.display.roundtrip()
# self.display.roundtrip() # Not sure if this is necessary or helpful here

except KeyError as e:
print(f"Error sending get_cosmic_toplevel request: {e}")
Expand Down

0 comments on commit 8b516f4

Please sign in to comment.