예제 #1
0
파일: rect.py 프로젝트: inktrap/xpybutil
def monitor_rects(monitors):
    """
    Takes a list of monitors returned by ``xinerama.get_monitors`` and returns
    a new list of rectangles, in the same order, of monitor areas that account
    for all struts set by all windows. Duplicate struts are ignored.

    :param monitors: A list of 4-tuples representing monitor rectangles.
    :return: A list of 4-tuples representing monitor rectangles after
             subtracting strut areas.
    :rtype: [(top_left_x, top_left_y, width, height)]
    """
    mons = monitors  # alias
    wa = mons[:]

    clients = ewmh.get_client_list().reply()

    log = []  # Identical struts should be ignored

    for c in clients:
        try:
            cx, cy, cw, ch = window.get_geometry(c)
        except xproto.BadWindow:
            continue

        for i, (x, y, w, h) in enumerate(wa):
            if rect_intersect_area((x, y, w, h), (cx, cy, cw, ch)) > 0:
                struts = ewmh.get_wm_strut_partial(c).reply()
                if not struts:
                    struts = ewmh.get_wm_strut(c).reply()

                key = (cx, cy, cw, ch, struts)
                if key in log:
                    continue
                log.append(key)

                if struts and not all([v == 0 for v in struts.values()]):
                    if struts["left"] or struts["right"]:
                        if struts["left"]:
                            x += cw
                        w -= cw
                    if struts["top"] or struts["bottom"]:
                        if struts["top"]:
                            y += ch
                        h -= ch
                elif struts:
                    # x/y shouldn't be zero
                    if cx > 0 and w == cx + cw:
                        w -= cw
                    elif cy > 0 and h == cy + ch:
                        h -= ch
                    elif cx > 0 and x == cx:
                        x += cw
                        w -= cw
                    elif cy > 0 and y == cy:
                        y += ch
                        h -= ch

                wa[i] = (x, y, w, h)

    return wa
예제 #2
0
def monitor_rects(monitors):
    """
    Takes a list of monitors returned by ``xinerama.get_monitors`` and returns
    a new list of rectangles, in the same order, of monitor areas that account
    for all struts set by all windows. Duplicate struts are ignored.

    :param monitors: A list of 4-tuples representing monitor rectangles.
    :return: A list of 4-tuples representing monitor rectangles after
             subtracting strut areas.
    :rtype: [(top_left_x, top_left_y, width, height)]
    """
    mons = monitors # alias
    wa = mons[:]

    clients = ewmh.get_client_list().reply()

    log = [] # Identical struts should be ignored

    for c in clients:
        try:
            cx, cy, cw, ch = window.get_geometry(c)
        except xcb.xproto.BadWindow:
            continue

        for i, (x, y, w, h) in enumerate(wa):
            if rect_intersect_area((x, y, w, h), (cx, cy, cw, ch)) > 0:
                struts = ewmh.get_wm_strut_partial(c).reply()
                if not struts:
                    struts = ewmh.get_wm_strut(c).reply()

                key = (cx, cy, cw, ch, struts)
                if key in log:
                    continue
                log.append(key)

                if struts and not all([v == 0 for v in struts.itervalues()]):
                    if struts['left'] or struts['right']:
                        if struts['left']:
                            x += cw
                        w -= cw
                    if struts['top'] or struts['bottom']:
                        if struts['top']:
                            y += ch
                        h -= ch
                elif struts:
                    # x/y shouldn't be zero
                    if cx > 0 and w == cx + cw:
                        w -= cw
                    elif cy > 0 and h == cy + ch:
                        h -= ch
                    elif cx > 0 and x == cx:
                        x += cw
                        w -= cw
                    elif cy > 0 and y == cy:
                        y += ch
                        h -= ch

                wa[i] = (x, y, w, h)

    return wa
예제 #3
0
    def getWinGeometry(wid, skip=0, **kwargs):
        ''' Gets the window geometry of the window.

		Skip controls howe many extra parents we should go to to get the geometry.
		In most window managers, this should be zero (ie, decorations are the parent of wid).
		However, at least one (KWin) introduces an extra parent window, so the decorations
		are actually the grandparent of the wid. In this case, skip should be 1. '''
        for i in range(skip):
            wid = window.get_parent_window(wid)

        geo = window.get_geometry(wid).reply()  # x, y, w, h
        return QRect(*geo)
예제 #4
0
    def restore(self):
        debug('Restoring %s' % self)
        if getattr(config, 'remove_decorations', False):
            motif.set_hints_checked(self.wid, 2, decoration=1).check()
        if getattr(config, 'tiles_below', False):
            ewmh.request_wm_state_checked(
                self.wid, 0, util.get_atom('_NET_WM_STATE_BELOW')).check()
        if self.saved_state:
            fullymaxed = False
            vatom = util.get_atom('_NET_WM_STATE_MAXIMIZED_VERT')
            hatom = util.get_atom('_NET_WM_STATE_MAXIMIZED_HORZ')

            if vatom in self.saved_state and hatom in self.saved_state:
                fullymaxed = True
                ewmh.request_wm_state_checked(self.wid, 1, vatom,
                                              hatom).check()
            elif vatom in self.saved_state:
                ewmh.request_wm_state_checked(self.wid, 1, vatom).check()
            elif hatom in self.saved_state:
                ewmh.request_wm_state_checked(self.wid, 1, hatom).check()

            # No need to continue if we've fully maximized the window
            if fullymaxed:
                return

        mnow = rect.get_monitor_area(window.get_geometry(self.wid),
                                     state.monitors)
        mold = rect.get_monitor_area(self.saved_geom, state.monitors)

        x, y, w, h = self.saved_geom

        # What if the client is on a monitor different than what it was before?
        # Use the same algorithm in Openbox to convert one monitor's
        # coordinates to another.
        if mnow != mold:
            nowx, nowy, noww, nowh = mnow
            oldx, oldy, oldw, oldh = mold

            xrat, yrat = float(noww) / float(oldw), float(nowh) / float(oldh)

            x = nowx + (x - oldx) * xrat
            y = nowy + (y - oldy) * yrat
            w *= xrat
            h *= yrat

        window.moveresize(self.wid, x, y, w, h)
예제 #5
0
    def restore(self):
        debug('Restoring %s' % self)
        if config.remove_decorations:
            motif.set_hints_checked(self.wid,2,decoration=1).check()
        if config.tiles_below:
            ewmh.request_wm_state_checked(self.wid,0,util.get_atom('_NET_WM_STATE_BELOW')).check()
        if self.saved_state:
            fullymaxed = False
            vatom = util.get_atom('_NET_WM_STATE_MAXIMIZED_VERT')
            hatom = util.get_atom('_NET_WM_STATE_MAXIMIZED_HORZ')

            if vatom in self.saved_state and hatom in self.saved_state:
                fullymaxed = True
                ewmh.request_wm_state_checked(self.wid, 1, vatom, hatom).check()
            elif vatom in self.saved_state:
                ewmh.request_wm_state_checked(self.wid, 1, vatom).check()
            elif hatom in self.saved_state:
                ewmh.request_wm_state_checked(self.wid, 1, hatom).check()

            # No need to continue if we've fully maximized the window
            if fullymaxed:
                return
            
        mnow = rect.get_monitor_area(window.get_geometry(self.wid),
                                     state.monitors)
        mold = rect.get_monitor_area(self.saved_geom, state.monitors)

        x, y, w, h = self.saved_geom

        # What if the client is on a monitor different than what it was before?
        # Use the same algorithm in Openbox to convert one monitor's 
        # coordinates to another.
        if mnow != mold:
            nowx, nowy, noww, nowh = mnow
            oldx, oldy, oldw, oldh = mold

            xrat, yrat = float(noww) / float(oldw), float(nowh) / float(oldh)

            x = nowx + (x - oldx) * xrat
            y = nowy + (y - oldy) * yrat
            w *= xrat
            h *= yrat

        window.moveresize(self.wid, x, y, w, h)
예제 #6
0
 def get_geometry(self):
     return window.get_geometry(self.wid)
예제 #7
0
 def save(self):
     self.saved_geom = window.get_geometry(self.wid)
     self.saved_state = ewmh.get_wm_state(self.wid).reply()
예제 #8
0
 def get_geometry(self):
     return window.get_geometry(self.wid)
예제 #9
0
	def get_geometry(self):
		return Rectangle(*window.get_geometry(wid, self.window_manager))
예제 #10
0
 def save(self):
     self.saved_geom = window.get_geometry(self.wid)
     self.saved_state = ewmh.get_wm_state(self.wid).reply()
     debug("Save done %s" % self)