Пример #1
0
def set_geometry(window: Wnck.Window,
                 x=None,
                 y=None,
                 w=None,
                 h=None,
                 synchronous=False,
                 raise_exceptions=True):

    if not w and not h:
        geometry = window.get_geometry()
        w = geometry.widthp
        h = geometry.heightp

    xo, yo, wo, ho = calculate_geometry_offset(window)
    x, y, w, h = x + xo, y + yo, w + wo, h + ho
    x, y, w, h = int(x), int(y), int(w), int(h)
    geometry_cache[window.get_xid()] = (x, y, w, h)
    adjustment_cache[window.get_xid()] = False
    window.set_geometry(Wnck.WindowGravity.STATIC, X_Y_W_H_GEOMETRY_MASK, x, y,
                        w, h)

    if synchronous:
        synchronized = wait_configure_event(window.get_xid(),
                                            Gdk.EventType.CONFIGURE,
                                            Gdk.Display.get_default())
        return synchronized

    return False
Пример #2
0
    def reposition(
        self,  # pylint: disable=too-many-arguments
        win: Wnck.Window,
        geom: Optional[Rectangle] = None,
        monitor: Rectangle = Rectangle(0, 0, 0, 0),
        keep_maximize: bool = False,
        geometry_mask: Wnck.WindowMoveResizeMask = (
            Wnck.WindowMoveResizeMask.X | Wnck.WindowMoveResizeMask.Y
            | Wnck.WindowMoveResizeMask.WIDTH
            | Wnck.WindowMoveResizeMask.HEIGHT)
    ) -> None:
        """
        Move and resize a window, decorations inclusive, according to the
        provided target window and monitor geometry rectangles.

        If no monitor rectangle is specified, the target position will be
        relative to the desktop as a whole.

        :param win: The window to reposition.
        :param geom: The new geometry for the window. Can be left unspecified
            if the intent is to move the window to another monitor without
            repositioning it.
        :param monitor: The frame relative to which ``geom`` should be
            interpreted. The whole desktop if unspecified.
        :param keep_maximize: Whether to re-maximize the window if it had to be
            un-maximized to ensure it would move.
        :param geometry_mask: A set of flags determining which aspects of the
            requested geometry should actually be applied to the window.
            (Allows the same geometry definition to easily be shared between
            operations like move and resize.)

        .. todo:: Look for a way to accomplish this with a cleaner method
            signature. :meth:`reposition` is getting a little hairy.

        .. todo:: Decide how to refactor :meth:`reposition` to allow for
            smarter handling of position clamping when cycling windows through
            a sequence of differently sized monitors.
        """

        old_geom = Rectangle(*win.get_geometry()).to_relative(
            self.get_monitor(win)[1])

        new_args = {}
        if geom:
            for attr in ('x', 'y', 'width', 'height'):
                if geometry_mask & getattr(Wnck.WindowMoveResizeMask,
                                           attr.upper()):
                    new_args[attr] = getattr(geom, attr)

        # Apply changes and return to absolute desktop coordinates.
        new_geom = old_geom._replace(**new_args).from_relative(monitor)

        # Ensure the window is fully within the monitor
        # TODO: Make this remember the original position and re-derive from it
        #       on each monitor-next call as long as the window hasn't changed
        #       (Ideally, re-derive from the tiling preset if set)
        if bool(monitor) and not geom:
            clipped_geom = self.usable_region.clip_to_usable_region(new_geom)
        else:
            clipped_geom = new_geom

        if bool(clipped_geom):
            logging.debug(" Repositioning to %s)\n", clipped_geom)
            with persist_maximization(win, keep_maximize):
                # Always use STATIC because either WMs implement window gravity
                # incorrectly or it's not applicable to this problem
                win.set_geometry(Wnck.WindowGravity.STATIC, geometry_mask,
                                 *clipped_geom)
        else:
            logging.debug(" Geometry clipping failed: %r", clipped_geom)