mrvladus
(Mrvladus)
May 26, 2022, 3:05pm
1
Hi! I’m trying to create a panel-like application (like tint2 or xfce-panel) in GTK4 and libadwaita. I need to put it at the bottom edge of the screen and prevent maximized windows from overlapping it. I think I need to set X11 properties _NET_WM_STRUT and _NET_WM_STRUT_PARTIAL, but i don’t understand how to do it. The closest thing i could find is GdkX11. X11Surface. set_utf8_property, but it can’t do what i need. How can I do this?
Here is my program:
#!/bin/python
import gi, os
gi.require_version('Adw', '1')
from gi.repository import Adw, Gtk, Gdk, GdkX11, GLib
data = {
'panel' : None
}
class Application(Adw.Application):
def __init__(self):
super().__init__()
self.get_style_manager().set_color_scheme(Adw.ColorScheme.PREFER_DARK)
self.run()
def do_activate(self):
Panel(app=self)
class Panel(Adw.ApplicationWindow):
def __init__(self, app):
super().__init__()
data['panel'] = self
self.props.application = app
self.props.resizable = False
self.props.default_height = 32
self.props.default_width = self.get_monitor_size()[0]
self.props.content = Box()
self.present()
self.move_panel_to_position()
def get_monitor_size(self):
out = os.popen("xrandr | grep '*'")
width, height = out.read().split()[0].split('x')
width = int(width)
height = int(height)
return width, height
def move_panel_to_position(self):
y_pos = self.get_monitor_size()[1] - self.props.default_height
x_pos = 0
xid = GdkX11.X11Surface.get_xid(self.get_surface())
xscreen = GdkX11.X11Display.get_screen(self.get_display())
class Box(Gtk.Box):
def __init__(self):
super().__init__()
self.props.homogeneous = True
self.append(ApplicationLauncher())
class ApplicationLauncher(Gtk.Button):
def __init__(self):
super().__init__()
self.props.halign = Gtk.Align.START
self.props.icon_name = 'view-app-grid-symbolic'
def do_clicked(self):
data['panel'].destroy()
def main():
Application()
if __name__ == '__main__':
main()
you will have to go through xlib for that after you have got the the window’s xid through gdk4-x11.
mrvladus
(Mrvladus)
May 26, 2022, 4:32pm
3
i do something like this with python-xlib:
xid = GdkX11.X11Surface.get_xid(self.get_surface())
display = Xlib.display.Display()
window = display.create_resource_object('window', xid)
window.change_property(...)
My problem is “change_property” function. There is now good documentation on it. And I don’t understand it’s arguments. How can I write it?
jfrancis
(Jason Francis)
May 26, 2022, 10:22pm
4
The Xlib documentation may be helpful: XChangeProperty
1 Like
mrvladus
(Mrvladus)
May 27, 2022, 12:49pm
5
I got the solution!
To make it behave like a panel I did this (“configure_window” function):
class Panel(Adw.ApplicationWindow):
def __init__(self, app):
super().__init__()
data['panel'] = self
self.props.application = app
self.props.resizable = False
self.props.default_height = 32
self.props.default_width = self.get_monitor_size()[0]
self.props.content = Box()
self.present()
self.configure_window()
def get_monitor_size(self):
out = os.popen("xrandr | grep '*'")
width, height = out.read().split()[0].split('x')
width = int(width)
height = int(height)
return width, height
def configure_window(self):
# Get position
height = self.props.default_height
width = self.props.default_width
y_pos = self.get_monitor_size()[1] - height
x_pos = 0
# Get window id
xid = GdkX11.X11Surface.get_xid(self.get_surface())
display = Xlib.display.Display()
window = display.create_resource_object('window', xid)
# Move window to position
window.configure(x=x_pos, y=y_pos)
# Add 'dock' property
window.change_property(display.intern_atom('_NET_WM_WINDOW_TYPE'), display.intern_atom('ATOM'), 32, [display.intern_atom('_NET_WM_WINDOW_TYPE_DOCK')], X.PropModeReplace)
# Reserve space for panel
window.change_property(display.intern_atom('_NET_WM_STRUT_PARTIAL'), display.intern_atom('CARDINAL'), 32, [0, 0, 0, height, 0, 0, 0, 0, 0, 0, 0, width], X.PropModeReplace)
# Sync changes
display.sync()
system
(system)
Closed
June 26, 2022, 12:49pm
6
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.