Ticket #107: xpra-windowresize.patch
File xpra-windowresize.patch, 20.3 KB (added by , 9 years ago) |
---|
-
wimpiggy/lowlevel/bindings.pyx
2013 2013 pyev.format = e.xclient.format 2014 2014 # I am lazy. Add this later if needed for some reason. 2015 2015 if pyev.format != 32: 2016 log ("Ignoring ClientMessage with format != 32")2016 log.warn("FIXME: Ignoring ClientMessage with format != 32") 2017 2017 return GDK_FILTER_CONTINUE 2018 2018 pieces = [] 2019 2019 for i in xrange(5): … … 2038 2038 pyev.atom = trap.call_synced(get_pyatom, d, 2039 2039 e.xproperty.atom) 2040 2040 elif e.type == ConfigureNotify: 2041 log("ConfigureNotify event received")2042 2041 pyev.window = _gw(d, e.xconfigure.window) 2043 2042 pyev.x = e.xconfigure.x 2044 2043 pyev.y = e.xconfigure.y 2045 2044 pyev.width = e.xconfigure.width 2046 2045 pyev.height = e.xconfigure.height 2047 2046 pyev.border_width = e.xconfigure.border_width 2047 log.info("ConfigureNotify %s event received: %s", pyev.type, (pyev.x, pyev.y, pyev.width, pyev.height)) 2048 log.info("ConfigureNotify pyev.window=%s", pyev.window) 2048 2049 elif e.type == ReparentNotify: 2049 2050 log("ReparentNotify event received") 2050 2051 pyev.window = _gw(d, e.xreparent.window) -
wimpiggy/composite.py
40 40 } 41 41 42 42 # This may raise XError. 43 def __init__(self, window, already_composited ):43 def __init__(self, window, already_composited, forward_our_configure_events_to=None): 44 44 super(CompositeHelper, self).__init__() 45 45 self._window = window 46 46 self._already_composited = already_composited 47 self._forward_our_configure_events_to = forward_our_configure_events_to 47 48 def setup(): 48 49 if not self._already_composited: 49 50 xcomposite_redirect_window(window) … … 149 150 self.invalidate_pixmap() 150 151 151 152 def do_wimpiggy_configure_event(self, event): 153 log.info("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX composite.do_wimpiggy_configure_event(%s), border_width=%s", event, event.border_width) 154 log.info("window is us? %s, delivered to us? %s", event.window is self._window, event.delivered_to is self._window) 152 155 self._border_width = event.border_width 153 156 self.invalidate_pixmap() 157 if event.window is self._window and self._forward_our_configure_events_to: 158 self._forward_our_configure_events_to(event) 154 159 155 160 def do_wimpiggy_reparent_event(self, *args): 156 161 self.invalidate_pixmap() -
wimpiggy/wm.py
135 135 # Public use: 136 136 # A new window has shown up: 137 137 "new-window": one_arg_signal, 138 # A window got resized: 139 "window-resized": one_arg_signal, 138 140 # X11 bell event: 139 141 "bell": one_arg_signal, 140 142 # You can emit this to cause the WM to quit, or the WM may … … 257 259 def bell_event(window_model, event): 258 260 self.do_bell_event(event) 259 261 win.connect("bell", bell_event) 260 #win.connect("bell", self.do_bell_event) 262 def geometry_changed(*args): 263 log.info("geometry_changed(%s)", args) 264 self.emit("window-resized", win) 265 win.connect("geometry", geometry_changed) 261 266 self._windows[gdkwindow] = win 262 267 self._windows_in_order.append(gdkwindow) 263 268 self.notify("windows") … … 296 301 # _NET_RESTACK_WINDOW 297 302 # _NET_WM_DESKTOP 298 303 # _NET_WM_STATE 304 log.info("do_wimpiggy_client_message_event(%s)", event) 299 305 pass 300 306 301 307 def _lost_wm_selection(self, selection): … … 318 324 # anyway, no harm in letting them move existing ones around), and it 319 325 # means that when the window actually gets mapped, we have more 320 326 # accurate info on what the app is actually requesting. 327 log.info("do_child_configure_request_event(%s)", event) 321 328 if event.window in self._windows: 322 329 return 323 330 log("Reconfigure on withdrawn window") -
wimpiggy/window.py
256 256 # Keith Packard says that composite state is undefined following a 257 257 # reparent, so I'm not sure doing this here in the superclass, 258 258 # before we reparent, actually works... let's wait and see. 259 self._composite = CompositeHelper(self.client_window, False )259 self._composite = CompositeHelper(self.client_window, False, self.composite_configure_event) 260 260 h = self._composite.connect("contents-changed", 261 261 self._forward_contents_changed) 262 262 self._damage_forward_handle = h … … 281 281 def do_wimpiggy_configure_event(self, event): 282 282 self._geometry = (event.x, event.y, event.width, event.height, 283 283 event.border_width) 284 log.info("do_wimpiggy_configure_event(%s), geometry=%s", event, self._geometry) 284 285 self.notify("geometry") 285 286 287 def composite_configure_event(self, event): 288 #self.emit("wimpiggy-configure-event", event) 289 log.info("BaseWindowModel.composite_configure_event(%s)", event) 290 286 291 def do_get_property_geometry(self, pspec): 287 292 (x, y, w, h, b) = self._geometry 293 log.info("do_get_property_geometry(%s) _geometry=%s", pspec, self._geometry) 288 294 return (x, y, w + 2*b, h + 2*b) 289 295 290 296 def unmanage(self, exiting=False): … … 448 454 __gsignals__ = { 449 455 # X11 bell event: 450 456 "bell": one_arg_signal, 457 "geometry": one_arg_signal, 451 458 452 459 "ownership-election": (gobject.SIGNAL_RUN_LAST, 453 460 gobject.TYPE_PYOBJECT, (), … … 649 656 def _update_client_geometry(self): 650 657 owner = self.get_property("owner") 651 658 if owner is not None: 652 (allocated_w, allocated_h) = owner.window_size(self) 659 log.info("_update_client_geometry: owner()=%s", owner) 660 def window_size(): 661 return owner.window_size(self) 662 def window_position(w, h): 663 return owner.window_position(self, w, h) 664 self._do_update_client_geometry(window_size, window_position) 665 666 def _do_update_client_geometry(self, window_size_cb, window_position_cb): 667 allocated_w, allocated_h = window_size_cb() 668 log.info("_do_update_client_geometry: %sx%s", allocated_w, allocated_h) 669 hints = self.get_property("size-hints") 670 self._sanitize_size_hints(hints) 671 size = calc_constrained_size(allocated_w, allocated_h, hints) 672 log.info("_do_update_client_geometry: size=%s", size) 673 w, h, wvis, hvis = size 674 x, y = window_position_cb(w, h) 675 log.info("_do_update_client_geometry: position=%s", (x,y)) 676 self.corral_window.move_resize(x, y, w, h) 677 trap.swallow(configureAndNotify, self.client_window, 0, 0, w, h) 678 self._internal_set_property("actual-size", (w, h)) 679 self._internal_set_property("user-friendly-size", (wvis, hvis)) 680 681 def composite_configure_event(self, event): 682 #self.do_wimpiggy_configure_event(event) 683 BaseWindowModel.composite_configure_event(self, event) 684 log.info("WindowModel.composite_configure_event(%s)", event) 685 log.info("composite_configure_event(..) event.geometry: %s", (event.x, event.y, event.width, event.height)) 686 log.info("composite_configure_event(..) corral_window: %s", self.corral_window.get_geometry()) 687 log.info("composite_configure_event(..) client_window: %s", self.client_window.get_geometry()) 688 (_, _, cow, coh, _) = self.corral_window.get_geometry() 689 (_, _, clw, clh, _) = self.client_window.get_geometry() 690 if cow!=clw or coh!=clh: 691 self.corral_window.resize(clw, clh) 653 692 hints = self.get_property("size-hints") 654 693 self._sanitize_size_hints(hints) 655 size = calc_constrained_size(allocated_w, allocated_h, hints) 656 (w, h, wvis, hvis) = size 657 (x, y) = owner.window_position(self, w, h) 658 self.corral_window.move_resize(x, y, w, h) 659 trap.swallow(configureAndNotify, self.client_window, 0, 0, w, h) 694 size = calc_constrained_size(clw, clh, hints) 695 log.info("composite_configure_event: size=%s", size) 696 w, h, wvis, hvis = size 660 697 self._internal_set_property("actual-size", (w, h)) 661 698 self._internal_set_property("user-friendly-size", (wvis, hvis)) 699 self.emit("geometry", event) 662 700 663 701 def do_child_configure_request_event(self, event): 664 702 # Ignore the request, but as per ICCCM 4.1.5, send back a synthetic 665 703 # ConfigureNotify telling the client that nothing has happened. 704 log.info("do_child_configure_request_event(%s)", event) 666 705 trap.swallow(sendConfigureNotify, event.window) 667 706 668 707 # Also potentially update our record of what the app has requested: … … 1231 1270 # widgets. For now the assumption is that we're pretty much always 1232 1271 # going to get a size imposed on us, so no point in spending excessive 1233 1272 # effort figuring out what requisition means in this context. 1273 log.info("do_size_request(%s)", requisition) 1234 1274 (requisition.width, requisition.height) = (100, 100) 1235 1275 1236 1276 def do_size_allocate(self, allocation): 1237 1277 self.allocation = allocation 1238 log ("New allocation = %r", tuple(self.allocation))1278 log.info("New allocation = %r", tuple(self.allocation)) 1239 1279 if self.flags() & gtk.REALIZED: 1240 1280 self.window.move_resize(*allocation) 1241 1281 self._image_window.resize(allocation.width, allocation.height) … … 1246 1286 1247 1287 def window_size(self, model): 1248 1288 assert self.flags() & gtk.REALIZED 1289 log.info("window_size(%s)=%s", model, (self.allocation.width, self.allocation.height)) 1249 1290 return (self.allocation.width, self.allocation.height) 1250 1291 1251 1292 def take_window(self, model, window): -
xpra/client_base.py
113 113 if self.jpegquality: 114 114 capabilities["jpeg"] = self.jpegquality 115 115 capabilities["raw_packets"] = True 116 capabilities["server-window-resize"] = True 116 117 return capabilities 117 118 118 119 def send(self, packet): -
xpra/client.py
212 212 "hello": self._process_hello, 213 213 "new-window": self._process_new_window, 214 214 "new-override-redirect":self._process_new_override_redirect, 215 "window-resized": self._process_window_resized, 215 216 "draw": self._process_draw, 216 217 "cursor": self._process_cursor, 217 218 "bell": self._process_bell, … … 670 671 def _process_new_override_redirect(self, packet): 671 672 self._process_new_common(packet, True) 672 673 674 def _process_window_resized(self, packet): 675 (wid, w, h) = packet[1:4] 676 window = self._id_to_window.get(wid) 677 log.info("_process_window_resized resizing window %s (id=%s) to %s", window, wid, (w,h)) 678 if window: 679 window.resize(w, h) 680 673 681 def _process_draw(self, packet): 674 682 (wid, x, y, width, height, coding, data, packet_sequence, rowstride) = packet[1:10] 675 683 window = self._id_to_window.get(wid) -
xpra/client_window.py
308 308 gobject.idle_add(self._focus_change) 309 309 310 310 def do_configure_event(self, event): 311 log("Got configure event")312 311 gtk.Window.do_configure_event(self, event) 313 if not self._override_redirect: 314 x, y, w, h = get_window_geometry(self) 315 ox, oy = self._pos 316 dx, dy = x-ox, y-oy 317 self._pos = (x, y) 318 if self._client.window_configure: 319 #if we support configure-window, send that first 320 self._client.send(["configure-window", self._id, x, y, w, h]) 321 if dx!=0 or dy!=0: 322 #window has moved 323 if not self._client.window_configure: 324 #if we don't handle the move via configure: 325 self._client.send(["move-window", self._id, x, y]) 326 #move any OR window with their parent: 327 for window in self._override_redirect_windows: 328 x, y = window.get_position() 329 window.move(x+dx, y+dy) 330 if (w, h) != self._size: 331 self._size = (w, h) 332 self.new_backing(w, h) 333 if not self._client.window_configure: 334 self._client.send(["resize-window", self._id, w, h]) 312 if self._override_redirect: 313 return 314 x, y, w, h = get_window_geometry(self) 315 log.info("do_configure_event(%s): new geometry=%s", event, (x, y, w, h)) 316 ox, oy = self._pos 317 dx, dy = x-ox, y-oy 318 self._pos = (x, y) 319 if self._client.window_configure: 320 #if we support configure-window, send that first 321 self._client.send(["configure-window", self._id, x, y, w, h]) 322 if dx!=0 or dy!=0: 323 #window has moved 324 if not self._client.window_configure: 325 #if we don't handle the move via configure: 326 self._client.send(["move-window", self._id, x, y]) 327 #move any OR window with their parent: 328 for window in self._override_redirect_windows: 329 x, y = window.get_position() 330 window.move(x+dx, y+dy) 331 if (w, h) != self._size: 332 self._size = (w, h) 333 self.new_backing(w, h) 334 if not self._client.window_configure: 335 self._client.send(["resize-window", self._id, w, h]) 335 336 336 337 def move_resize(self, x, y, w, h): 337 338 assert self._override_redirect 339 log.info("move_resize(%s)", (x, y, w, h)) 338 340 self.window.move_resize(x, y, w, h) 339 341 self.new_backing(w, h) 340 342 -
xpra/server.py
116 116 assert self.flags() & gtk.REALIZED 117 117 s = AdHocStruct() 118 118 s.shown = False 119 s.geom = (x, y, w, h)119 s.geom = [x, y, w, h] 120 120 s.window = None 121 121 self._models[model] = s 122 122 model.connect("unmanaged", self._unmanaged) 123 123 model.connect("ownership-election", self._elect_me) 124 def new_geom(*args): 125 log.info("new_geom(%s)", args) 126 127 model.connect("geometry", new_geom) 124 128 model.ownership_election() 125 129 126 130 def window_geometry(self, model): … … 133 137 model.set_property("iconic", False) 134 138 135 139 def configure_window(self, model, x, y, w, h): 140 log.info("configure_window(%s, %s, %s, %s, %s)", model, x, y, w, h) 136 141 if not self.visible(model): 137 142 self._models[model].shown = True 138 143 model.set_property("iconic", False) 139 144 model.ownership_election() 140 self._models[model].geom = (x, y, w, h)145 self._models[model].geom = [x, y, w, h] 141 146 model.maybe_recalculate_geometry_for(self) 142 147 143 148 def hide_window(self, model): … … 173 178 self._models[model].window = window 174 179 175 180 def window_size(self, model): 176 (_, _, w, h) = self._models[model].geom181 w, h = self._models[model].geom[2:4] 177 182 return (w, h) 178 183 179 184 def window_position(self, model, w, h): 180 (x, y, w0, h0)= self._models[model].geom185 [x, y, w0, h0] = self._models[model].geom 181 186 if (w0, h0) != (w, h): 182 187 log.warn("Uh-oh, our size doesn't fit window sizing constraints: " 183 188 "%sx%s vs %sx%s", w0, h0, w, h) … … 809 814 ### Create the WM object 810 815 self._wm = Wm("Xpra", clobber) 811 816 self._wm.connect("new-window", self._new_window_signaled) 817 self._wm.connect("window-resized", self._window_resized_signaled) 812 818 self._wm.connect("bell", self._bell_signaled) 813 819 self._wm.connect("quit", lambda _: self.quit(True)) 814 820 … … 1047 1053 if not self.keymap_changing: 1048 1054 self._modifier_map = grok_modifier_map(gtk.gdk.display_get_default(), self.xkbmap_mod_meanings) 1049 1055 1056 def _window_resized_signaled(self, wm, window): 1057 log.info("_window_resized_signaled(%s,%s) actual-size=%s", wm, window, window.get_property("actual-size")) 1058 w,h = window.get_property("actual-size") 1059 geom = self._desktop_manager.window_geometry(window) 1060 geom[2] = w 1061 geom[3] = h 1062 if self.server_window_resize: 1063 self._send(["window-resized", self._window_to_id[window], w, h]) 1064 log.info("_window_resized_signaled(%s,%s) id=%s, new size=%s", wm, window, self._window_to_id.get(window), self._desktop_manager.window_geometry(window)) 1065 1050 1066 def _new_window_signaled(self, wm, window): 1051 1067 self._add_new_window(window) 1052 1068 … … 1802 1818 log.debug("cursors=%s, bell=%s, notifications=%s, clipboard=%s", self.send_cursors, self.send_bell, self.send_notifications, self.clipboard_enabled) 1803 1819 self._wm.enableCursors(self.send_cursors) 1804 1820 self.png_window_icons = "png" in self.encodings and "png" in ENCODINGS 1821 self.server_window_resize = capabilities.get("server-window-resize", False) 1805 1822 # now we can set the modifiers to match the client 1806 1823 modifiers = capabilities.get("modifiers", []) 1807 1824 log.debug("setting modifiers to %s", modifiers) … … 2024 2041 log("cannot map window %s: already removed!", wid) 2025 2042 return 2026 2043 assert not isinstance(window, OverrideRedirectWindowModel) 2027 (_, _, oww, owh) = self._desktop_manager.window_geometry(window) 2044 (owx, owy, oww, owh) = self._desktop_manager.window_geometry(window) 2045 log.info("_process_configure_window(%s) old window geometry: %s", packet, (owx, owy, oww, owh)) 2028 2046 self._desktop_manager.configure_window(window, x, y, w, h) 2029 2047 if self._desktop_manager.visible(window) and (oww!=w or owh!=h): 2030 2048 self._damage(window, 0, 0, w, h) … … 2032 2050 def _process_move_window(self, proto, packet): 2033 2051 (wid, x, y) = packet[1:4] 2034 2052 window = self._id_to_window.get(wid) 2053 log.info("_process_move_window(%s)", packet) 2035 2054 if not window: 2036 2055 log("cannot move window %s: already removed!", wid) 2037 2056 return … … 2042 2061 def _process_resize_window(self, proto, packet): 2043 2062 (wid, w, h) = packet[1:4] 2044 2063 window = self._id_to_window.get(wid) 2064 log.info("_process_resize_window(%s)", packet) 2045 2065 if not window: 2046 2066 log("cannot resize window %s: already removed!", wid) 2047 2067 return … … 2051 2071 self._desktop_manager.configure_window(window, x, y, w, h) 2052 2072 (_, _, ww, wh) = self._desktop_manager.window_geometry(window) 2053 2073 visible = self._desktop_manager.visible(window) 2054 log ("resize_window to %sx%s, desktop manager set it to %sx%s, visible=%s", w, h, ww, wh, visible)2074 log.info("resize_window to %sx%s, desktop manager set it to %sx%s, visible=%s", w, h, ww, wh, visible) 2055 2075 if visible: 2056 self._damage(window, 0, 0, w ,h)2076 self._damage(window, 0, 0, ww, wh) 2057 2077 2058 2078 def _process_focus(self, proto, packet): 2059 2079 wid = packet[1]