Ejemplo n.º 1
0
 def set_bri(self, slider):
     set_brightness(slider)
     icon_name = bri_icon_name(int(slider.get_value()))
     if icon_name != self.bri_icon_name:
         update_image(self.bri_image, icon_name, self.icon_size,
                      self.icons_path)
         self.bri_icon_name = icon_name
Ejemplo n.º 2
0
 def set_vol(self, slider):
     set_volume(slider)
     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
Ejemplo n.º 3
0
    def update_bt(self, is_on, name):
        icon_name = "bluetooth-active-symbolic" if is_on else "bluetooth-disabled-symbolic"
        if icon_name != self.bt_icon_name:
            update_image(self.bt_image, icon_name, self.icon_size)

        if self.bt_label:
            self.bt_label.set_text(name)
Ejemplo n.º 4
0
    def custom_item(self, name, icon, cmd):
        eb = Gtk.EventBox()

        v_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        h_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        v_box.pack_start(h_box, False, False, 6)
        eb.add(v_box)

        image = Gtk.Image()
        update_image(image, icon, self.icon_size, self.icons_path)
        h_box.pack_start(image, False, True, 6)

        label = Gtk.Label(name)
        h_box.pack_start(label, False, True, 4)

        if cmd:
            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, cmd)

            img = Gtk.Image()
            update_image(img, "pan-end-symbolic", self.icon_size,
                         self.icons_path)
            h_box.pack_end(img, False, True, 4)

        return eb
Ejemplo n.º 5
0
    def update_widget(self, output):
        if output:
            if len(output) == 1:
                if output[0].endswith(".svg") or output[0].endswith(".png"):
                    new_path = output[0].strip()
                    if new_path != self.icon_path:
                        if "/" not in new_path and "." not in new_path:  # name given instead of path
                            update_image(self.image, new_path,
                                         self.settings["icon-size"],
                                         self.icons_path)
                            self.icon_path = new_path
                        else:
                            try:
                                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                                    new_path, self.settings["icon-size"],
                                    self.settings["icon-size"])
                                self.image.set_from_pixbuf(pixbuf)
                                self.icon_path = new_path
                            except:
                                print("Failed setting image from {}".format(
                                    output[0].strip()))
                            if not self.image.get_visible():
                                self.image.show()
                            if self.label.get_visible():
                                self.label.hide()
                else:
                    if self.image.get_visible():
                        self.image.hide()
                    self.label.set_text(output[0].strip())
                    if not self.label.get_visible():
                        self.label.show()

            elif len(output) == 2:
                new_path = output[0].strip()
                if "/" not in new_path and "." not in new_path:  # name given instead of path
                    update_image(self.image, new_path,
                                 self.settings["icon-size"], self.icons_path)
                    self.icon_path = new_path
                else:
                    if new_path != self.icon_path:
                        try:
                            pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                                new_path, self.settings["icon-size"],
                                self.settings["icon-size"])
                            self.image.set_from_pixbuf(pixbuf)
                            self.icon_path = new_path
                        except:
                            print("Failed setting image from {}".format(
                                output[0].strip()))
                        if not self.image.get_visible():
                            self.image.show()

                self.label.set_text(output[1].strip())
        else:
            if self.image.get_visible():
                self.image.hide()
            if self.label.get_visible():
                self.label.hide()

        return False
Ejemplo n.º 6
0
    def __init__(self, settings, icons_path=""):
        self.settings = settings
        self.icons_path = icons_path
        Gtk.EventBox.__init__(self)
        check_key(settings, "interval", 1)
        check_key(settings, "label-css-name", "")
        check_key(settings, "button-css-name", "")
        check_key(settings, "icon-size", 16)
        check_key(settings, "buttons-position", "left")
        check_key(settings, "chars", 30)

        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        self.box.set_property("name", "task-box")
        self.add(self.box)
        self.image = Gtk.Image()
        update_image(self.image, "view-refresh-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
        self.label = Gtk.Label("")
        self.icon_path = None
        self.play_pause_btn = Gtk.Button()
        check_key(settings, "button-css-name", "")
        if self.settings["button-css-name"]:
            self.play_pause_btn.set_property("name", self.settings["button-css-name"])
        self.status = ""
        self.retries = 2  # to avoid hiding the module on forward / backward btn when playing from the browser

        if settings["label-css-name"]:
            self.label.set_property("name", settings["label-css-name"])

        self.build_box()

        self.refresh()

        if settings["interval"] > 0:
            Gdk.threads_add_timeout_seconds(GLib.PRIORITY_LOW, settings["interval"], self.refresh)
Ejemplo n.º 7
0
    def update_widget(self, status, metadata):
        if status in ["Playing", "Paused"]:
            self.retries = 2
            if not self.get_visible():
                self.show()

            if not self.status == status:
                if status == "Playing":
                    update_image(self.play_pause_btn.get_image(),
                                 "media-playback-pause-symbolic",
                                 self.settings["icon-size"],
                                 icons_path=self.icons_path)
                elif status == "Paused":
                    update_image(self.play_pause_btn.get_image(),
                                 "media-playback-start-symbolic",
                                 self.settings["icon-size"],
                                 icons_path=self.icons_path)
                    metadata = "{} - paused".format(metadata)

            self.label.set_text(metadata)
        else:
            if self.get_visible():
                if self.retries == 0:
                    self.hide()
                else:
                    self.retries -= 1

        return False
Ejemplo n.º 8
0
    def update_net(self, ip):
        icon_name = "network-wired-symbolic" if ip 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

        if self.net_label:
            self.net_label.set_text("{}".format(self.settings["net-interface"]))
Ejemplo n.º 9
0
    def update_volume(self, value, switch):
        icon_name = vol_icon_name(value, switch)

        if icon_name != self.vol_icon_name:
            update_image(self.vol_image, icon_name, self.settings["icon-size"])
            self.vol_icon_name = icon_name

        if self.vol_label:
            self.vol_label.set_text("{}%".format(value))
Ejemplo n.º 10
0
    def update_brightness(self, value):
        icon_name = bri_icon_name(value)

        if icon_name != self.bri_icon_name:
            update_image(self.bri_image, icon_name, self.icon_size)
            self.bri_icon_name = icon_name

        if self.bri_label:
            self.bri_label.set_text("{}%".format(value))
Ejemplo n.º 11
0
    def update_battery(self, value):
        icon_name = bat_icon_name(value)

        if icon_name != self.bat_icon_name:
            update_image(self.bat_image, icon_name, self.icon_size)
            self.bat_icon_name = icon_name

        if self.bat_label:
            self.bat_label.set_text("{}%".format(value))
Ejemplo n.º 12
0
    def update_bt(self, adr):
        icon_name = "bluetooth-active-symbolic" if adr != "off" else "bluetooth-disabled-symbolic"
        if icon_name != self.bt_icon_name:
            update_image(self.bt_image, icon_name, self.icon_size,
                         self.icons_path)
            self.bt_icon_name = icon_name

        self.bt_name = adr
        if self.bt_label:
            self.bt_label.set_text(adr)
Ejemplo n.º 13
0
    def update_volume(self):
        self.vol_value, self.vol_muted = get_volume()
        icon_name = vol_icon_name(self.vol_value, self.vol_muted)

        if icon_name != self.vol_icon_name:
            update_image(self.vol_image, icon_name, self.settings["icon-size"],
                         self.icons_path)
            self.vol_icon_name = icon_name

        if self.vol_label:
            self.vol_label.set_text("{}%".format(self.vol_value))
Ejemplo n.º 14
0
    def update_brightness(self):
        value = get_brightness()
        icon_name = bri_icon_name(value)

        if icon_name != self.bri_icon_name:
            update_image(self.bri_image, icon_name, self.icon_size,
                         self.icons_path)
            self.bri_icon_name = icon_name

        self.bri_value = value
        if self.bri_label:
            self.bri_label.set_text("{}%".format(value))
Ejemplo n.º 15
0
    def refresh(self):
        if self.i3.get_tree().find_focused():
            ws_num, win_name, win_id, non_empty, win_layout = self.find_details()

            if ws_num > 0:
                for num in self.settings["numbers"]:
                    # mark non-empty WS with a dot
                    if self.settings["mark-content"]:
                        try:
                            int_num = int(num)
                        except:
                            int_num = 0
                        lbl = self.ws_num2lbl[num]
                        text = lbl.get_text()
                        if int_num in non_empty:
                            if not text.endswith("."):
                                text += "."
                                lbl.set_text(text)
                        else:
                            if text.endswith("."):
                                text = text[0:-1]
                                lbl.set_text(text)

                    if num == str(ws_num):
                        self.ws_num2box[num].set_property("name", "task-box-focused")
                    else:
                        self.ws_num2box[num].set_property("name", "task-box")

                if self.settings["show-icon"] and win_id != self.win_id:
                    self.update_icon(win_id, win_name)
                    self.win_id = win_id

            if self.settings["show-name"]:
                self.name_label.set_text(win_name)
            
            if self.settings["show-layout"]:
                if win_name:
                    if win_layout == "splith":
                        update_image(self.layout_icon, "go-next-symbolic", self.settings["image-size"], self.icons_path)
                    elif win_layout == "splitv":
                        update_image(self.layout_icon, "go-down-symbolic", self.settings["image-size"], self.icons_path)
                    elif win_layout == "tabbed":
                        update_image(self.layout_icon, "view-dual-symbolic", self.settings["image-size"], self.icons_path)
                    elif win_layout == "stacked":
                        update_image(self.layout_icon, "view-paged-symbolic", self.settings["image-size"], self.icons_path)
                    else:
                        update_image(self.layout_icon, "window-pop-out-symbolic", self.settings["image-size"], self.icons_path)
                        
                    if not self.layout_icon.get_visible():
                        self.layout_icon.show()
                else:
                    if self.layout_icon.get_visible():
                        self.layout_icon.hide()
Ejemplo n.º 16
0
    def refresh(self, *args):
        if self.get_visible():
            self.refresh_sinks()
            if "net" in self.settings["components"] and commands[
                    "netifaces"] and self.settings["net-interface"]:
                if self.parent.net_icon_name != self.net_icon_name:
                    update_image(self.net_image, self.parent.net_icon_name,
                                 self.icon_size, self.icons_path)
                    self.net_icon_name = self.parent.net_icon_name

                ip_addr = "disconnected" if not self.parent.net_ip_addr else self.parent.net_ip_addr
                self.net_label.set_text("{}: {}".format(
                    self.settings["net-interface"], ip_addr))

            if "bluetooth" in self.settings["components"] and commands[
                    "pybluez"]:
                if self.parent.bt_icon_name != self.bt_icon_name:
                    update_image(self.bt_image, self.parent.bt_icon_name,
                                 self.icon_size, self.icons_path)
                    self.bt_icon_name = self.parent.bt_icon_name

                if self.bt_label:
                    self.bt_label.set_text(self.parent.bt_name)

            if "battery" in self.settings["components"]:
                if self.parent.bat_icon_name != self.bat_icon_name:
                    update_image(self.bat_image, self.parent.bat_icon_name,
                                 self.icon_size, self.icons_path)
                    self.bat_icon_name = self.parent.bat_icon_name

                self.bat_label.set_text("{}% {}".format(
                    self.parent.bat_value, self.parent.bat_time))

            if "volume" in self.settings["components"] and commands["pamixer"]:
                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

                self.vol_scale.set_value(self.parent.vol_value)

            if "brightness" in self.settings["components"]:
                if self.parent.bri_icon_name != self.bri_icon_name:
                    update_image(self.bri_image, self.parent.bri_icon_name,
                                 self.icon_size, self.icons_path)
                    self.bri_icon_name = self.parent.bri_icon_name

                self.bri_scale.set_value(self.parent.bri_value)

        return True
Ejemplo n.º 17
0
    def __init__(self, settings, icons_path):
        self.settings = settings
        self.icons_path = icons_path
        Gtk.EventBox.__init__(self)
        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        self.add(self.box)
        self.image = Gtk.Image()
        self.label = Gtk.Label("")
        self.icon_path = None

        check_key(settings, "script", "")
        check_key(settings, "interval", 0)
        check_key(settings, "root-css-name", "root-executor")
        check_key(settings, "css-name", "")
        check_key(settings, "icon-placement", "left")
        check_key(settings, "icon-size", 16)
        check_key(settings, "tooltip-text", "")
        check_key(settings, "on-left-click", "")
        check_key(settings, "on-right-click", "")
        check_key(settings, "on-middle-click", "")
        check_key(settings, "on-scroll-up", "")
        check_key(settings, "on-scroll-down", "")

        update_image(self.image, "view-refresh-symbolic", self.settings["icon-size"], self.icons_path)

        self.set_property("name", settings["root-css-name"])

        # reverting #57, as check_key only adds keys if MISSING, not if empty
        if settings["css-name"]:
            self.label.set_property("name", settings["css-name"])
        else:
            self.label.set_property("name", "executor-label")

        if settings["tooltip-text"]:
            self.set_tooltip_text(settings["tooltip-text"])

        if settings["on-left-click"] or settings["on-right-click"] or settings["on-middle-click"] or settings[
            "on-scroll-up"] or settings["on-scroll-down"]:
            self.connect('button-press-event', self.on_button_press)
            self.add_events(Gdk.EventMask.SCROLL_MASK)
            self.connect('scroll-event', self.on_scroll)

            self.connect('enter-notify-event', self.on_enter_notify_event)
            self.connect('leave-notify-event', self.on_leave_notify_event)

        self.build_box()
        self.refresh()

        if settings["interval"] > 0:
            Gdk.threads_add_timeout_seconds(GLib.PRIORITY_LOW, settings["interval"], self.refresh)
Ejemplo n.º 18
0
    def __init__(self, panel, icons_path=""):
        Gtk.Button.__init__(self)
        self.set_always_show_image(True)
        self.panel = panel
        check_key(panel, "menu-start-settings", {})
        self.settings = panel["menu-start-settings"]
        self.set_property("name", "button-start")

        check_key(self.settings, "icon-size-button", 16)

        image = Gtk.Image()
        update_image(image, "nwg-shell", self.settings["icon-size-button"],
                     icons_path)
        self.set_image(image)

        self.connect("clicked", self.on_click)

        self.show()
Ejemplo n.º 19
0
 def update_icon(self, win_id, win_name):
     if win_id and win_name:
         icon_from_desktop = get_icon(win_id)
         if icon_from_desktop:
             if "/" not in icon_from_desktop and not icon_from_desktop.endswith(
                     ".svg") and not icon_from_desktop.endswith(".png"):
                 update_image(self.icon, icon_from_desktop, self.settings["image-size"], self.icons_path)
             else:
                 pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(icon_from_desktop, self.settings["image-size"],
                                                                 self.settings["image-size"])
                 self.icon.set_from_pixbuf(pixbuf)
         else:
             image = Gtk.Image()
             update_image(image, win_id, self.settings["image-size"], self.icons_path)
         
         if not self.icon.get_visible():
             self.icon.show()
     else:
         if self.icon.get_visible():
             self.icon.hide()
Ejemplo n.º 20
0
    def build_box(self):
        for item in self.get_children():
            item.destroy()

        if len(self.content) > 0 and self.settings["css-name"]:
            self.set_property("name", self.settings["css-name"])
        else:
            self.set_property("name", None)

        for item in self.content:
            if item["icon"]:
                eb = Gtk.EventBox()
                image = Gtk.Image()
                update_image(image, item["icon"], self.settings["icon-size"], self.icons_path)
                eb.add(image)
                eb.connect("button-press-event", self.on_button_press, item["pid"])
                if item["name"]:
                    eb.set_tooltip_text(item["name"])
                self.pack_start(eb, False, False, 3)

        self.show_all()
Ejemplo n.º 21
0
    def build_box(self):
        button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)

        img = Gtk.Image()
        update_image(img, "media-skip-backward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
        btn = Gtk.Button()
        btn.set_image(img)
        if self.settings["button-css-name"]:
            btn.set_property("name", self.settings["button-css-name"])
        btn.connect("clicked", self.launch, "playerctl previous")
        button_box.pack_start(btn, False, False, 1)

        img = Gtk.Image()
        update_image(img, "media-playback-start-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
        self.play_pause_btn.set_image(img)
        self.play_pause_btn.connect("clicked", self.launch, "playerctl play-pause")
        button_box.pack_start(self.play_pause_btn, False, False, 1)

        img = Gtk.Image()
        update_image(img, "media-skip-forward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
        btn = Gtk.Button()
        btn.set_image(img)
        if self.settings["button-css-name"]:
            btn.set_property("name", self.settings["button-css-name"])
        btn.connect("clicked", self.launch, "playerctl next")
        button_box.pack_start(btn, False, False, 1)

        if self.settings["buttons-position"] == "left":
            self.box.pack_start(button_box, False, False, 2)
            self.box.pack_start(self.label, False, False, 10)
        else:
            self.box.pack_start(self.label, False, False, 2)
            self.box.pack_start(button_box, False, False, 10)
Ejemplo n.º 22
0
    def __init__(self, settings, icons_path=""):
        Gtk.Button.__init__(self)
        self.set_always_show_image(True)
        self.settings = settings

        check_key(settings, "icon", "dialog-error")
        check_key(settings, "icon-size", 16)
        image = Gtk.Image()
        update_image(image, settings["icon"], settings["icon-size"], icons_path)
        self.set_image(image)

        check_key(settings, "label", "")
        if "label" in settings and settings["label"]:
            if "label-position" in settings:
                if settings["label-position"] == "right":
                    self.set_image_position(Gtk.PositionType.LEFT)
                    self.set_label(settings["label"])
                elif settings["label-position"] == "left":
                    self.set_image_position(Gtk.PositionType.RIGHT)
                    self.set_label(settings["label"])
                elif settings["label-position"] == "top":
                    self.set_image_position(Gtk.PositionType.BOTTOM)
                    self.set_label(settings["label"])
                elif settings["label-position"] == "bottom":
                    self.set_image_position(Gtk.PositionType.TOP)
                    self.set_label(settings["label"])
                else:
                    self.set_tooltip_text(settings["label"])
            else:
                self.set_tooltip_text(settings["label"])

        check_key(settings, "command", "")
        if settings["command"]:
            self.connect("clicked", self.on_click, settings["command"])

        check_key(settings, "css-name", "")
        if settings["css-name"]:
            self.set_property("name", settings["css-name"])

        self.show()
Ejemplo n.º 23
0
    def refresh(self):
        if self.get_visible():
            if "net" in self.settings["components"] and dependencies["netifaces"]:
                ip_addr = get_interface(self.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

                if not ip_addr:
                    ip_addr = "disconnected"
                self.net_label.set_text("{}: {}".format(self.settings["net-interface"], ip_addr))

            if bt_service_enabled() and "bluetooth" in self.settings["components"]:
                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

                self.bat_label.set_text(bt_name())

            if "battery" in self.settings["components"]:
                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

                self.bat_label.set_text(msg)

        return True
Ejemplo n.º 24
0
    def context_menu(self, workspaces):
        menu = Gtk.Menu()
        menu.set_reserve_toggle_size(False)
        # Numbers have been converted to strings by mistake (config.py). Reverting this would be a breaking change,
        # so let's accept both numbers and strings.
        for i in workspaces:
            ws_num = self.con_ws_num(self.con)
            if str(i) != str(ws_num):
                hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
                img = Gtk.Image()
                update_image(img, "go-next-symbolic", 16, self.icons_path)
                hbox.pack_start(img, True, True, 0)
                label = Gtk.Label(str(i))
                hbox.pack_start(label, True, True, 0)
                item = Gtk.MenuItem()
                item.add(hbox)
                item.connect("activate", self.execute, i)
                menu.append(item)

        item = Gtk.SeparatorMenuItem()

        menu.append(item)

        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        img = Gtk.Image()
        update_image(img, "view-paged-symbolic", 16, self.icons_path)
        hbox.pack_start(img, True, True, 0)
        img = Gtk.Image()
        update_image(img, "view-dual-symbolic", 16, self.icons_path)
        hbox.pack_start(img, True, True, 0)
        item = Gtk.MenuItem()
        item.add(hbox)
        item.connect("activate", self.floating_toggle)
        menu.append(item)

        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        img = Gtk.Image()
        update_image(img, "window-close-symbolic", 16, self.icons_path)
        hbox.pack_start(img, True, True, 0)
        item = Gtk.MenuItem()
        item.add(hbox)
        item.connect("activate", self.kill)
        menu.append(item)

        return menu
Ejemplo n.º 25
0
    def __init__(self, con, settings, position):
        self.position = position
        self.settings = settings
        Gtk.EventBox.__init__(self)
        check_key(settings, "task-spacing", 0)
        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
                           spacing=settings["task-spacing"]
                           if settings["task-spacing"] else 0)
        self.add(self.box)
        self.con = con
        self.pid = con.pid

        self.old_name = ""

        if con.focused:
            self.box.set_property("name", "task-box-focused")
        else:
            self.box.set_property("name", "task-box")

        self.connect('enter-notify-event', self.on_enter_notify_event)
        self.connect('leave-notify-event', self.on_leave_notify_event)
        self.connect('button-press-event', self.on_click, self.box)
        self.add_events(Gdk.EventMask.SCROLL_MASK)
        self.connect('scroll-event', self.on_scroll)

        check_key(settings, "show-app-icon", True)
        if settings["show-app-icon"]:
            name = con.app_id if con.app_id else con.window_class

            icon_from_desktop = get_icon(name)
            if icon_from_desktop:
                if "/" not in icon_from_desktop and not icon_from_desktop.endswith(
                        ".svg") and not icon_from_desktop.endswith(".png"):
                    image = Gtk.Image()
                    update_image(image, icon_from_desktop,
                                 settings["image-size"])
                else:
                    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                        icon_from_desktop, settings["image-size"],
                        settings["image-size"])
                    image = Gtk.Image.new_from_pixbuf(pixbuf)

                self.box.pack_start(image, False, False, 4)
            else:
                image = Gtk.Image()
                update_image(image, name, settings["image-size"])
                self.box.pack_start(image, False, False, 4)

        if con.name:
            check_key(settings, "name-max-len", 10)
            name = con.name[:settings["name-max-len"]] if len(
                con.name) > settings["name-max-len"] else con.name
            label = Gtk.Label(name)
            self.box.pack_start(label, False, False, 0)

        check_key(settings, "show-layout", True)
        if settings["show-layout"] and con.parent.layout:
            if con.parent.layout == "splith":
                image = Gtk.Image()
                update_image(image, "go-next", 16)
            elif con.parent.layout == "splitv":
                image = Gtk.Image()
                update_image(image, "go-down", 16)
            elif con.parent.layout == "tabbed":
                image = Gtk.Image()
                update_image(image, "view-dual", 16)
            elif con.parent.layout == "stacked":
                image = Gtk.Image()
                update_image(image, "view-paged", 16)
            else:
                image = Gtk.Image()
                update_image(image, "window-new", 16)

            self.box.pack_start(image, False, False, 4)
Ejemplo n.º 26
0
    def __init__(self, con, settings, position, icons_path, floating=False):
        self.position = position
        self.settings = settings
        Gtk.EventBox.__init__(self)
        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        self.add(self.box)
        self.con = con
        self.pid = con.pid
        self.icons_path = icons_path

        self.old_name = ""

        if con.focused:
            self.box.set_property("name", "task-box-focused")
        else:
            self.box.set_property("name", "task-box")

        self.connect('enter-notify-event', self.on_enter_notify_event)
        self.connect('leave-notify-event', self.on_leave_notify_event)
        self.connect('button-press-event', self.on_click, self.box)
        self.add_events(Gdk.EventMask.SCROLL_MASK)
        self.connect('scroll-event', self.on_scroll)

        check_key(settings, "show-app-icon", True)
        if settings["show-app-icon"]:
            name = con.app_id if con.app_id else con.window_class

            icon_from_desktop = get_icon(name)
            if icon_from_desktop:
                if "/" not in icon_from_desktop and not icon_from_desktop.endswith(
                        ".svg") and not icon_from_desktop.endswith(".png"):
                    image = Gtk.Image()
                    update_image(image, icon_from_desktop,
                                 settings["image-size"], icons_path)
                else:
                    try:
                        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                            icon_from_desktop, settings["image-size"],
                            settings["image-size"])
                    except:
                        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
                            os.path.join(get_config_dir(),
                                         "icons_light/icon-missing.svg"),
                            settings["image-size"], settings["image-size"])
                    image = Gtk.Image.new_from_pixbuf(pixbuf)

                self.box.pack_start(image, False, False, 4)
            else:
                image = Gtk.Image()
                update_image(image, name, settings["image-size"], icons_path)
                self.box.pack_start(image, False, False, 4)

        if con.name:
            check_key(settings, "show-app-name", True)
            name = con.name[:settings["name-max-len"]] if len(
                con.name) > settings["name-max-len"] else con.name
            if settings["show-app-name"]:
                check_key(settings, "name-max-len", 10)
                label = Gtk.Label(name)
                self.box.pack_start(label, False, False, 0)
            else:
                self.set_tooltip_text(name)

        check_key(settings, "show-layout", True)

        if settings["show-layout"] and con.parent.layout:
            if con.parent.layout == "splith":
                image = Gtk.Image()
                update_image(image, "go-next-symbolic", 16, icons_path)
            elif con.parent.layout == "splitv":
                image = Gtk.Image()
                update_image(image, "go-down-symbolic", 16, icons_path)
            elif con.parent.layout == "tabbed":
                image = Gtk.Image()
                update_image(image, "view-dual-symbolic", 16, icons_path)
            elif con.parent.layout == "stacked":
                image = Gtk.Image()
                update_image(image, "view-paged-symbolic", 16, icons_path)

            if floating:
                image = Gtk.Image()
                update_image(image, "window-pop-out-symbolic", 16, icons_path)

            self.box.pack_start(image, False, False, 4)
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
    def __init__(self,
                 settings,
                 position,
                 alignment,
                 width,
                 monitor=None,
                 icons_path=""):
        self.settings = settings
        self.position = position
        self.alignment = alignment
        self.icons_path = icons_path
        Gtk.EventBox.__init__(self)

        check_key(settings, "show-values", True)
        check_key(settings, "icon-size", 16)
        check_key(settings, "interval", 1)
        check_key(settings, "icon-size", 16)
        check_key(settings, "hover-opens", True)
        check_key(settings, "leave-closes", True)
        check_key(settings, "css-name", "controls-label")
        check_key(settings, "components",
                  ["net", "brightness", "volume", "battery"])
        check_key(settings, "net-interface", "")

        self.icon_size = settings["icon-size"]

        self.net_icon_name = "view-refresh-symbolic"
        self.net_image = Gtk.Image.new_from_icon_name(self.net_icon_name,
                                                      Gtk.IconSize.MENU)
        self.net_label = Gtk.Label() if settings["show-values"] else None
        self.net_ip_addr = None

        self.bri_icon_name = "view-refresh-symbolic"
        self.bri_image = Gtk.Image.new_from_icon_name(self.bri_icon_name,
                                                      Gtk.IconSize.MENU)
        self.bri_label = Gtk.Label() if settings["show-values"] else None
        self.bri_value = 0

        self.vol_icon_name = "view-refresh-symbolic"
        self.vol_image = Gtk.Image.new_from_icon_name(self.vol_icon_name,
                                                      Gtk.IconSize.MENU)
        self.vol_label = Gtk.Label() if settings["show-values"] else None
        self.vol_value = 0
        self.vol_muted = False

        self.bt_icon_name = "view-refresh-symbolic"
        self.bt_image = Gtk.Image.new_from_icon_name(self.bt_icon_name,
                                                     Gtk.IconSize.MENU)
        self.bt_label = Gtk.Label() if settings["show-values"] else None
        self.bt_name = ""

        self.bat_icon_name = "view-refresh-symbolic"
        self.bat_image = Gtk.Image.new_from_icon_name(self.bat_icon_name,
                                                      Gtk.IconSize.MENU)
        self.bat_label = Gtk.Label() if settings["show-values"] else None
        self.bat_value = 0
        self.bat_time = ""
        self.bat_charging = False

        self.pan_image = Gtk.Image()
        update_image(self.pan_image, "pan-down-symbolic", self.icon_size,
                     self.icons_path)

        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
        self.add(self.box)

        self.popup_window = PopupWindow(self,
                                        position,
                                        alignment,
                                        settings,
                                        width,
                                        monitor=monitor,
                                        icons_path=self.icons_path)

        self.connect('button-press-event', self.on_button_press)
        self.connect('enter-notify-event', self.on_enter_notify_event)
        self.connect('leave-notify-event', self.on_leave_notify_event)

        self.build_box()
        self.refresh()

        if "battery" in settings["components"]:
            self.refresh_bat()

        if settings["interval"] > 0:
            Gdk.threads_add_timeout_seconds(GLib.PRIORITY_LOW,
                                            settings["interval"], self.refresh)

        if "battery" in settings["components"]:
            Gdk.threads_add_timeout_seconds(GLib.PRIORITY_LOW, 5,
                                            self.refresh_bat)
Ejemplo n.º 29
0
    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)