Changeset 210

Show
Ignore:
Timestamp:
05/04/2008 04:00:13 PM (8 months ago)
Author:
petli
Message:

plcm: quite experimental composition manager

Location:
trunk
Files:
9 added
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/examples/petliwm.py

    r198 r210  
    3939     mw_clock, mw_acpi, \ 
    4040     mw_watchfiles, \ 
    41      inspect, misc, input 
     41     inspect, misc, input, \ 
     42     composite, mixer 
    4243 
    4344from plwm.cycle import CycleKeys, CycleActivate 
     
    180181               ): 
    181182 
     183    window_proxy_class = composite.CompositeProxy 
     184 
    182185    no_border_clients = name('MPlayer') 
    183186    full_screen_windows = name('MPlayer') 
     
    223226    view_reorder_views = 1 
    224227    view_reorder_delay = 2.0 
    225  
    226     allow_self_changes = none 
     228     
     229    #allow_self_changes = none 
    227230 
    228231class WMConfig: 
     
    239242           mw_watchfiles.ModeWindowWatchFiles, 
    240243           inspect.InspectServer, 
     244           composite.CompositionManager, 
     245           mixer.Mixer, 
    241246           ModeWindowTraceIM, 
    242247           WMConfig): 
     
    251256                                               present_msg = '', 
    252257                                               missing_msg = 'LTM OFF'), 
    253                      mw_watchfiles.WatchedFile('/var/run/network-error', 
    254                                                present_msg = 'NET: %s', 
     258                     mw_watchfiles.WatchedFile('/var/run/tre-network', 
     259                                               present_msg = '3|%s', 
    255260                                               format_content = 1) 
    256261                     ) 
     
    378383        self.wm.current_screen.view_find_with_client(Or(name('xpdf'), 
    379384                                                        name('soffice'), 
    380                                                         name('VCLSalFrame'), 
     385                                                        name('OpenOffice.org 2.0'), 
    381386                                                        name('AcroRead'))) 
    382387 
     
    385390 
    386391    def F8(self, evt): 
    387         self.wm.current_screen.view_find_with_client(name('Vmware')) 
     392        self.wm.current_screen.view_find_with_client(Or(name('Vmware'), 
     393                                                        name('Vmplayer'))) 
    388394 
    389395    def F5(self, evt): 
     
    443449        self.wm.fake_button_click(3) 
    444450 
    445     # def F12(self, evt): 
    446     #           clients = self.wm.query_clients() 
    447     #           f = name('titrax') 
    448     #           for c in clients: 
    449     #               if f(c): 
    450     #                   c.deiconify() 
    451     #                   c.activate() 
    452     #                   return 
    453     #           else: 
    454     #               self.wm.system('/opt/local/bin/titrax') 
     451    # 
     452    # Composition effects 
     453    # 
     454 
     455    def M5_S_b(self, evt): 
     456        if self.wm.current_client: 
     457            self.wm.comp_change_brightness(self.wm.current_client, 16) 
     458 
     459    def M5_b(self, evt): 
     460        if self.wm.current_client: 
     461            self.wm.comp_change_brightness(self.wm.current_client, -16) 
     462             
     463    def M5_C_b(self, evt): 
     464        if self.wm.current_client: 
     465            self.wm.comp_set_brightness(self.wm.current_client, 0) 
    455466 
    456467    # 
     
    458469    # 
    459470 
    460     # def F7(self, evt): 
    461     #         # lower volume.  First main to 50, then pcm to 0 
    462     #         main = self.wm.mixer_get('vol') 
    463     #         if main > 50: 
    464     #             self.wm.mixer_set('vol', max(main - 10, 50)) 
    465     #         else: 
    466     #             pcm = self.wm.mixer_get('pcm') 
    467     #             if pcm > 0: 
    468     #                 self.wm.mixer_set('pcm', max(pcm - 10, 0)) 
    469     #             else: 
    470     #                 self.wm.display.bell(100) 
    471     # 
    472     #         self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
    473     # 
    474     # def F8(self, evt): 
    475     #         # raise volume.  First pcm to 100, then main to 100 
    476     #         pcm = self.wm.mixer_get('pcm') 
    477     #         if pcm < 100: 
    478     #             self.wm.mixer_set('pcm', min(pcm + 10, 100)) 
    479     #         else: 
    480     #             main = self.wm.mixer_get('vol') 
    481     #             if main < 100: 
    482     #                 self.wm.mixer_set('vol', min(main + 10, 100)) 
    483     #             else: 
    484     #                 self.wm.display.bell(-50) 
    485     # 
    486     #         self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
    487     # 
    488     # def S_F7(self, evt): 
    489     #         # toggle mute 
    490     #         self.wm.mixer_mute('pcm') 
    491     #         self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
    492     # 
    493     # S_F8 = S_F7 
     471    def M5_Delete(self, evt): 
     472        # lower volume.  First main to 50, then pcm to 0 
     473        main = self.wm.mixer_get('vol') 
     474        if main > 50: 
     475            self.wm.mixer_set('vol', max(main - 10, 50)) 
     476        else: 
     477            pcm = self.wm.mixer_get('pcm') 
     478            if pcm > 0: 
     479                self.wm.mixer_set('pcm', max(pcm - 10, 0)) 
     480            else: 
     481                self.wm.display.bell(100) 
     482                 
     483        self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
     484     
     485    def M5_Insert(self, evt): 
     486        # raise volume.  First pcm to 100, then main to 100 
     487        pcm = self.wm.mixer_get('pcm') 
     488        if pcm < 100: 
     489            self.wm.mixer_set('pcm', min(pcm + 10, 100)) 
     490        else: 
     491            main = self.wm.mixer_get('vol') 
     492            if main < 100: 
     493                self.wm.mixer_set('vol', min(main + 10, 100)) 
     494            else: 
     495                self.wm.display.bell(-50) 
     496                 
     497        self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
     498     
     499    def M5_End(self, evt): 
     500        # toggle mute 
     501        self.wm.mixer_mute('pcm') 
     502        self.wm.mixer_status_view(devs = ('vol', 'pcm')) 
    494503 
    495504 
  • trunk/plwm

    • Property svn:ignore set to
      *.pyc
  • trunk/plwm/__init__.py

    r203 r210  
    3333            'cfilter', 
    3434            'color', 
     35            'composite', 
    3536            'cycle', 
    3637            'deltamove', 
  • trunk/plwm/wmanager.py

    r201 r210  
    6262 
    6363class Window: 
    64     "A container for all window objects on a screen." 
     64    """Class representing any window object on a screen, either internal 
     65    or client windows. 
     66    """ 
    6567 
    6668    full_screen_windows = cfilter.none 
     
    9496        self.border_width = r.border_width 
    9597 
     98 
     99    def __str__(self): 
     100        return '<%s %s>' % (self.__class__, self.window) 
     101 
     102    def __repr__(self): 
     103        return self.__str__() 
     104 
    96105    # 
    97106    # Internal methods 
     
    200209 
    201210 
     211    def set_border_color(self, color): 
     212        if self.withdrawn: 
     213            return 
     214 
     215        self.window.change_attributes(border_pixel = color) 
     216 
     217 
    202218    def keep_on_screen(self, x, y, width, height): 
    203219        """Return X, Y, WIDTH, HEIGHT after adjusting so the entire window 
     
    284300    def map(self): 
    285301        if self.withdrawn: return None 
     302 
     303        # Perform delayed resizing 
     304        if self.delayed_moveresize: 
     305            self.window.configure(x = self.x, y = self.y, 
     306                                  width = self.width, 
     307                                  height = self.height) 
     308            self.delayed_moveresize = 0 
     309 
    286310        self.window.map() 
    287311 
     
    344368    needs_reparent_clients = cfilter.name('AWTapp') 
    345369 
     370    window_proxy_class = None 
     371     
    346372    def __init__(self, screen, window, maprequest): 
    347373        """Create a client object managing WINDOW. 
     
    353379        """ 
    354380 
     381        # Let any window proxy in on the fun 
     382        if self.window_proxy_class is not None: 
     383            window = self.window_proxy_class(screen, window) 
     384             
    355385        Window.__init__(self, screen, window) 
    356386        self.window.change_save_set(X.SetModeInsert) 
     
    469499            self.window.delete_property(self.wm.WM_STATE) 
    470500 
    471  
     501        # Pass note to proxy, if any, that the window is gone 
     502        if self.window_proxy_class is not None: 
     503            self.window._proxy_withdraw() 
     504 
     505         
    472506    def handle_property_notify(self, event): 
    473507        """Called when a property has changed on the client window. 
     
    555589        self.window.unmap() 
    556590 
     591        debug('client', 'iconify') 
     592         
     593        # Prevent us from recieving UnmapNotify events 
     594        self.dispatch.block_masks(X.StructureNotifyMask) 
     595        self.screen.dispatch.block_masks(X.SubstructureNotifyMask) 
     596 
     597        self.unmap() 
     598 
    557599        self.screen.dispatch.unblock_masks(X.SubstructureNotifyMask) 
    558600        self.dispatch.unblock_masks(X.StructureNotifyMask) 
     
    562604        self.wm.events.put_event(wmevents.ClientIconified(self)) 
    563605 
     606 
    564607    def deiconify(self): 
    565608        if self.withdrawn: 
     
    569612            return 
    570613 
     614        if self.force_iconified: 
     615            return 
     616         
    571617        debug('client', 'deiconify') 
    572  
    573         # Perform delayed resizing 
    574         if self.delayed_moveresize: 
    575             self.window.configure(x = self.x, y = self.y, 
    576                                   width = self.width, 
    577                                   height = self.height) 
    578             self.delayed_moveresize = 0 
    579  
    580         self.window.map() 
     618         
     619        self.map() 
    581620        self.mapped = 1 
    582621        self.window.set_wm_state(state = Xutil.NormalState, icon = 0) 
     
    822861        self.windows = {} 
    823862 
     863        # Map proxy windows to actual windows 
     864        self.proxy_windows = {} 
     865         
    824866        # Set up event handler for this screen 
    825867        self.dispatch = event.WindowDispatcher(self.root) 
     
    839881        # Fix a DISPLAY string for this screen by replacing the 
    840882        # screen number in the DISPLAY with this screen's number 
    841  
     883         
    842884        dstr = self.wm.display.get_display_name() 
    843885        m = re.search(r'(:\d+)(\.\d+)?$', dstr) 
     
    913955        else: 
    914956            debug('clients', 'Adding client for %s', window) 
    915             self.windows[window] = self.wm.client_class(self, window, maprequest) 
    916             self.windows[window].initial_map() 
    917             self.wm.events.put_event(wmevents.AddClient(self.windows[window])) 
     957            client = self.wm.client_class(self, window, maprequest) 
     958 
     959            # Use what client think its window is, to handle proxy windows 
     960            self.windows[client.window] = client 
     961 
     962            client.initial_map() 
     963            self.wm.events.put_event(wmevents.AddClient(client)) 
    918964            return 1 
    919965 
     
    9561002 
    9571003    def get_window(self, window): 
    958         return self.windows.get(window, None) 
     1004        """Translate an Xlib window object into its controlling Window 
     1005        or Client object. 
     1006 
     1007        Returns None if the Xlib window isn't known.  
     1008        """ 
     1009 
     1010        while window is not None: 
     1011            try: 
     1012                return self.windows[window] 
     1013            except KeyError: 
     1014                # Try to translate via proxy window 
     1015                window = self.proxy_windows.get(window, None) 
     1016 
     1017        return None 
     1018 
    9591019 
    9601020    def is_client(self, window): 
    9611021        return isinstance(self.get_window(window), Client) 
     1022     
    9621023 
    9631024    def is_internal_window(self, window): 
    9641025        return isinstance(self.get_window(window), InternalWindow) 
     1026 
     1027 
     1028    def add_proxy_window(self, proxy, window): 
     1029        """Add a proxy window, so that get_window() on PROXY leads on 
     1030        to WINDOW to find the actual Window object. 
     1031        """ 
     1032     
     1033        self.proxy_windows[proxy] = window 
     1034 
     1035 
     1036    def remove_proxy_window(self, proxy): 
     1037        """Remove a proxy window previously registered with add_proxy_window(). 
     1038        """ 
     1039     
     1040        del self.proxy_windows[proxy] 
     1041         
    9651042 
    9661043    def query_clients(self, client_filter = cfilter.all, stackorder = 0): 
     
    17481825 
    17491826 
     1827class WindowProxyBase: 
     1828    """Base class for proxy objects for the real Xlib window objects. 
     1829 
     1830    These proxies can override the Xlib window object methods when 
     1831    necessary. 
     1832    """ 
     1833 
     1834    def __init__(self, screen, window): 
     1835        self._screen = screen 
     1836        self._window = window 
     1837        self._wm = screen.wm 
     1838 
     1839        # These Xlib casts allows the proxy object to be passed to any 
     1840        # Xlib method expecting one of the following objects 
     1841        self.__resource__ = window.__resource__ 
     1842        self.__drawable__ = window.__resource__ 
     1843        self.__window__ = window.__resource__ 
     1844 
     1845        # And these allows the proxy, for dictionary purposes, to 
     1846        # pretend to be the actual window object. 
     1847        self.__cmp__ = window.__cmp__ 
     1848        self.__hash__ = window.__hash__ 
     1849 
     1850 
     1851    def __getattr__(self, attr): 
     1852        # Unknown attribute in the proxy, grab it from the real window instead 
     1853        v = getattr(self._window, attr) 
     1854 
     1855        # And avoid this getting called again for this attr 
     1856        setattr(self, attr, v) 
     1857 
     1858        return v 
     1859 
     1860 
     1861    def _proxy_withdraw(self): 
     1862        """Called by Client when the proxied window is gone, to allow any cleanup. 
     1863        """ 
     1864        pass 
     1865         
     1866 
     1867    def __str__(self): 
     1868        return '<%s for %s 0x%08x>' % ( 
     1869            self.__class__,  
     1870            self._window.__class__, self._window.id) 
     1871 
     1872 
     1873    def __repr__(self): 
     1874        return self.__str__() 
    17501875 
    17511876