xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #107: xpra-windowresize.patch

File xpra-windowresize.patch, 20.3 KB (added by Antoine Martin, 9 years ago)

work in progress patch, definitely not ready for merging, but should work

  • wimpiggy/lowlevel/bindings.pyx

     
    20132013                    pyev.format = e.xclient.format
    20142014                    # I am lazy.  Add this later if needed for some reason.
    20152015                    if pyev.format != 32:
    2016                         log("Ignoring ClientMessage with format != 32")
     2016                        log.warn("FIXME: Ignoring ClientMessage with format != 32")
    20172017                        return GDK_FILTER_CONTINUE
    20182018                    pieces = []
    20192019                    for i in xrange(5):
     
    20382038                    pyev.atom = trap.call_synced(get_pyatom, d,
    20392039                                                 e.xproperty.atom)
    20402040                elif e.type == ConfigureNotify:
    2041                     log("ConfigureNotify event received")
    20422041                    pyev.window = _gw(d, e.xconfigure.window)
    20432042                    pyev.x = e.xconfigure.x
    20442043                    pyev.y = e.xconfigure.y
    20452044                    pyev.width = e.xconfigure.width
    20462045                    pyev.height = e.xconfigure.height
    20472046                    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)
    20482049                elif e.type == ReparentNotify:
    20492050                    log("ReparentNotify event received")
    20502051                    pyev.window = _gw(d, e.xreparent.window)
  • wimpiggy/composite.py

     
    4040        }
    4141
    4242    # This may raise XError.
    43     def __init__(self, window, already_composited):
     43    def __init__(self, window, already_composited, forward_our_configure_events_to=None):
    4444        super(CompositeHelper, self).__init__()
    4545        self._window = window
    4646        self._already_composited = already_composited
     47        self._forward_our_configure_events_to = forward_our_configure_events_to
    4748        def setup():
    4849            if not self._already_composited:
    4950                xcomposite_redirect_window(window)
     
    149150        self.invalidate_pixmap()
    150151
    151152    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)
    152155        self._border_width = event.border_width
    153156        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)
    154159
    155160    def do_wimpiggy_reparent_event(self, *args):
    156161        self.invalidate_pixmap()
  • wimpiggy/wm.py

     
    135135        # Public use:
    136136        # A new window has shown up:
    137137        "new-window": one_arg_signal,
     138        # A window got resized:
     139        "window-resized": one_arg_signal,
    138140        # X11 bell event:
    139141        "bell": one_arg_signal,
    140142        # You can emit this to cause the WM to quit, or the WM may
     
    257259        def bell_event(window_model, event):
    258260            self.do_bell_event(event)
    259261        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)
    261266        self._windows[gdkwindow] = win
    262267        self._windows_in_order.append(gdkwindow)
    263268        self.notify("windows")
     
    296301        #   _NET_RESTACK_WINDOW
    297302        #   _NET_WM_DESKTOP
    298303        #   _NET_WM_STATE
     304        log.info("do_wimpiggy_client_message_event(%s)", event)
    299305        pass
    300306
    301307    def _lost_wm_selection(self, selection):
     
    318324        # anyway, no harm in letting them move existing ones around), and it
    319325        # means that when the window actually gets mapped, we have more
    320326        # accurate info on what the app is actually requesting.
     327        log.info("do_child_configure_request_event(%s)", event)
    321328        if event.window in self._windows:
    322329            return
    323330        log("Reconfigure on withdrawn window")
  • wimpiggy/window.py

     
    256256            # Keith Packard says that composite state is undefined following a
    257257            # reparent, so I'm not sure doing this here in the superclass,
    258258            # 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)
    260260            h = self._composite.connect("contents-changed",
    261261                                        self._forward_contents_changed)
    262262            self._damage_forward_handle = h
     
    281281    def do_wimpiggy_configure_event(self, event):
    282282        self._geometry = (event.x, event.y, event.width, event.height,
    283283                          event.border_width)
     284        log.info("do_wimpiggy_configure_event(%s), geometry=%s", event, self._geometry)
    284285        self.notify("geometry")
    285286
     287    def composite_configure_event(self, event):
     288        #self.emit("wimpiggy-configure-event", event)
     289        log.info("BaseWindowModel.composite_configure_event(%s)", event)
     290
    286291    def do_get_property_geometry(self, pspec):
    287292        (x, y, w, h, b) = self._geometry
     293        log.info("do_get_property_geometry(%s) _geometry=%s", pspec, self._geometry)
    288294        return (x, y, w + 2*b, h + 2*b)
    289295
    290296    def unmanage(self, exiting=False):
     
    448454    __gsignals__ = {
    449455        # X11 bell event:
    450456        "bell": one_arg_signal,
     457        "geometry": one_arg_signal,
    451458       
    452459        "ownership-election": (gobject.SIGNAL_RUN_LAST,
    453460                               gobject.TYPE_PYOBJECT, (),
     
    649656    def _update_client_geometry(self):
    650657        owner = self.get_property("owner")
    651658        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)
    653692            hints = self.get_property("size-hints")
    654693            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
    660697            self._internal_set_property("actual-size", (w, h))
    661698            self._internal_set_property("user-friendly-size", (wvis, hvis))
     699            self.emit("geometry", event)
    662700
    663701    def do_child_configure_request_event(self, event):
    664702        # Ignore the request, but as per ICCCM 4.1.5, send back a synthetic
    665703        # ConfigureNotify telling the client that nothing has happened.
     704        log.info("do_child_configure_request_event(%s)", event)
    666705        trap.swallow(sendConfigureNotify, event.window)
    667706
    668707        # Also potentially update our record of what the app has requested:
     
    12311270        # widgets.  For now the assumption is that we're pretty much always
    12321271        # going to get a size imposed on us, so no point in spending excessive
    12331272        # effort figuring out what requisition means in this context.
     1273        log.info("do_size_request(%s)", requisition)
    12341274        (requisition.width, requisition.height) = (100, 100)
    12351275
    12361276    def do_size_allocate(self, allocation):
    12371277        self.allocation = allocation
    1238         log("New allocation = %r", tuple(self.allocation))
     1278        log.info("New allocation = %r", tuple(self.allocation))
    12391279        if self.flags() & gtk.REALIZED:
    12401280            self.window.move_resize(*allocation)
    12411281            self._image_window.resize(allocation.width, allocation.height)
     
    12461286
    12471287    def window_size(self, model):
    12481288        assert self.flags() & gtk.REALIZED
     1289        log.info("window_size(%s)=%s", model, (self.allocation.width, self.allocation.height))
    12491290        return (self.allocation.width, self.allocation.height)
    12501291
    12511292    def take_window(self, model, window):
  • xpra/client_base.py

     
    113113        if self.jpegquality:
    114114            capabilities["jpeg"] = self.jpegquality
    115115        capabilities["raw_packets"] = True
     116        capabilities["server-window-resize"] = True
    116117        return capabilities
    117118
    118119    def send(self, packet):
  • xpra/client.py

     
    212212            "hello":                self._process_hello,
    213213            "new-window":           self._process_new_window,
    214214            "new-override-redirect":self._process_new_override_redirect,
     215            "window-resized":       self._process_window_resized,
    215216            "draw":                 self._process_draw,
    216217            "cursor":               self._process_cursor,
    217218            "bell":                 self._process_bell,
     
    670671    def _process_new_override_redirect(self, packet):
    671672        self._process_new_common(packet, True)
    672673
     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
    673681    def _process_draw(self, packet):
    674682        (wid, x, y, width, height, coding, data, packet_sequence, rowstride) = packet[1:10]
    675683        window = self._id_to_window.get(wid)
  • xpra/client_window.py

     
    308308        gobject.idle_add(self._focus_change)
    309309
    310310    def do_configure_event(self, event):
    311         log("Got configure event")
    312311        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])
    335336
    336337    def move_resize(self, x, y, w, h):
    337338        assert self._override_redirect
     339        log.info("move_resize(%s)", (x, y, w, h))
    338340        self.window.move_resize(x, y, w, h)
    339341        self.new_backing(w, h)
    340342
  • xpra/server.py

     
    116116        assert self.flags() & gtk.REALIZED
    117117        s = AdHocStruct()
    118118        s.shown = False
    119         s.geom = (x, y, w, h)
     119        s.geom = [x, y, w, h]
    120120        s.window = None
    121121        self._models[model] = s
    122122        model.connect("unmanaged", self._unmanaged)
    123123        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)
    124128        model.ownership_election()
    125129
    126130    def window_geometry(self, model):
     
    133137            model.set_property("iconic", False)
    134138
    135139    def configure_window(self, model, x, y, w, h):
     140        log.info("configure_window(%s, %s, %s, %s, %s)", model, x, y, w, h)
    136141        if not self.visible(model):
    137142            self._models[model].shown = True
    138143            model.set_property("iconic", False)
    139144            model.ownership_election()
    140         self._models[model].geom = (x, y, w, h)
     145        self._models[model].geom = [x, y, w, h]
    141146        model.maybe_recalculate_geometry_for(self)
    142147
    143148    def hide_window(self, model):
     
    173178        self._models[model].window = window
    174179
    175180    def window_size(self, model):
    176         (_, _, w, h) = self._models[model].geom
     181        w, h = self._models[model].geom[2:4]
    177182        return (w, h)
    178183
    179184    def window_position(self, model, w, h):
    180         (x, y, w0, h0) = self._models[model].geom
     185        [x, y, w0, h0] = self._models[model].geom
    181186        if (w0, h0) != (w, h):
    182187            log.warn("Uh-oh, our size doesn't fit window sizing constraints: "
    183188                     "%sx%s vs %sx%s", w0, h0, w, h)
     
    809814        ### Create the WM object
    810815        self._wm = Wm("Xpra", clobber)
    811816        self._wm.connect("new-window", self._new_window_signaled)
     817        self._wm.connect("window-resized", self._window_resized_signaled)
    812818        self._wm.connect("bell", self._bell_signaled)
    813819        self._wm.connect("quit", lambda _: self.quit(True))
    814820
     
    10471053        if not self.keymap_changing:
    10481054            self._modifier_map = grok_modifier_map(gtk.gdk.display_get_default(), self.xkbmap_mod_meanings)
    10491055
     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
    10501066    def _new_window_signaled(self, wm, window):
    10511067        self._add_new_window(window)
    10521068
     
    18021818        log.debug("cursors=%s, bell=%s, notifications=%s, clipboard=%s", self.send_cursors, self.send_bell, self.send_notifications, self.clipboard_enabled)
    18031819        self._wm.enableCursors(self.send_cursors)
    18041820        self.png_window_icons = "png" in self.encodings and "png" in ENCODINGS
     1821        self.server_window_resize = capabilities.get("server-window-resize", False)
    18051822        # now we can set the modifiers to match the client
    18061823        modifiers = capabilities.get("modifiers", [])
    18071824        log.debug("setting modifiers to %s", modifiers)
     
    20242041            log("cannot map window %s: already removed!", wid)
    20252042            return
    20262043        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))
    20282046        self._desktop_manager.configure_window(window, x, y, w, h)
    20292047        if self._desktop_manager.visible(window) and (oww!=w or owh!=h):
    20302048            self._damage(window, 0, 0, w, h)
     
    20322050    def _process_move_window(self, proto, packet):
    20332051        (wid, x, y) = packet[1:4]
    20342052        window = self._id_to_window.get(wid)
     2053        log.info("_process_move_window(%s)", packet)
    20352054        if not window:
    20362055            log("cannot move window %s: already removed!", wid)
    20372056            return
     
    20422061    def _process_resize_window(self, proto, packet):
    20432062        (wid, w, h) = packet[1:4]
    20442063        window = self._id_to_window.get(wid)
     2064        log.info("_process_resize_window(%s)", packet)
    20452065        if not window:
    20462066            log("cannot resize window %s: already removed!", wid)
    20472067            return
     
    20512071        self._desktop_manager.configure_window(window, x, y, w, h)
    20522072        (_, _, ww, wh) = self._desktop_manager.window_geometry(window)
    20532073        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)
    20552075        if visible:
    2056             self._damage(window, 0, 0, w, h)
     2076            self._damage(window, 0, 0, ww, wh)
    20572077
    20582078    def _process_focus(self, proto, packet):
    20592079        wid = packet[1]