-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjpanel.py
More file actions
169 lines (132 loc) · 5.71 KB
/
jpanel.py
File metadata and controls
169 lines (132 loc) · 5.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# To run this script without installing the library, set GI_TYPELIB_PATH and LD_LIBRARY_PATH to the build/src directory
# GI_TYPELIB_PATH=build/src LD_LIBRARY_PATH=build/src python3 examples/simple-example.py
# For GTK4 Layer Shell to get linked before libwayland-client we must explicitly load it before importing with gi
from ctypes import CDLL
CDLL('libgtk4-layer-shell.so')
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Gtk4LayerShell', '1.0')
from gi.repository import Gtk, GLib
from gi.repository import Gtk4LayerShell as LayerShell
from datetime import datetime
class Panel:
def __init__(self, app, edge=LayerShell.Edge.BOTTOM, layer=LayerShell.Layer.TOP, width=400, height=32):
"""
Initialize a new panel
Args:
app: GTK Application instance
edge: Which edge to anchor to (BOTTOM, TOP, LEFT, RIGHT)
layer: Layer level (TOP, BOTTOM, BACKGROUND, OVERLAY)
width: Panel width
height: Panel height
"""
self.app = app
self.edge = edge
self.layer = layer
self.width = width
self.height = height
# Create the window
self.window = Gtk.Window(application=app)
self.window.set_default_size(width, height)
# Initialize LayerShell
self._setup_layer_shell()
# Create root container
self.root_box = Gtk.Box(spacing=4)
self.window.set_child(self.root_box)
# Store widgets for easy access
self.widgets = {}
def _setup_layer_shell(self):
"""Configure the layer shell settings"""
LayerShell.init_for_window(self.window)
LayerShell.set_layer(self.window, self.layer)
# Anchor to the specified edge
if self.edge == LayerShell.Edge.BOTTOM:
LayerShell.set_anchor(self.window, LayerShell.Edge.BOTTOM, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.LEFT, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.RIGHT, True)
elif self.edge == LayerShell.Edge.TOP:
LayerShell.set_anchor(self.window, LayerShell.Edge.TOP, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.LEFT, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.RIGHT, True)
elif self.edge == LayerShell.Edge.LEFT:
LayerShell.set_anchor(self.window, LayerShell.Edge.LEFT, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.TOP, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.BOTTOM, True)
elif self.edge == LayerShell.Edge.RIGHT:
LayerShell.set_anchor(self.window, LayerShell.Edge.RIGHT, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.TOP, True)
LayerShell.set_anchor(self.window, LayerShell.Edge.BOTTOM, True)
LayerShell.auto_exclusive_zone_enable(self.window)
def add_time_widget(self, format_str="%Y-%m-%d %H:%M:%S", update_interval=1000):
"""
Add a time widget that updates automatically
Args:
format_str: strftime format string for time display
update_interval: Update interval in milliseconds
"""
current_time = datetime.now().strftime(format_str)
time_label = Gtk.Label(label=current_time)
def update_time():
current_time = datetime.now().strftime(format_str)
time_label.set_text(current_time)
return True
# Set up timer
GLib.timeout_add(update_interval, update_time)
# Add to panel and store reference
self.root_box.append(time_label)
self.widgets['time_label'] = time_label
return time_label
def add_button(self, label, callback=None, name=None):
"""
Add a button to the panel
Args:
label: Button text
callback: Function to call when clicked
name: Optional name to store widget reference
"""
button = Gtk.Button(label=label)
if callback:
button.connect('clicked', callback)
self.root_box.append(button)
if name:
self.widgets[name] = button
return button
def add_widget(self, widget, name=None):
"""
Add any GTK widget to the panel
Args:
widget: GTK widget to add
name: Optional name to store widget reference
"""
self.root_box.append(widget)
if name:
self.widgets[name] = widget
return widget
def get_widget(self, name):
"""Get a stored widget by name"""
return self.widgets.get(name)
def show(self):
"""Display the panel"""
self.window.present()
def hide(self):
"""Hide the panel"""
self.window.hide()
def close(self):
"""Close the panel"""
self.window.close()
def on_activate(app):
# Create a bottom panel
bottom_panel = Panel(app, edge=LayerShell.Edge.BOTTOM)
# Add widgets to the panel
bottom_panel.add_time_widget()
bottom_panel.add_button('Close Panel', lambda btn: bottom_panel.close(), 'close_btn')
# Show the panel
bottom_panel.show()
# Example: Create a second panel at the top (uncomment to test)
# top_panel = Panel(app, edge=LayerShell.Edge.TOP, height=24)
# top_panel.add_time_widget(format_str="%H:%M:%S")
# top_panel.add_button('Top Panel', name='top_btn')
# top_panel.show()
app = Gtk.Application(application_id='de.janlu.shell.panel.py')
app.connect('activate', on_activate)
app.run(None)