Changeset 216

Show
Ignore:
Timestamp:
05/28/2008 04:35:12 PM (7 months ago)
Author:
petli
Message:

Stability fixes: handle destroyed windows better in some Client methods; don't crash in CompositionProxy? for GLX-infested visuals

Location:
trunk/plwm
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/plwm/composite.py

    r214 r216  
    1 # $Id: __init__.py,v 1.10 2005/07/10 00:12:19 petli Exp $ 
    2 # 
    31# composite.py - interface plcm to produce visual effects 
    42# 
     
    3533import struct 
    3634 
    37 from Xlib import X, Xatom 
     35from Xlib import X, Xatom, error 
    3836import Xlib.protocol.event 
    3937from Xlib.ext.composite import RedirectManual 
     
    145143        # Is client already composition enabled? 
    146144        if client in self.comp_clients: 
     145            return 
     146 
     147        # Is composition disabled due to strange visuals? 
     148        if client.window._composition_disabled: 
     149            wmanager.debug('composite', 'composition disabled for client %s', client) 
    147150            return 
    148151 
     
    287290        a = window.get_attributes() 
    288291 
     292        # Never trust an X server.  The visual and depth as returned 
     293        # by the methods just called can result in a BadMatch, despite 
     294        # the reasonable assumption that if the client could create a 
     295        # window with those specs, then we can also do it. 
     296 
     297        # The reason for this sad state of affairs is OpenGL: a GLX 
     298        # visual that have 24 bits of colour info _and_ 8 bits of 
     299        # alpha info appears to a non-GL application (e.g. plwm) to 
     300        # have depth 24, but you can't create windows of that depth on 
     301        # it.  An example of an application that does this is 
     302        # OpenOffice 2.0, which is how I found it. 
     303 
     304        # In this case, just create a window on the default visual for 
     305        # the proxy and disable composition for this client (as plcm 
     306        # require that the proxy and the client windows use the same 
     307        # visual). 
     308 
     309        self._composition_disabled = 0 
     310 
     311        ec = error.CatchError(error.BadMatch) 
    289312        self._proxy = screen.root.create_window( 
    290313            g.x, g.y, g.width, g.height, g.border_width, g.depth, 
    291             a.win_class, a.visual) 
    292  
     314            a.win_class, a.visual, onerror = ec) 
     315 
     316        # Check if the mismatch was triggered 
     317        self._wm.display.sync() 
     318 
     319        if ec.get_error(): 
     320            wmanager.debug('composite', 'strange visual, disabling composition for %s', window) 
     321             
     322            self._composition_disabled = 1 
     323            self._proxy = screen.root.create_window( 
     324                g.x, g.y, g.width, g.height, g.border_width, X.CopyFromParent) 
     325             
     326             
    293327        # The proxy window must have the SubstructureRedirectMask set, so 
    294328        # we still get MapRequest, ConfigureRequest etc for the client window. 
     
    307341        self.get_geometry = self._proxy.get_geometry 
    308342        self.circulate = self._proxy.circulate 
     343        self.reparent = self._proxy.reparent 
    309344 
    310345        self._screen.add_proxy_window(self._proxy, window) 
  • trunk/plwm/wmanager.py

    r215 r216  
    288288        if self.withdrawn: 
    289289            return None 
    290         r = self.window.query_pointer() 
     290 
     291        # Handle destroyed windows gracefully, registering the error 
     292        # so the window is withdrawn from managing. 
     293 
     294        try: 
     295            r = self.window.query_pointer() 
     296        except error.BadWindow, e: 
     297            self.wm.events.put_event(e) 
     298            return None 
     299 
    291300        if r.same_screen: 
    292301            return r.win_x, r.win_y 
     
    521530        # mapped, and mostly affect initial state anyway. 
    522531 
    523         # Besides, Netscape does weird things with its requesters: it 
    524         # changes WM_PROTOCOLS just before they are destroyed, giving 
    525         # us a BadWindow traceback if we try to follow that property. 
    526         # Hohum. 
    527  
    528532        if event.atom == Xatom.WM_NORMAL_HINTS: 
    529             self.sizehints = self.window.get_wm_normal_hints() 
     533 
     534            # Handle destroyed windows gracefully, registering the error 
     535            # so the window is withdrawn from managing. 
     536 
     537            try: 
     538                self.sizehints = self.window.get_wm_normal_hints() 
     539            except error.BadWindow, e: 
     540                self.wm.events.put_event(e) 
    530541 
    531542    def handle_destroy_notify(self, event): 
     
    820831        if self.withdrawn: 
    821832            return None 
    822         return self.window.get_wm_name() 
     833 
     834        # Handle destroyed windows gracefully, registering the error 
     835        # so the window is withdrawn from managing. 
     836        try: 
     837            return self.window.get_wm_name() 
     838        except error.BadWindow, e: 
     839            self.wm.events.put_event(e) 
     840            return None 
    823841 
    824842 
     
    839857            return Xutil.WithdrawnState 
    840858 
    841         r = self.window.get_wm_state() 
     859        try: 
     860            r = self.window.get_wm_state() 
     861        except error.BadWindow, e: 
     862            self.wm.events.put_event(e) 
     863            return None 
     864 
    842865        if r: 
    843866            return r.state