| 1 |  |  | """Wrapper around libwnck for interacting with the window manager""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | __author__ = "Stephan Sokolow (deitarion/SSokolow)" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | __license__ = "GNU GPL 2.0 or later" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | import logging | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | from contextlib import contextmanager | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | import gtk.gdk, wnck           # pylint: disable=import-error | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | from gtk.gdk import Rectangle  # pylint: disable=import-error | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | from .util import clamp_idx, EnumSafeDict, XInitError | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | # Allow MyPy to work without depending on the `typing` package | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | # (And silence complaints from only using the imported types in comments) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | MYPY = False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | if MYPY: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     # pylint: disable=unused-import | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     from typing import Any, List, Optional, Sequence, Tuple, Union  # NOQA | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     from .util import Strut  # NOQA | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | del MYPY | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | #: Lookup table for internal window gravity support. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | #: (libwnck's support is either unreliable or broken) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | GRAVITY = EnumSafeDict({ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     'NORTH_WEST': (0.0, 0.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     'NORTH': (0.5, 0.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     'NORTH_EAST': (1.0, 0.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     'WEST': (0.0, 0.5), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     'CENTER': (0.5, 0.5), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     'EAST': (1.0, 0.5), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     'SOUTH_WEST': (0.0, 1.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     'SOUTH': (0.5, 1.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     'SOUTH_EAST': (1.0, 1.0), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | }) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | key, val = None, None  # Safety cushion for the "del" line. | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  | for key, val in GRAVITY.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     # Support GDK gravity constants | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     GRAVITY[getattr(gtk.gdk, 'GRAVITY_%s' % key)] = val | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     # Support libwnck gravity constants | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     _name = 'WINDOW_GRAVITY_%s' % key.replace('_', '') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     GRAVITY[getattr(wnck, _name)] = val | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | # Prevent these temporary variables from showing up in the apidocs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | del _name, key, val | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | # --- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  | @contextmanager | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | def persist_maximization(win, keep_maximize=True): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |     """Context manager to persist maximization state after a reposition | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     If C{keep_maximize=False}, this becomes a no-op to ease writing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     clean code which needs to support both behaviours. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     # Unmaximize and record the types we may need to restore | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     max_types, maxed = ['', '_horizontally', '_vertically'], [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     for maxtype in max_types: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         if getattr(win, 'is_maximized' + maxtype)(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             maxed.append(maxtype) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             getattr(win, 'unmaximize' + maxtype)() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |     yield | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     # Restore maximization if asked | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |     if maxed and keep_maximize: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         for maxtype in maxed: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |             getattr(win, 'maximize' + maxtype)() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  | class WorkArea(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     """Helper to calculate and query available workarea on the desktop.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     def __init__(self, gdk_screen, ignore_struts=False): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         # type: (gtk.gdk.Screen, bool) -> None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         self.gdk_screen = gdk_screen | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         self.ignore_struts = ignore_struts | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |     def get_struts(self, root_win):  # type: (gtk.gdk.Window) -> List[Strut] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |         """Retrieve the struts from the root window if supported.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         if not self.gdk_screen.supports_net_wm_hint("_NET_WM_STRUT_PARTIAL"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |             return [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         # Gather all struts | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         struts = [root_win.property_get("_NET_WM_STRUT_PARTIAL")] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         if self.gdk_screen.supports_net_wm_hint("_NET_CLIENT_LIST"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |             # Source: http://stackoverflow.com/a/11332614/435253 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |             for wid in root_win.property_get('_NET_CLIENT_LIST')[2]: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |                 w = gtk.gdk.window_foreign_new(wid) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |                 struts.append(w.property_get("_NET_WM_STRUT_PARTIAL")) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         struts = [tuple(x[2]) for x in struts if x] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         logging.debug("Gathered _NET_WM_STRUT_PARTIAL values:\n\t%s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |                       struts) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         return struts | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |     def subtract_struts(self, usable_region,  # type: gtk.gdk.Region | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                         struts                # type: Sequence[Strut] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |                         ):  # type: (...) -> Tuple[gtk.gdk.Region, Rectangle] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |         """Subtract the given struts from the given region.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |         # Subtract the struts from the usable region | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         _Sub = lambda *g: usable_region.subtract( | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |             gtk.gdk.region_rectangle(g)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |         _w, _h = self.gdk_screen.get_width(), self.gdk_screen.get_height() | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         for g in struts:  # pylint: disable=invalid-name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |             # http://standards.freedesktop.org/wm-spec/1.5/ar01s05.html | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |             # XXX: Must not cache unless watching for notify events. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |             _Sub(0, g[4], g[0], g[5] - g[4] + 1)             # left | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |             _Sub(_w - g[1], g[6], g[1], g[7] - g[6] + 1)     # right | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |             _Sub(g[8], 0, g[9] - g[8] + 1, g[2])             # top | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |             _Sub(g[10], _h - g[3], g[11] - g[10] + 1, g[3])  # bottom | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         # Generate a more restrictive version used as a fallback | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         usable_rect = usable_region.copy() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         _Sub = lambda *g: usable_rect.subtract(gtk.gdk.region_rectangle(g)) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         for geom in struts: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |             # http://standards.freedesktop.org/wm-spec/1.5/ar01s05.html | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             # XXX: Must not cache unless watching for notify events. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             _Sub(0, geom[4], geom[0], _h)             # left | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |             _Sub(_w - geom[1], geom[6], geom[1], _h)  # right | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             _Sub(0, 0, _w, geom[2])                   # top | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             _Sub(0, _h - geom[3], _w, geom[3])        # bottom | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |             # TODO: The required "+ 1" in certain spots confirms that we're | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |             #       going to need unit tests which actually check that the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             #       WM's code for constraining windows to the usable area | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |             #       doesn't cause off-by-one bugs. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             # TODO: Share this on http://stackoverflow.com/q/2598580/435253 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |         return usable_rect.get_clipbox(), usable_region | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |     def get(self, monitor, ignore_struts=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         # type: (Rectangle, bool) -> Tuple[gtk.gdk.Region, Rectangle] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         """Retrieve the usable area of the specified monitor using | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         the most expressive method the window manager supports. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |         @param monitor: The number or dimensions of the desired monitor. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         @param ignore_struts: If C{True}, just return the size of the whole | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |             monitor, allowing windows to overlap panels. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         @type monitor: C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         @type ignore_struts: C{bool} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         @returns: The usable region and its largest rectangular subset. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         @rtype: C{gtk.gdk.Region}, C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         # Get the region and return failure early if it's empty | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         usable_rect, usable_region = monitor, gtk.gdk.region_rectangle(monitor) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |         if not usable_region.get_rectangles(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |             logging.error("WorkArea.get_monitor_rect received " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |                           "an empty monitor region!") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |             return None, None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |         # Return early if asked to ignore struts | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |         if ignore_struts or (ignore_struts is None and self.ignore_struts): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |             logging.debug("Panels ignored. Reported monitor geometry is:\n%s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |                           usable_rect) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |             return usable_region, usable_rect | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         # Get the list of struts from the root window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |         root_win = self.gdk_screen.get_root_window() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         struts = self.get_struts(root_win) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         # Fall back to _NET_WORKAREA if we couldn't get any struts | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         if struts: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |             usable_rect, usable_region = self.subtract_struts(usable_region, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |                                                               struts) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |         elif self.gdk_screen.supports_net_wm_hint("_NET_WORKAREA"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |             desktop_geo = tuple(root_win.property_get('_NET_WORKAREA')[2][0:4]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |             logging.debug("Falling back to _NET_WORKAREA: %s", desktop_geo) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |             usable_region.intersect(gtk.gdk.region_rectangle(desktop_geo)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |             usable_rect = usable_region.get_clipbox() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |         # FIXME: Only call get_rectangles if --debug | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |         logging.debug("Usable region of monitor calculated as:\n" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |                       "\tRegion: %r\n\tRectangle: %r", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |                       usable_region.get_rectangles(), usable_rect) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |         return usable_region, usable_rect | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  | class WindowManager(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |     """A simple API-wrapper class for manipulating window positioning.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |     def __init__(self, screen=None, ignore_workarea=False): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |         # type: (gtk.gdk.Screen, bool) -> None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |         Initializes C{WindowManager}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         @param screen: The X11 screen to operate on. If C{None}, the default | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |             screen as retrieved by C{gtk.gdk.screen_get_default} will be used. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         @type screen: C{gtk.gdk.Screen} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         @todo: Confirm that the root window only changes on X11 server | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |                restart. (Something which will crash QuickTile anyway since | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |                PyGTK makes X server disconnects uncatchable.) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |                It could possibly change while toggling "allow desktop icons" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |                in KDE 3.x. (Not sure what would be equivalent elsewhere) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |         self.gdk_screen = screen or gtk.gdk.screen_get_default() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         if self.gdk_screen is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |             raise XInitError("GTK+ could not open a connection to the X server" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |                              " (bad DISPLAY value?)") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |         # pylint: disable=no-member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |         self.screen = wnck.screen_get(self.gdk_screen.get_number()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |         self.workarea = WorkArea(self.gdk_screen, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |                                  ignore_struts=ignore_workarea) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |     def calc_win_gravity(geom, gravity): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |         # (Rectangle, Tuple[float, float]) -> Tuple[int, int] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |         """Calculate the X and Y coordinates necessary to simulate non-topleft | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         gravity on a window. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |         @param geom: The window geometry to which to apply the corrections. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |         @param gravity: A desired gravity chosen from L{GRAVITY}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |         @type geom: C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |         @type gravity: C{wnck.WINDOW_GRAVITY_*} or C{gtk.gdk.GRAVITY_*} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |         @returns: The coordinates to be used to achieve the desired position. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |         @rtype: C{(x, y)} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |         This exists because, for whatever reason, whether it's wnck, Openbox, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |         or both at fault, the WM's support for window gravities seems to have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |         no effect beyond double-compensating for window border thickness unless | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |         using WINDOW_GRAVITY_STATIC. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |         My best guess is that the gravity modifiers are being applied to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |         window frame rather than the window itself, hence static gravity would | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         position correctly and north-west gravity would double-compensate for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |         the titlebar and border dimensions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |         ...however, that still doesn't explain why the non-topleft gravities | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |         have no effect. I'm guessing something's just broken. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |         grav_x, grav_y = GRAVITY[gravity] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |         return ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |             int(geom.x - (geom.width * grav_x)), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |             int(geom.y - (geom.height * grav_y)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |         ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |     def get_geometry_rel(window, monitor_geom): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |         # type: (wnck.Window, Rectangle) -> Rectangle | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         """Get window position relative to the monitor rather than the desktop. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |         @param monitor_geom: The rectangle returned by | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |             C{gdk.Screen.get_monitor_geometry} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |         @type window: C{wnck.Window} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |         @type monitor_geom: C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |         @rtype: C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |         win_geom = Rectangle(*window.get_geometry()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |         win_geom.x -= monitor_geom.x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |         win_geom.y -= monitor_geom.y | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |         return win_geom | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 261 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 262 |  |  |     def get_monitor(self, win): | 
            
                                                                        
                            
            
                                    
            
            
                | 263 |  |  |         # type: (wnck.Window) -> Tuple[int, Rectangle] | 
            
                                                                        
                            
            
                                    
            
            
                | 264 |  |  |         """Given a C{wnck.Window}, retrieve the monitor ID and geometry. | 
            
                                                                        
                            
            
                                    
            
            
                | 265 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 266 |  |  |         @type win: C{wnck.Window} | 
            
                                                                        
                            
            
                                    
            
            
                | 267 |  |  |         @returns: A tuple containing the monitor ID and geometry. | 
            
                                                                        
                            
            
                                    
            
            
                | 268 |  |  |         @rtype: C{(int, gtk.gdk.Rectangle)} | 
            
                                                                        
                            
            
                                    
            
            
                | 269 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 270 |  |  |         # TODO: Look for a way to get the monitor ID without having | 
            
                                                                        
                            
            
                                    
            
            
                | 271 |  |  |         #       to instantiate a gtk.gdk.Window | 
            
                                                                        
                            
            
                                    
            
            
                | 272 |  |  |         if not isinstance(win, gtk.gdk.Window): | 
            
                                                                        
                            
            
                                    
            
            
                | 273 |  |  |             win = gtk.gdk.window_foreign_new(win.get_xid()) | 
            
                                                                        
                            
            
                                    
            
            
                | 274 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 275 |  |  |         # TODO: How do I retrieve the root window from a given one? | 
            
                                                                        
                            
            
                                    
            
            
                | 276 |  |  |         monitor_id = self.gdk_screen.get_monitor_at_window(win) | 
            
                                                                        
                            
            
                                    
            
            
                | 277 |  |  |         monitor_geom = self.gdk_screen.get_monitor_geometry(monitor_id) | 
            
                                                                        
                            
            
                                    
            
            
                | 278 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 279 |  |  |         logging.debug(" Window is on monitor %s, which has geometry %s", | 
            
                                                                        
                            
            
                                    
            
            
                | 280 |  |  |                       monitor_id, monitor_geom) | 
            
                                                                        
                            
            
                                    
            
            
                | 281 |  |  |         return monitor_id, monitor_geom | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |     def _get_win_for_prop(self, window=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |         # type: (Optional[wnck.Window]) -> gtk.gdk.Window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |         """Retrieve a GdkWindow for a given WnckWindow, or the root if None.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |         if window: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |             return gtk.gdk.window_foreign_new(window.get_xid()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |             return self.gdk_screen.get_root_window() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |     def get_property(self, key, window=None): | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |         # type: (str, Optional[wnck.Window]) -> Any | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |         """Retrieve the value of a property on the given window. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |         @param window: If unset, the root window will be queried. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |         @type window: C{wnck.Window} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |         return self._get_win_for_prop(window).property_get(key) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |     def set_property(self, key,   # type: str | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |                      value,       # type: Union[Sequence[int], int, str] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |                      window=None  # type: Optional[wnck.Window] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |                      ):           # type: (...) -> None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |         """Set the value of a property on the given window. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |         @param window: If unset, the root window will be queried. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |         @type window: C{wnck.Window} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |         if isinstance(value, basestring): | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |             prop_format = 8 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |             prop_type = "STRING" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |             prop_format = 32 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |             prop_type = "CARDINAL" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |             if isinstance(value, int): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |                 value = [value] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |         self._get_win_for_prop(window).property_change( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |             key, prop_type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |             prop_format, gtk.gdk.PROP_MODE_REPLACE, value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |     def del_property(self, key, window=None): | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |         # type: (str, Optional[wnck.Window]) -> None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |         """Unset a property on the given window. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |         @param window: If unset, the root window will be queried. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |         @type window: C{wnck.Window} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |         self._get_win_for_prop(window).property_delete(key) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |     def get_relevant_windows(self, workspace): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |         """C{wnck.Screen.get_windows} without WINDOW_DESKTOP/DOCK windows.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |         for window in self.screen.get_windows(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |             # Skip windows on other virtual desktops for intuitiveness | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |             if workspace and not window.is_on_workspace(workspace): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |                 logging.debug("Skipping window on other workspace: %r", window) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |                 continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |             # Don't cycle elements of the desktop | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |             if not self.is_relevant(window): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |                 continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |             yield window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |     def get_workspace(self, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |                       window=None,      # type: wnck.Window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |                       direction=None,   # type: wnck.MotionDirection | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |                       wrap_around=True  # type: bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |                       ):                # type: (...) -> wnck.Workspace | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |         """Get a workspace relative to either a window or the active one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |         @param window: The point of reference. C{None} for the active workspace | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |         @param direction: The direction in which to look, relative to the point | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |             of reference. Accepts the following types: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |              - C{wnck.MotionDirection}: Non-cycling direction | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |              - C{int}: Relative index in the list of workspaces | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |              - C{None}: Just get the workspace object for the point of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |                reference | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |         @param wrap_around: Whether relative indexes should wrap around. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |         @type window: C{wnck.Window} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |         @type wrap_around: C{bool} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         @rtype: C{wnck.Workspace} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |         @returns: The workspace object or C{None} if no match could be found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |         if window: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |             cur = window.get_workspace() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |             cur = self.screen.get_active_workspace() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |         if not cur: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |             return None  # It's either pinned or on no workspaces | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |         # pylint: disable=no-member | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         if isinstance(direction, wnck.MotionDirection): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |             nxt = cur.get_neighbor(direction) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |         elif isinstance(direction, int): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |             # TODO: Deduplicate with the wrapping code in commands.py | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |             n_spaces = self.screen.get_workspace_count() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |             nxt = self.screen.get_workspace( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |                 clamp_idx(cur.get_number() + direction, n_spaces, wrap_around)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |         elif direction is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |             nxt = cur | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |             nxt = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |             logging.warn("Unrecognized direction: %r", direction) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         return nxt | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |     def is_relevant(window): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |         # type: (wnck.Window) -> bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |         """Return False if the window should be ignored. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |         (eg. If it's the desktop or a panel) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |         if not window: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |             logging.debug("Received no window object to manipulate") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |             return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |         if window.get_window_type() in [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |                 wnck.WINDOW_DESKTOP,  # pylint: disable=E1101 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |                 wnck.WINDOW_DOCK]:    # pylint: disable=E1101 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |             logging.debug("Irrelevant window: %r", window) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |             return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |         # TODO: Support customizations to exclude things like my Conky window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |         # (Which I can't make a `desktop` window because I sometimes drag it) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |         return True | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |     def reposition(self, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |             win,                                    # type: wnck.Window | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |             geom=None,                              # type: Optional[Rectangle] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |             monitor=Rectangle(0, 0, 0, 0),          # type: Rectangle | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |             keep_maximize=False,                    # type: bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |             gravity=wnck.WINDOW_GRAVITY_NORTHWEST, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |             geometry_mask=wnck.WINDOW_CHANGE_X | wnck.WINDOW_CHANGE_Y | | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |                 wnck.WINDOW_CHANGE_WIDTH | | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |                 wnck.WINDOW_CHANGE_HEIGHT  # type: wnck.WindowMoveResizeMask | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |                    ):  # pylint: disable=no-member,too-many-arguments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |         # type: (...) -> None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |         # TODO: Complete MyPy type signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |         # pylint:disable=line-too-long | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |         Position and size a window, decorations inclusive, according to the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |         provided target window and monitor geometry rectangles. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |         If no monitor rectangle is specified, position relative to the desktop | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |         as a whole. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |         @param win: The C{wnck.Window} to operate on. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |         @param geom: The new geometry for the window. Can be left unspecified | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |             if the intent is to move the window to another monitor without | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |             repositioning it. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |         @param monitor: The frame relative to which C{geom} should be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |             interpreted. The whole desktop if unspecified. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |         @param keep_maximize: Whether to re-maximize a maximized window after | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |             un-maximizing it to move it. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |         @param gravity: A constant specifying which point on the window is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |             referred to by the X and Y coordinates in C{geom}. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |         @param geometry_mask: A set of flags determining which aspects of the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |             requested geometry should actually be applied to the window. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |             (Allows the same geometry definition to easily be shared between | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |             operations like move and resize.) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |         @type win: C{wnck.Window} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |         @type geom: C{gtk.gdk.Rectangle} or C{None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |         @type monitor: C{gtk.gdk.Rectangle} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |         @type keep_maximize: C{bool} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |         @type gravity: U{WnckWindowGravity<https://developer.gnome.org/libwnck/stable/WnckWindow.html#WnckWindowGravity>} or U{GDK Gravity Constant<http://www.pygtk.org/docs/pygtk/gdk-constants.html#gdk-gravity-constants>} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |         @type geometry_mask: U{WnckWindowMoveResizeMask<https://developer.gnome.org/libwnck/2.30/WnckWindow.html#WnckWindowMoveResizeMask>} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  |         @todo 1.0.0: Look for a way to accomplish this with a cleaner method | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |             signature. This is getting a little hairy. (API-breaking change) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |         """  # NOQA | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |         # We need to ensure that ignored values are still present for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |         # gravity calculations. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |         old_geom = self.get_geometry_rel(win, self.get_monitor(win)[1]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |         if geom: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |             for attr in ('x', 'y', 'width', 'height'): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |                 if not geometry_mask & getattr(wnck, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |                         'WINDOW_CHANGE_%s' % attr.upper()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  |                     setattr(geom, attr, getattr(old_geom, attr)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |             geom = old_geom | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  |         with persist_maximization(win, keep_maximize): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  |             # Apply gravity and resolve to absolute desktop coordinates. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |             new_x, new_y = self.calc_win_gravity(geom, gravity) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 |  |  |             new_x += monitor.x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 |  |  |             new_y += monitor.y | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 |  |  |             logging.debug(" Repositioning to (%d, %d, %d, %d)\n", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 |  |  |                     new_x, new_y, geom.width, geom.height) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  |             # See the calc_win_gravity docstring for the rationale here | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  |             win.set_geometry(wnck.WINDOW_GRAVITY_STATIC, geometry_mask, | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 483 |  |  |                     new_x, new_y, geom.width, geom.height) | 
            
                                                        
            
                                    
            
            
                | 484 |  |  |  | 
            
                        
This check looks for invalid names for a range of different identifiers.
You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.
If your project includes a Pylint configuration file, the settings contained in that file take precedence.
To find out more about Pylint, please refer to their site.