Skip to content

Commit

Permalink
#3476 all x11 window models should have an xid
Browse files Browse the repository at this point in the history
then we can always use it to lookup the model given a gdk window
and use the same code for both 'group-leader' and 'transient-for' metadata
  • Loading branch information
totaam committed Mar 14, 2022
1 parent 6cda08d commit ff4413b
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 55 deletions.
18 changes: 9 additions & 9 deletions xpra/server/mixins/window_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ def is_shown(self, _window) -> bool:
return True


def get_window_id(self, window):
return self._window_to_id.get(window)
def get_window_id(self, _gdkwindow):
#the X11 server can find the model from the window's xid
return 0


def reset_window_filters(self):
Expand All @@ -164,7 +165,7 @@ def get_window_info(self, window):
for prop in window.get_property_names():
if prop=="icons" or prop is None:
continue
metadata = make_window_metadata(window, prop, get_transient_for=self.get_transient_for)
metadata = make_window_metadata(window, prop)
info.update(metadata)
for prop in window.get_internal_property_names():
metadata = make_window_metadata(window, prop)
Expand Down Expand Up @@ -225,10 +226,11 @@ def _do_send_new_window_packet(self, ptype, window, geometry):
x, y, w, h = geometry
#adjust if the transient-for window is not mapped in the same place by the client we send to:
if "transient-for" in window.get_property_names():
transient_for = self.get_transient_for(window)
if transient_for>0:
parent = self._id_to_window.get(transient_for)
parent_ws = ss.get_window_source(transient_for)
transient_for = window.get_property("transient-for")
if transient_for:
window_tf = self.get_window_id(transient_for)
parent = self._id_to_window.get(window_tf)
parent_ws = ss.get_window_source(window_tf)
pos = self.get_window_position(parent)
geomlog("transient-for=%s : %s, ws=%s, pos=%s", transient_for, parent, parent_ws, pos)
if pos and parent and parent_ws:
Expand Down Expand Up @@ -336,8 +338,6 @@ def _window_mapped_at(self, proto, wid, window, coords=None):
else:
ss.unmap_window(wid, window)

def get_transient_for(self, _window):
return 0

def _process_map_window(self, proto, packet):
log.info("_process_map_window(%s, %s)", proto, packet)
Expand Down
3 changes: 0 additions & 3 deletions xpra/server/source/windows_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def is_needed(cls, caps : typedict) -> bool:


def __init__(self):
self.get_transient_for = None
self.get_focus = None
self.get_cursor_data_cb = None
self.get_window_id = None
Expand All @@ -59,7 +58,6 @@ def __init__(self):
self.statistics = None

def init_from(self, _protocol, server):
self.get_transient_for = server.get_transient_for
self.get_focus = server.get_focus
self.get_cursor_data_cb = server.get_cursor_data
self.get_window_id = server.get_window_id
Expand Down Expand Up @@ -391,7 +389,6 @@ def _make_metadata(self, window, propname, skip_defaults=False):
metalog("make_metadata: client does not support '%s'", propname)
return {}
metadata = make_window_metadata(window, propname,
get_transient_for=self.get_transient_for,
get_window_id=self.get_window_id,
skip_defaults=skip_defaults)
if self.readonly:
Expand Down
38 changes: 17 additions & 21 deletions xpra/server/window/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
SKIP_METADATA = os.environ.get("XPRA_SKIP_METADATA", "").split(",")


def make_window_metadata(window, propname, get_transient_for=None, get_window_id=None, skip_defaults=False) -> dict:
def make_window_metadata(window, propname, get_window_id=None, skip_defaults=False) -> dict:
try:
return do_make_window_metadata(window, propname, get_transient_for, get_window_id, skip_defaults)
return do_make_window_metadata(window, propname, get_window_id, skip_defaults)
except (ValueError, TypeError) as e:
log = get_util_logger()
log("make_window_metadata%s",
(window, propname, get_transient_for, get_window_id, skip_defaults), exc_info=True)
(window, propname, get_window_id, skip_defaults), exc_info=True)
log.error("Error: failed to make window metadata")
log.error(" for attribute '%s' of window %s", propname, window)
log.error(" with value '%s':", getattr(window, propname, None))
log.error(" %s", e)
return {}


def do_make_window_metadata(window, propname, get_transient_for=None, get_window_id=None, skip_defaults=False) -> dict:
def do_make_window_metadata(window, propname, get_window_id=None, skip_defaults=False) -> dict:
if propname in SKIP_METADATA:
return {}
#note: some of the properties handled here aren't exported to the clients,
Expand Down Expand Up @@ -83,13 +83,6 @@ def raw():
if not client_machine:
return {}
return {propname : client_machine}
if propname == "transient-for":
wid = None
if get_transient_for:
wid = get_transient_for(window)
if wid:
return {propname : wid}
return {}
if propname in ("window-type", "shape", "children", "hwnd"):
v = raw()
if not v and skip_defaults:
Expand Down Expand Up @@ -128,18 +121,21 @@ def raw():
return {propname : v}
if propname == "xid":
return {propname : hex(raw() or 0)}
if propname == "group-leader":
gl = raw()
if not gl or not get_window_id:
if propname in ("group-leader", "transient-for"):
ref_window = raw()
if not ref_window:
return {}
xid, gdkwin = gl
p = {}
if xid:
p["group-leader-xid"] = xid
if gdkwin and get_window_id:
glwid = get_window_id(gdkwin)
if glwid:
p["group-leader-wid"] = glwid
if hasattr(ref_window, "get_xid"):
#for Gdk X11 windows:
p["%s-xid" % propname] = ref_window.get_xid()
if get_window_id:
wid = get_window_id(ref_window)
if wid:
if propname=="group-leader":
p["%s-wid" % propname] = wid
else:
p["propname"] = wid
return p
#the properties below are not actually exported to the client (yet?)
#it was just easier to handle them here
Expand Down
9 changes: 5 additions & 4 deletions xpra/x11/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,11 @@ def _handle_wm_hints_change(self):
group_leader = None
if "window_group" in wm_hints:
xid = wm_hints.get("window_group")
try:
group_leader = xid, get_pywindow(xid)
except Exception:
group_leader = xid, None
if xid:
try:
group_leader = get_pywindow(xid)
except Exception:
log.error("Error locating group leader window %#x", xid)
self._updateprop("group-leader", group_leader)
self._updateprop("attention-requested", wm_hints.get("urgency", False))
_input = wm_hints.get("input")
Expand Down
18 changes: 0 additions & 18 deletions xpra/x11/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,24 +518,6 @@ def _lookup_window(self, wid):
assert isinstance(wid, int), "window id value '%s' is a %s and not a number" % (wid, type(wid))
return self._id_to_window.get(wid)

def get_transient_for(self, window):
transient_for = window.get_property("transient-for")
log("get_transient_for window=%s, transient_for=%s", window, transient_for)
if transient_for is None:
return 0
xid = transient_for.get_xid()
log("transient_for.xid=%#x", xid)
for w,wid in self._window_to_id.items():
if w.get_property("xid")==xid:
log("found match, window id=%s", wid)
return wid
root = get_default_root_window()
if root.get_xid()==xid:
log("transient-for using root")
return -1 #-1 is the backwards compatible marker for root...
log("not found transient_for=%s, xid=%#x", transient_for, xid)
return 0


def parse_hello_ui_window_settings(self, ss, _caps):
#FIXME: with multiple users, don't set any frame size?
Expand Down
12 changes: 12 additions & 0 deletions xpra/x11/x11_server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,18 @@ def get_window_info(self, window) -> dict:
return info


def get_window_id(self, gdkwindow):
if not gdkwindow:
return 0
xid = gdkwindow.get_xid()
if not xid:
return 0
for wid, window in self._id_to_window.items():
if window.get("xid", 0)==xid:
return wid
return 0


def get_keyboard_config(self, props=typedict()):
from xpra.x11.server_keyboard_config import KeyboardConfig
keyboard_config = KeyboardConfig()
Expand Down

0 comments on commit ff4413b

Please sign in to comment.