panorama_panel.py
Python script, ASCII text executable
1import gi 2gi.require_version("Gtk", "4.0") 3 4from gi.repository import Gtk, Gdk, GObject, GLib 5 6 7class Applet(Gtk.Box): 8name = "Generic applet" 9description = "" 10 11__gsignals__ = { 12"config-changed": (GObject.SIGNAL_RUN_FIRST, None, ()) 13} 14 15def __init__(self, orientation=Gtk.Orientation.HORIZONTAL, config=None): 16super().__init__(orientation=orientation) 17self.add_css_class("panorama-panel-applet") 18if orientation == Gtk.Orientation.VERTICAL: 19self.set_hexpand(True) 20self.set_vexpand(False) 21elif orientation == Gtk.Orientation.HORIZONTAL: 22self.set_vexpand(True) 23self.set_hexpand(False) 24 25self.drag_source = Gtk.DragSource(actions=Gdk.DragAction.MOVE) 26self.drag_source.connect("prepare", self.provide_drag_data) 27self.drag_source.connect("drag-begin", self.drag_begin) 28self.drag_source.connect("drag-cancel", self.drag_cancel) 29 30def provide_drag_data(self, source: Gtk.DragSource, x: float, y: float): 31app = self.get_root().get_application() 32app.drags[id(self)] = self 33value = GObject.Value() 34value.init(GObject.TYPE_UINT64) 35value.set_uint64(id(self)) 36return Gdk.ContentProvider.new_for_value(value) 37 38def drag_begin(self, source: Gtk.DragSource, drag: Gdk.Drag): 39paintable = Gtk.WidgetPaintable.new(self).get_current_image() 40source.set_icon(paintable, 0, 0) 41self.hide() 42 43def drag_cancel(self, source: Gtk.DragSource, drag: Gdk.Drag, reason: Gdk.DragCancelReason): 44self.show() 45return False 46 47def get_config(self): 48return {} 49 50def shutdown(self, app: Gtk.Application): 51return 52 53def set_panel_position(self, position: Gtk.PositionType): 54return 55 56def make_draggable(self): 57self.add_controller(self.drag_source) 58 59def restore_drag(self): 60self.remove_controller(self.drag_source) 61 62def output_changed(self): 63return 64 65@classmethod 66def print_log(cls, *args, **kwargs): 67print(f"{cls.__name__}:", *args, **kwargs) 68 69def wl_output_enter(self, output, name): 70pass 71 72def foreign_toplevel_new(self, manager, toplevel): 73pass 74 75def foreign_toplevel_output_enter(self, toplevel, output): 76pass 77 78def foreign_toplevel_output_leave(self, toplevel, output): 79pass 80 81def foreign_toplevel_app_id(self, toplevel, app_id): 82pass 83 84def foreign_toplevel_title(self, toplevel, title): 85pass 86 87def foreign_toplevel_state(self, toplevel, state): 88pass 89 90def foreign_toplevel_closed(self, toplevel): 91pass 92 93def foreign_toplevel_refresh(self): 94pass 95 96 97def track_popover(popover: Gtk.Popover): 98popover.connect("show", lambda *args: _popover_shown(popover)) 99popover.connect("closed", lambda *args: _popover_hidden(popover)) 100 101 102def _popover_shown(popover: Gtk.Popover): 103popover.get_root().open_popovers.add(id(popover)) 104if popover.get_root().autohide: 105GLib.timeout_add(popover.get_root().hide_time // (popover.get_root().size - 1), 106popover.get_root().slide_in) 107 108 109def _popover_hidden(popover: Gtk.Popover): 110popover.get_root().open_popovers.remove(id(popover)) 111if popover.get_root().autohide and not popover.get_root().open_popovers: 112GLib.timeout_add(popover.get_root().hide_time // (popover.get_root().size - 1), 113popover.get_root().slide_out) 114 115 116def get_panel_position(applet: Applet) -> Gtk.PositionType: 117return applet.get_root().position 118 119 120OPPOSITE_POSITION = { 121Gtk.PositionType.TOP: Gtk.PositionType.BOTTOM, 122Gtk.PositionType.BOTTOM: Gtk.PositionType.TOP, 123Gtk.PositionType.LEFT: Gtk.PositionType.RIGHT, 124Gtk.PositionType.RIGHT: Gtk.PositionType.LEFT, 125} 126 127POSITION_TO_ARROW = { 128Gtk.PositionType.TOP: Gtk.ArrowType.UP, 129Gtk.PositionType.BOTTOM: Gtk.ArrowType.DOWN, 130Gtk.PositionType.LEFT: Gtk.ArrowType.LEFT, 131Gtk.PositionType.RIGHT: Gtk.ArrowType.RIGHT, 132} 133