Hide keyboard shortcuts

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. 

7 

8import os 

9 

10from xpra.util import WORKSPACE_UNSET, get_util_logger 

11 

12SKIP_METADATA = os.environ.get("XPRA_SKIP_METADATA", "").split(",") 

13 

14 

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 {} 

27 

28 

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)