Skip to content

Commit

Permalink
Allow XStatic configure requests. (#4541)
Browse files Browse the repository at this point in the history
* Allow XStatic configure requests.

In the X11 backend, static windows are allowed to change their position
and size, unless those parameters were set explicitly in
Window.static().  This commit implements the same behavior for XStatic
windows in the Wayland backend.  This fixes gkrellm.

* Tweaked XStatic reconfigure requests.

* Make configured geometry private

---------

Co-authored-by: Joe Rabinoff <rabinoff@post.harvard.edu>
  • Loading branch information
QBobWatson and Joe Rabinoff committed Oct 30, 2023
1 parent 2933cde commit 1050e1a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
12 changes: 10 additions & 2 deletions libqtile/backend/wayland/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,14 @@ def static(
self.defunct = True
if self.group:
self.group.remove(self)

# Keep track of user-specified geometry to support X11.
# Respect configure requests only if these are `None` here.
conf_x = x
conf_y = y
conf_width = width
conf_height = height

if x is None:
x = self.x + self.borderwidth
if y is None:
Expand All @@ -750,7 +758,7 @@ def static(
if self.tree:
self.tree.node.set_position(0, 0)

win = self._to_static()
win = self._to_static(conf_x, conf_y, conf_width, conf_height)

# Pass ownership of the foreign toplevel handle to the static window.
if self.ftm_handle:
Expand All @@ -769,7 +777,7 @@ def is_visible(self) -> bool:
return self.container.node.enabled

@abc.abstractmethod
def _to_static(self) -> Static:
def _to_static(self, x: int | None, y: int | None, width: int | None, height: int | None) -> Static:
# This must return a new `Static` subclass instance
pass

Expand Down
2 changes: 1 addition & 1 deletion libqtile/backend/wayland/xdgwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def static(

hook.fire("client_managed", win)

def _to_static(self) -> XdgStatic:
def _to_static(self, x: int | None, y: int | None, width: int | None, height: int | None) -> XdgStatic:
return XdgStatic(
self.core,
self.qtile,
Expand Down
42 changes: 34 additions & 8 deletions libqtile/backend/wayland/xwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,21 @@ def static(
Window.static(self, screen, x, y, width, height)
hook.fire("client_managed", self.qtile.windows_map[self._wid])

def _to_static(self) -> XStatic:
return XStatic(self.core, self.qtile, self, self._idle_inhibitors_count)
def _to_static(self, x: int | None, y: int | None, width: int | None, height: int | None) -> XStatic:
return XStatic(
self.core, self.qtile, self, self._idle_inhibitors_count, x, y, width, height
)


class ConfigWindow:
"""The XCB_CONFIG_WINDOW_* constants.
Reproduced here to remove a dependency on xcffib.
"""
X = 1
Y = 2
Width = 4
Height = 8


class XStatic(Static[xwayland.Surface]):
Expand All @@ -351,17 +364,25 @@ def __init__(
qtile: Qtile,
win: XWindow,
idle_inhibitor_count: int,
x: int | None,
y: int | None,
width: int | None,
height: int | None,
):
surface = win.surface
Static.__init__(
self, core, qtile, surface, win.wid, idle_inhibitor_count=idle_inhibitor_count
)
self._wm_class = surface.wm_class

self._conf_x = x
self._conf_y = y
self._conf_width = width
self._conf_height = height

self.add_listener(surface.map_event, self._on_map)
self.add_listener(surface.unmap_event, self._on_unmap)
self.add_listener(surface.destroy_event, self._on_destroy)
self.add_listener(surface.surface.commit_event, self._on_commit)
self.add_listener(surface.request_configure_event, self._on_request_configure)
self.add_listener(surface.set_title_event, self._on_set_title)
self.add_listener(surface.set_class_event, self._on_set_class)
Expand Down Expand Up @@ -392,11 +413,17 @@ def _on_unmap(self, _listener: Listener, _data: Any) -> None:
win = XWindow(self.core, self.qtile, self.surface)
self.core.pending_windows.add(win)

def _on_commit(self, _listener: Listener, _data: Any) -> None:
logger.debug("Signal: xstatic commit")

def _on_request_configure(self, _listener: Listener, event: SurfaceConfigureEvent) -> None:
logger.debug("Signal: xstatic request_configure")
cw = ConfigWindow
if self._conf_x is None and event.mask & cw.X:
self.x = event.x
if self._conf_y is None and event.mask & cw.Y:
self.y = event.y
if self._conf_width is None and event.mask & cw.Width:
self.width = event.width
if self._conf_height is None and event.mask & cw.Height:
self.height = event.height
self.place(self.x, self.y, self.width, self.height, self.borderwidth, self.bordercolor)

@expose_command()
Expand All @@ -410,8 +437,7 @@ def hide(self) -> None:
def unhide(self) -> None:
if self not in self.core.pending_windows:
# Only when mapping does the xwayland_surface have a wlr_surface that we can
# listen for commits on and create a tree for.
self.add_listener(self.surface.surface.commit_event, self._on_commit)
# create a tree for.
if not self.tree:
self.tree = SceneTree.subsurface_tree_create(self.container, self.surface.surface)
self.tree.node.set_position(self.borderwidth, self.borderwidth)
Expand Down

0 comments on commit 1050e1a

Please sign in to comment.