def __init__(self, pos_x=0, pos_y=0, width=300, height=300, message="Message", settings=None): Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL) self.pos_x = pos_x self.pos_y = pos_y self.width = max(100, width) self.height = max(100, height) self.settings = settings self.message = message self.set_size_request(50, 50) self.connect('draw', self.dodraw) self.connect('motion-notify-event', self.drag) self.connect('button-press-event', self.button_press) self.connect('button-release-event', self.button_release) self.set_app_paintable(True) self.monitor = 0 self.drag_type = None self.drag_x = 0 self.drag_y = 0 GtkLayerShell.init_for_window(self) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True) self.show_all()
def __init__(self): super().__init__(title="Navbar") GtkLayerShell.init_for_window(self) GtkLayerShell.auto_exclusive_zone_enable(self) css_provider = Gtk.CssProvider() Gtk.CssProvider.load_from_path(css_provider, "navbar/themes/default/style.css") #Gtk.StyleContext.add_provider(self.get_style_context(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) self.main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=False, spacing=0) self.add(self.main_box) self.left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=False, spacing=0) self.main_box.pack_start(self.left_box, False, False, 0) self.center_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=False, spacing=0) self.main_box.set_center_widget(self.center_box) self.right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=False, spacing=0) self.main_box.pack_end(self.right_box, False, False, 0) self.load_config() self.set_horizontal()
def set_wayland_state(self): """ If wayland is in use then attempt to set up a GtkLayerShell I have no idea how this should register a fail for Weston/KDE/Gnome """ if self.is_wayland: GtkLayerShell.init_for_window(self) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.OVERLAY) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True)
def _create_window(self, anchor, color): window = Gtk.Window() GtkLayerShell.init_for_window(window) GtkLayerShell.set_exclusive_zone(window, -1) GtkLayerShell.set_margin(window, GtkLayerShell.Edge.TOP, 0) GtkLayerShell.set_margin(window, GtkLayerShell.Edge.BOTTOM, 0) GtkLayerShell.set_anchor(window, anchor, True) GtkLayerShell.set_layer(window, GtkLayerShell.Layer.OVERLAY) window.set_size_request(0, 0) window.override_background_color(Gtk.StateFlags.NORMAL, color) window.set_accept_focus(False) window.show_all() window.connect("destroy", Gtk.main_quit) return window
def set_wayland_state(self): """ If wayland is in use then attempt to set up a GtkLayerShell I have no idea how this should register a fail for Weston/KDE/Gnome """ if self.is_wayland: if not GtkLayerShell.is_supported(): logging.info("GTK Layer Shell is not supported on this wayland compositor") logging.info("Currently not possible: Gnome, Plasma, Weston") sys.exit(0) GtkLayerShell.init_for_window(self) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.OVERLAY) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True)
def __init__(self, task: str, duration: int, *args, **kwargs): self.task = task self.duration = duration self.crt_effect = CRTEffect(2560, 1080) self.bar = Gtk.Window() GtkLayerShell.init_for_window(self.bar) GtkLayerShell.set_exclusive_zone(self.bar, -1) GtkLayerShell.set_margin(self.bar, GtkLayerShell.Edge.BOTTOM, 0) GtkLayerShell.set_anchor(self.bar, GtkLayerShell.Edge.BOTTOM, True) GtkLayerShell.set_layer(self.bar, GtkLayerShell.Layer.OVERLAY) self.bar.set_accept_focus(False) self.bar.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(1.0, 0.0, 0.0, 1.0)) self.bar.set_size_request(0, 0) self.bar.show_all() self.bar.connect("destroy", Gtk.main_quit) label_overlay = Gtk.Window() label = Gtk.Label() label.set_markup( f'<span foreground="#D8D8D8" font_desc="Fira Code Regular 11">{task}</span>' # noqa:E501 ) label_overlay.add(label) GtkLayerShell.init_for_window(label_overlay) GtkLayerShell.set_exclusive_zone(label_overlay, -1) GtkLayerShell.set_margin(label_overlay, GtkLayerShell.Edge.BOTTOM, 3) GtkLayerShell.set_anchor(label_overlay, GtkLayerShell.Edge.BOTTOM, True) GtkLayerShell.set_layer(label_overlay, GtkLayerShell.Layer.OVERLAY) label_overlay.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(1.0, 1.0, 1.0, 0.0)) label_overlay.set_accept_focus(False) label_overlay.show_all() label_overlay.connect("destroy", Gtk.main_quit) self.label_overlay = label_overlay
def __init__(self, parent, position, alignment, settings, width, monitor=None, icons_path=""): Gtk.Window.__init__(self, type_hint=Gdk.WindowTypeHint.NORMAL) GtkLayerShell.init_for_window(self) if monitor: GtkLayerShell.set_monitor(self, monitor) check_key(settings, "css-name", "controls-window") self.parent = parent self.set_property("name", settings["css-name"]) self.icon_size = settings["icon-size"] self.icons_path = icons_path self.settings = settings self.position = position self.net_icon_name = "" self.menu_box = None self.sink_box = None self.bri_scale = None self.vol_scale = None self.src_tag = 0 self.connect("show", self.on_window_show) check_key(settings, "output-switcher", False) self.sinks = [] if commands["pamixer"] and settings["output-switcher"] and commands[ "pamixer"]: self.sinks = list_sinks() eb = Gtk.EventBox() eb.set_above_child(False) if settings["leave-closes"]: self.connect("leave_notify_event", self.on_window_exit) self.connect("enter_notify_event", self.on_window_enter) outer_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) eb.add(outer_vbox) self.add(eb) outer_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) Gtk.Widget.set_size_request(outer_hbox, width, 10) outer_vbox.pack_start(outer_hbox, True, True, 20) v_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) outer_hbox.pack_start(v_box, True, True, 20) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP) # GtkLayerShell.set_keyboard_interactivity(self, True) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.TOP, settings["window-margin"]) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.BOTTOM, settings["window-margin"]) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.RIGHT, settings["window-margin"]) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.LEFT, settings["window-margin"]) if alignment == "left": GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) else: GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) if position == "bottom": GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) else: GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True) check_key(settings, "commands", {"battery": "", "net": ""}) add_sep = False if "brightness" in settings["components"]: inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) v_box.pack_start(inner_hbox, False, False, 0) self.bri_icon_name = "view-refresh-symbolic" self.bri_image = Gtk.Image.new_from_icon_name( self.bri_icon_name, Gtk.IconSize.MENU) inner_hbox.pack_start(self.bri_image, False, False, 6) self.bri_scale = Gtk.Scale.new_with_range( orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=1) self.bri_scale.connect("value-changed", self.set_bri) inner_hbox.pack_start(self.bri_scale, True, True, 5) add_sep = True if "volume" in settings["components"] and commands["pamixer"]: inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) v_box.pack_start(inner_hbox, False, False, 6) self.vol_icon_name = "view-refresh-symbolic" self.vol_image = Gtk.Image.new_from_icon_name( self.vol_icon_name, Gtk.IconSize.MENU) if self.parent.vol_icon_name != self.vol_icon_name: update_image(self.vol_image, self.parent.vol_icon_name, self.icon_size, self.icons_path) self.vol_icon_name = self.parent.vol_icon_name eb = Gtk.EventBox() eb.connect("enter_notify_event", self.on_enter_notify_event) eb.connect("leave_notify_event", self.on_leave_notify_event) eb.connect("button-press-event", self.toggle_mute) eb.add(self.vol_image) inner_hbox.pack_start(eb, False, False, 6) self.vol_scale = Gtk.Scale.new_with_range( orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=1) self.vol_scale.set_value(self.parent.vol_value) self.vol_scale.connect("value-changed", self.set_vol) inner_hbox.pack_start(self.vol_scale, True, True, 5) if commands["pamixer"] and settings["output-switcher"]: pactl_eb = Gtk.EventBox() image = Gtk.Image() pactl_eb.add(image) pactl_eb.connect("enter_notify_event", self.on_enter_notify_event) pactl_eb.connect("leave_notify_event", self.on_leave_notify_event) update_image(image, "pan-down-symbolic", self.icon_size, self.icons_path) inner_hbox.pack_end(pactl_eb, False, False, 5) self.sink_box = SinkBox() pactl_eb.connect('button-press-event', self.sink_box.switch_visibility) v_box.pack_start(self.sink_box, False, False, 0) add_sep = True if add_sep: sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL) v_box.pack_start(sep, True, True, 10) if "net" in settings["components"] and commands[ "netifaces"] and settings["net-interface"]: event_box = Gtk.EventBox() if "net" in settings["commands"] and settings["commands"]["net"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["net"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 0) self.net_icon_name = "view-refresh-symbolic" self.net_image = Gtk.Image.new_from_icon_name( self.net_icon_name, Gtk.IconSize.MENU) icon_name = "network-wired-symbolic" if self.parent.net_ip_addr else "network-wired-disconnected-symbolic" if icon_name != self.net_icon_name: update_image(self.net_image, icon_name, self.icon_size, self.icons_path) self.net_icon_name = icon_name inner_hbox.pack_start(self.net_image, False, False, 6) self.net_label = Gtk.Label("{}: {}".format( settings["net-interface"], self.parent.net_ip_addr)) inner_hbox.pack_start(self.net_label, False, True, 6) if "net" in settings["commands"] and settings["commands"]["net"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size, self.icons_path) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) if "bluetooth" in settings["components"] and commands["pybluez"]: event_box = Gtk.EventBox() if "bluetooth" in settings["commands"] and settings["commands"][ "bluetooth"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["bluetooth"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 0) self.bt_icon_name = "view-refresh-symbolic" self.bt_image = Gtk.Image.new_from_icon_name( self.bt_icon_name, Gtk.IconSize.MENU) inner_hbox.pack_start(self.bt_image, False, False, 6) self.bt_label = Gtk.Label() inner_hbox.pack_start(self.bt_label, False, True, 6) if "bluetooth" in settings["commands"] and settings["commands"][ "bluetooth"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size, self.icons_path) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) if "battery" in settings["components"]: event_box = Gtk.EventBox() if "battery" in settings["commands"] and settings["commands"][ "battery"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["battery"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 0) self.bat_icon_name = "view-refresh-symbolic" self.bat_image = Gtk.Image.new_from_icon_name( self.bat_icon_name, Gtk.IconSize.MENU) inner_hbox.pack_start(self.bat_image, False, False, 6) self.bat_label = Gtk.Label() inner_hbox.pack_start(self.bat_label, False, True, 6) if "battery" in settings["commands"] and settings["commands"][ "battery"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size, self.icons_path) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) check_key(settings, "custom-items", []) if settings["custom-items"]: for item in settings["custom-items"]: check_key(item, "name", "undefined") check_key(item, "icon", "") check_key(item, "cmd", "") c_item = self.custom_item(item["name"], item["icon"], item["cmd"]) v_box.pack_start(c_item, True, True, 2) check_key(settings, "menu", {}) if settings["menu"]: template = settings["menu"] sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL) v_box.pack_start(sep, True, True, 10) e_box = Gtk.EventBox() box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) e_box.add(box) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) box.pack_start(inner_hbox, True, True, 6) v_box.pack_start(e_box, True, True, 6) img = Gtk.Image() update_image(img, template["icon"], self.icon_size, self.icons_path) inner_hbox.pack_start(img, False, False, 6) check_key(template, "name", "Menu name") label = Gtk.Label(template["name"]) inner_hbox.pack_start(label, False, False, 6) check_key(template, "items", []) if template["items"]: img = Gtk.Image() update_image(img, "pan-down-symbolic", self.icon_size, self.icons_path) inner_hbox.pack_end(img, False, True, 5) e_box.connect("enter-notify-event", self.on_enter_notify_event) e_box.connect("leave-notify-event", self.on_leave_notify_event) self.menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) v_box.pack_start(self.menu_box, False, False, 0) for item in template["items"]: eb = Gtk.EventBox() vb = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) hb = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) vb.pack_start(hb, False, False, 3) i = Gtk.Label(item["name"]) hb.pack_start(i, False, False, self.icon_size + 18) eb.add(vb) eb.connect("enter_notify_event", self.on_enter_notify_event) eb.connect("leave_notify_event", self.on_leave_notify_event) eb.connect("button-press-event", self.launch, item["cmd"]) self.menu_box.pack_start(eb, False, False, 0) e_box.connect('button-press-event', self.switch_menu_box) Gdk.threads_add_timeout(GLib.PRIORITY_LOW, 500, self.refresh)
def main(): common.config_dir = get_config_dir() common.defaults = get_defaults() parser = argparse.ArgumentParser() parser.add_argument("-c", "--config", type=str, default="config", help="config filename (in {}/)".format(common.config_dir)) parser.add_argument("-s", "--style", type=str, default="style.css", help="css filename (in {}/)".format(common.config_dir)) parser.add_argument("-r", "--restore", action="store_true", help="restore default config files") parser.add_argument("-v", "--version", action="version", version="%(prog)s {}".format(__version__), help="display version information") args = parser.parse_args() try: from pyalsa import alsamixer common.dependencies["pyalsa"] = True except: print("pylsa module not found, will try amixer") global restart_cmd restart_cmd = "nwg-panel -c {} -s {}".format(args.config, args.style) # Try and kill already running instance if any pid_file = os.path.join(temp_dir(), "nwg-panel.pid") if os.path.isfile(pid_file): try: pid = int(load_text_file(pid_file)) os.kill(pid, signal.SIGINT) print("Running instance killed, PID {}".format(pid)) except: pass save_string(str(os.getpid()), pid_file) save_string("-c {} -s {}".format(args.config, args.style), os.path.join(local_dir(), "args")) common.app_dirs = get_app_dirs() common.dependencies["amixer"] = is_command("amixer") config_file = os.path.join(common.config_dir, args.config) copy_files(os.path.join(dir_name, "icons_light"), os.path.join(common.config_dir, "icons_light")) copy_files(os.path.join(dir_name, "icons_dark"), os.path.join(common.config_dir, "icons_dark")) copy_executors(os.path.join(dir_name, "executors"), os.path.join(common.config_dir, "executors")) copy_files(os.path.join(dir_name, "config"), common.config_dir, args.restore) common.outputs = list_outputs(sway=sway) panels = load_json(config_file) screen = Gdk.Screen.get_default() provider = Gtk.CssProvider() style_context = Gtk.StyleContext() style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) try: provider.load_from_path(os.path.join(common.config_dir, args.style)) except Exception as e: print(e) for panel in panels: check_key(panel, "icons", "") icons_path = "" if panel["icons"] == "light": icons_path = os.path.join(common.config_dir, "icons_light") elif panel["icons"] == "dark": icons_path = os.path.join(common.config_dir, "icons_dark") check_key(panel, "output", "") # This is to allow width "auto" value. Actually all non-numeric values will be removed. if "width" in panel and not isinstance(panel["width"], int): panel.pop("width") if panel["output"] in common.outputs or not panel["output"]: check_key(panel, "spacing", 6) check_key(panel, "css-name", "") check_key(panel, "padding-horizontal", 0) check_key(panel, "padding-vertical", 0) window = Gtk.Window() if panel["css-name"]: window.set_property("name", panel["css-name"]) if "output" not in panel or not panel["output"]: display = Gdk.Display.get_default() monitor = display.get_monitor(0) for key in common.outputs: if common.outputs[key]["monitor"] == monitor: panel["output"] = key # Width undefined or "auto" if "output" in panel and panel["output"] and "width" not in panel: panel["width"] = common.outputs[panel["output"]]["width"] check_key(panel, "width", 0) w = panel["width"] check_key(panel["controls-settings"], "window-width", 0) controls_width = panel["controls-settings"]["window-width"] if panel["controls-settings"][ "window-width"] > 0 else int(w / 5) check_key(panel, "height", 0) h = panel["height"] check_key(panel, "controls", "off") if panel["controls"]: check_key(panel, "controls-settings", {}) if "controls-settings" in panel: controls_settings = panel["controls-settings"] check_key(controls_settings, "show-values", False) Gtk.Widget.set_size_request(window, w, h) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) vbox.pack_start(hbox, True, True, panel["padding-vertical"]) check_key(panel, "modules-left", []) check_key(panel, "modules-center", []) check_key(panel, "modules-right", []) # This is to allow the "auto" value. Actually all non-numeric values will be removed. if "homogeneous" in panel and not isinstance(panel["homogeneous"], bool): panel.pop("homogeneous") # set equal columns width by default if "modules-center" not empty; this may be overridden in config if panel["modules-center"]: check_key(panel, "homogeneous", True) else: check_key(panel, "homogeneous", False) inner_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_box.set_homogeneous(panel["homogeneous"]) hbox.pack_start(inner_box, True, True, panel["padding-horizontal"]) left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=panel["spacing"]) inner_box.pack_start(left_box, False, True, 0) if panel["controls"] and panel["controls"] == "left": monitor = None try: monitor = common.outputs[panel["output"]]["monitor"] except KeyError: pass cc = Controls(panel["controls-settings"], panel["position"], panel["controls"], controls_width, monitor=monitor, icons_path=icons_path) common.controls_list.append(cc) left_box.pack_start(cc, False, False, 0) instantiate_content(panel, left_box, panel["modules-left"], icons_path=icons_path) center_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=panel["spacing"]) inner_box.pack_start(center_box, True, False, 0) check_key(panel, "modules-center", []) instantiate_content(panel, center_box, panel["modules-center"], icons_path=icons_path) right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=panel["spacing"]) # Damn on the guy who invented `pack_start(child, expand, fill, padding)`! helper_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) helper_box.pack_end(right_box, False, False, 0) inner_box.pack_start(helper_box, False, True, 0) check_key(panel, "modules-right", []) instantiate_content(panel, right_box, panel["modules-right"], icons_path=icons_path) if panel["controls"] and panel["controls"] == "right": monitor = None try: monitor = common.outputs[panel["output"]]["monitor"] except KeyError: pass cc = Controls(panel["controls-settings"], panel["position"], panel["controls"], controls_width, monitor=monitor, icons_path=icons_path) common.controls_list.append(cc) right_box.pack_end(cc, False, False, 0) window.add(vbox) GtkLayerShell.init_for_window(window) monitor = None try: monitor = common.outputs[panel["output"]]["monitor"] except KeyError: pass check_key(panel, "layer", "top") o = panel["output"] if "output" in panel else "undefined" print("Display: {}, position: {}, layer: {}, width: {}, height: {}".format(o, panel["position"], panel["layer"], panel["width"], panel["height"])) if monitor: GtkLayerShell.set_monitor(window, monitor) GtkLayerShell.auto_exclusive_zone_enable(window) if panel["layer"] == "top": GtkLayerShell.set_layer(window, GtkLayerShell.Layer.TOP) else: GtkLayerShell.set_layer(window, GtkLayerShell.Layer.BOTTOM) check_key(panel, "margin-top", 0) GtkLayerShell.set_margin(window, GtkLayerShell.Edge.TOP, panel["margin-top"]) check_key(panel, "margin-bottom", 0) GtkLayerShell.set_margin(window, GtkLayerShell.Edge.BOTTOM, panel["margin-bottom"]) if panel["position"] == "top": GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.TOP, 1) else: GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.BOTTOM, 1) window.show_all() Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT_IDLE, 150, check_tree) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) Gtk.main()
def __init__(self, position, settings, width, monitor=None): Gtk.Window.__init__(self, type_hint=Gdk.WindowTypeHint.NORMAL) GtkLayerShell.init_for_window(self) if monitor: GtkLayerShell.set_monitor(self, monitor) check_key(settings, "css-name", "controls-window") self.set_property("name", settings["css-name"]) self.icon_size = settings["icon-size"] self.settings = settings self.position = position self.bt_icon_name = "" self.bt_image = Gtk.Image() eb = Gtk.EventBox() eb.set_above_child(False) self.connect("leave_notify_event", self.on_window_exit) outer_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) eb.add(outer_vbox) self.add(eb) outer_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) Gtk.Widget.set_size_request(outer_hbox, width, 10) outer_vbox.pack_start(outer_hbox, True, True, 20) v_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) outer_hbox.pack_start(v_box, True, True, 20) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP) # GtkLayerShell.set_keyboard_interactivity(self, True) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.TOP, 6) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.BOTTOM, 6) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.RIGHT, 6) GtkLayerShell.set_margin(self, GtkLayerShell.Edge.LEFT, 6) if settings["alignment"] == "left": GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) else: GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) if position == "bottom": GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) else: GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True) check_key(settings, "commands", {"battery": "", "net": ""}) add_sep = False if "brightness" in settings["components"]: inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) v_box.pack_start(inner_hbox, False, False, 0) self.bri_icon_name = "view-refresh-symbolic" self.bri_image = Gtk.Image.new_from_icon_name(self.bri_icon_name, Gtk.IconSize.MENU) icon_name = bri_icon_name(int(get_brightness())) if icon_name != self.bri_icon_name: update_image(self.bri_image, icon_name, self.icon_size) self.bri_icon_name = icon_name inner_hbox.pack_start(self.bri_image, False, False, 6) scale = Gtk.Scale.new_with_range(orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=1) value = get_brightness() scale.set_value(value) scale.connect("value-changed", self.set_bri) inner_hbox.pack_start(scale, True, True, 5) add_sep = True if "volume" in settings["components"]: inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) v_box.pack_start(inner_hbox, False, False, 6) self.vol_icon_name = "view-refresh-symbolic" self.vol_image = Gtk.Image.new_from_icon_name(self.vol_icon_name, Gtk.IconSize.MENU) vol, switch = get_volume() icon_name = vol_icon_name(vol, switch) if icon_name != self.vol_icon_name: update_image(self.vol_image, icon_name, self.icon_size) self.vol_icon_name = icon_name inner_hbox.pack_start(self.vol_image, False, False, 6) scale = Gtk.Scale.new_with_range(orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=1) value, switch = get_volume() scale.set_value(value) scale.connect("value-changed", self.set_vol) inner_hbox.pack_start(scale, True, True, 5) add_sep = True if add_sep: sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL) v_box.pack_start(sep, True, True, 10) if "net" in settings["components"] and dependencies["netifaces"]: event_box = Gtk.EventBox() if "net" in settings["commands"] and settings["commands"]["net"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["net"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 10) self.net_icon_name = "view-refresh-symbolic" self.net_image = Gtk.Image.new_from_icon_name(self.net_icon_name, Gtk.IconSize.MENU) ip_addr = get_interface(settings["net-interface"]) icon_name = "network-wired-symbolic" if ip_addr else "network-wired-disconnected-symbolic" if icon_name != self.net_icon_name: update_image(self.net_image, icon_name, self.icon_size) self.net_icon_name = icon_name inner_hbox.pack_start(self.net_image, False, False, 6) self.net_label = Gtk.Label("{}: {}".format(settings["net-interface"], ip_addr)) inner_hbox.pack_start(self.net_label, False, True, 6) if "net" in settings["commands"] and settings["commands"]["net"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) if bt_service_enabled() and "bluetooth" in settings["components"]: event_box = Gtk.EventBox() if "bluetooth" in settings["commands"] and settings["commands"]["bluetooth"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["bluetooth"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 6) self.bt_icon_name = "view-refresh-symbolic" self.bt_image = Gtk.Image.new_from_icon_name(self.bt_icon_name, Gtk.IconSize.MENU) icon_name = bt_icon_name(bt_on()) if icon_name != self.bt_icon_name: update_image(self.bt_image, icon_name, self.icon_size) self.bt_icon_name = icon_name inner_hbox.pack_start(self.bt_image, False, False, 6) self.bt_label = Gtk.Label(bt_name()) inner_hbox.pack_start(self.bt_label, False, True, 6) if "bluetooth" in settings["commands"] and settings["commands"]["bluetooth"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) if "battery" in settings["components"]: event_box = Gtk.EventBox() if "battery" in settings["commands"] and settings["commands"]["battery"]: event_box.connect("enter_notify_event", self.on_enter_notify_event) event_box.connect("leave_notify_event", self.on_leave_notify_event) event_box.connect('button-press-event', self.launch, settings["commands"]["battery"]) inner_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) inner_vbox.pack_start(inner_hbox, True, True, 6) v_box.pack_start(event_box, True, True, 6) self.bat_icon_name = "view-refresh-symbolic" self.bat_image = Gtk.Image.new_from_icon_name(self.bat_icon_name, Gtk.IconSize.MENU) msg, level = get_battery() icon_name = bat_icon_name(level) if icon_name != self.bat_icon_name: update_image(self.bat_image, icon_name, self.icon_size) self.bat_icon_name = icon_name inner_hbox.pack_start(self.bat_image, False, False, 6) self.bat_label = Gtk.Label(msg) inner_hbox.pack_start(self.bat_label, False, True, 6) if "battery" in settings["commands"] and settings["commands"]["battery"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size) inner_hbox.pack_end(img, False, True, 4) event_box.add(inner_vbox) check_key(settings, "custom-items", []) if settings["custom-items"]: for item in settings["custom-items"]: c_item = self.custom_item(item["name"], item["icon"], item["cmd"]) v_box.pack_start(c_item, True, True, 6) check_key(settings, "menu", {}) if settings["menu"]: template = settings["menu"] sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL) v_box.pack_start(sep, True, True, 10) e_box = Gtk.EventBox() box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) e_box.add(box) inner_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) box.pack_start(inner_hbox, True, True, 6) v_box.pack_start(e_box, True, True, 6) img = Gtk.Image() update_image(img, template["icon"], self.icon_size) inner_hbox.pack_start(img, False, False, 6) check_key(template, "name", "Menu name") label = Gtk.Label(template["name"]) inner_hbox.pack_start(label, False, False, 6) check_key(template, "items", []) if template["items"]: img = Gtk.Image() update_image(img, "pan-end-symbolic", self.icon_size) inner_hbox.pack_end(img, False, True, 0) e_box.connect("enter-notify-event", self.on_enter_notify_event) e_box.connect("leave-notify-event", self.on_leave_notify_event) self.menu_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) v_box.pack_start(self.menu_box, False, False, 0) for item in template["items"]: eb = Gtk.EventBox() vb = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) hb = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) vb.pack_start(hb, False, False, 6) i = Gtk.Label(item["name"]) hb.pack_start(i, False, False, self.icon_size + 18) eb.add(vb) eb.connect("enter_notify_event", self.on_enter_notify_event) eb.connect("leave_notify_event", self.on_leave_notify_event) eb.connect("button-press-event", self.launch, item["cmd"]) self.menu_box.pack_start(eb, False, False, 0) e_box.connect('button-press-event', self.switch_menu_box) Gdk.threads_add_timeout_seconds(GLib.PRIORITY_LOW, settings["interval"], self.refresh)
title = "TestWindow" if len(sys.argv) > 2: window_type = sys.argv[2] else: window_type = "normal" win = Gtk.Window(title=title) win.connect("destroy", Gtk.main_quit) win.connect("key-press-event", Gtk.main_quit) win.set_default_size(100, 100) if window_type == "notification": if os.environ["GDK_BACKEND"] == "wayland": try: gi.require_version('GtkLayerShell', '0.1') from gi.repository import GtkLayerShell except ValueError: sys.exit(1) win.add(Gtk.Label(label='This is a test notification')) GtkLayerShell.init_for_window(win) else: win.set_type_hint(Gdk.WindowTypeHint.NOTIFICATION) elif window_type == "normal": win.set_type_hint(Gdk.WindowTypeHint.NORMAL) win.show_all() Gtk.main()