Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/window/metadata.py : 69%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2010-2018 Antoine Martin <antoine@xpra.org>
4# Copyright (C) 2008 Nathaniel Smith <njs@pobox.com>
5# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
6# later version. See the file COPYING for details.
8import os
10from xpra.util import WORKSPACE_UNSET, get_util_logger
12SKIP_METADATA = os.environ.get("XPRA_SKIP_METADATA", "").split(",")
15def make_window_metadata(window, propname, get_transient_for=None, get_window_id=None, skip_defaults=False) -> dict:
16 try:
17 return do_make_window_metadata(window, propname, get_transient_for, get_window_id, skip_defaults)
18 except (ValueError, TypeError) as e:
19 log = get_util_logger()
20 log("make_window_metadata%s",
21 (window, propname, get_transient_for, get_window_id, skip_defaults), exc_info=True)
22 log.error("Error: failed to make window metadata")
23 log.error(" for attribute '%s' of window %s", propname, window)
24 log.error(" with value '%s':", getattr(window, propname, None))
25 log.error(" %s", e)
26 return {}
29def do_make_window_metadata(window, propname, get_transient_for=None, get_window_id=None, skip_defaults=False) -> dict:
30 if propname in SKIP_METADATA:
31 return {}
32 #note: some of the properties handled here aren't exported to the clients,
33 #but we do expose them via xpra info
34 def raw():
35 return window.get_property(propname)
36 if propname in ("title", "icon-title", "command", "content-type"):
37 v = raw()
38 if v is None:
39 if skip_defaults:
40 return {}
41 return {propname: ""}
42 return {propname: v.encode("utf-8")}
43 if propname in ("pid", "workspace", "bypass-compositor", "depth", "opacity", "quality", "speed"):
44 v = raw()
45 assert v is not None, "%s is None!" % propname
46 default_value = {
47 "pid" : 0,
48 "workspace" : WORKSPACE_UNSET,
49 "bypass-compositor" : 0,
50 "depth" : 24,
51 "opacity" : 100,
52 }.get(propname, -1)
53 if (v<0 or v==default_value) and skip_defaults:
54 #unset or default value,
55 #so don't bother sending anything:
56 return {}
57 return {propname : v}
58 if propname == "size-hints":
59 #just to confuse things, this is renamed
60 #and we have to filter out ratios as floats (already exported as pairs anyway)
61 v = dict(raw())
62 return {"size-constraints": v}
63 if propname == "strut":
64 strut = raw()
65 if not strut:
66 strut = {}
67 else:
68 strut = strut.todict()
69 if not strut and skip_defaults:
70 return {}
71 return {"strut": strut}
72 if propname == "class-instance":
73 c_i = raw()
74 if c_i is None:
75 return {}
76 return {"class-instance": [x.encode("utf-8") for x in c_i]}
77 if propname == "client-machine":
78 client_machine = raw()
79 if client_machine is None:
80 import socket
81 client_machine = socket.gethostname()
82 if client_machine is None:
83 return {}
84 return {"client-machine": client_machine.encode("utf-8")}
85 if propname == "transient-for":
86 wid = None
87 if get_transient_for:
88 wid = get_transient_for(window)
89 if wid:
90 return {"transient-for" : wid}
91 return {}
92 if propname in ("window-type", "shape", "children"):
93 v = raw()
94 if not v and skip_defaults:
95 return {}
96 #always send unchanged:
97 return {propname : raw()}
98 if propname=="decorations":
99 #-1 means unset, don't send it
100 v = raw()
101 if v<0:
102 return {}
103 return {propname : v}
104 if propname in ("iconic", "fullscreen", "maximized",
105 "above", "below",
106 "shaded", "sticky",
107 "skip-taskbar", "skip-pager",
108 "modal", "focused",
109 ):
110 v = raw()
111 if v is False and skip_defaults:
112 #we can skip those when the window is first created,
113 #but not afterwards when those attributes are toggled
114 return {}
115 #always send these when requested
116 return {propname : bool(raw())}
117 if propname in ("has-alpha", "override-redirect", "tray", "shadow", "set-initial-position"):
118 v = raw()
119 if v is False and skip_defaults:
120 #save space: all these properties are assumed false if unspecified
121 return {}
122 return {propname : v}
123 if propname in ("role", "fullscreen-monitors"):
124 v = raw()
125 if v is None or v=="":
126 return {}
127 return {propname : v}
128 if propname == "xid":
129 return {"xid" : hex(raw() or 0)}
130 if propname == "group-leader":
131 gl = raw()
132 if not gl or not get_window_id:
133 return {}
134 xid, gdkwin = gl
135 p = {}
136 if xid:
137 p["group-leader-xid"] = xid
138 if gdkwin and get_window_id:
139 glwid = get_window_id(gdkwin)
140 if glwid:
141 p["group-leader-wid"] = glwid
142 return p
143 #the properties below are not actually exported to the client (yet?)
144 #it was just easier to handle them here
145 #(convert to a type that can be encoded for xpra info):
146 if propname in ("state", "protocols"):
147 return {"state" : tuple(raw() or [])}
148 if propname == "allowed-actions":
149 return {"allowed-actions" : tuple(raw())}
150 if propname == "frame":
151 frame = raw()
152 if not frame:
153 return {}
154 return {"frame" : tuple(frame)}
155 raise Exception("unhandled property name: %s" % propname)