diff --git a/src/.python-version b/src/.python-version new file mode 100644 index 0000000..8d7f852 --- /dev/null +++ b/src/.python-version @@ -0,0 +1 @@ +3.10.4 diff --git a/src/core/controller.py b/src/core/controller.py index 652b8a1..49a224c 100644 --- a/src/core/controller.py +++ b/src/core/controller.py @@ -38,45 +38,25 @@ class Controller(ControllerData): # NOTE: To be filled out after app data is actually working... - def search_for_entry(self, widget, data=None): + def search_for_entry(self, widget, data = None): ... def set_list_group(self, widget): group = widget.get_label().strip() group_items = self.core_widget.get_group(group) - grid = self.builder.get_object("programListBttns") + grid = self.builder.get_object("program_list_bttns") children = grid.get_children() for child in children: + child.disconnect(child.sig_id) grid.remove(child) - row = 0 - col = 0 + row = 0 + col = 0 + icon_theme = Gtk.IconTheme.get_default() + for item in group_items: - title = item["title"] - if not item["exec"] in ("", None): - exec = item["exec"] - else: - exec = item["tryExec"] - - button = Gtk.Button(label=title) - button.connect("clicked", self.test_exec, exec) - if self.show_image: - if os.path.exists(item["icon"]): - pixbuf = GdkPixbuf.PixbufAnimation.new_from_file(item["icon"]) \ - .get_static_image() \ - .scale_simple(64, 64, \ - GdkPixbuf.InterpType.BILINEAR) - - icon = Gtk.Image.new_from_pixbuf(pixbuf) - else: - gio_icon = Gio.Icon.new_for_string(item["icon"]) - icon = Gtk.Image.new_from_gicon(gio_icon, 64) - - button.set_image(icon) - button.set_always_show_image(True) - - button.show_all() + button = self.generate_app_button(icon_theme, item) grid.attach(button, col, row, 1, 1) col += 1 @@ -84,7 +64,54 @@ class Controller(ControllerData): col = 0 row += 1 - # grid.add(button) + + + def generate_app_button(self, icon_theme, item): + title = item["title"] + exec_str = item[ + "exec" if not item["exec"] in ("", None) else "tryExec" + ] + + button = Gtk.Button(label = title) + button.sig_id = button.connect("clicked", self.test_exec, exec_str) + + if self.show_image: + _icon = item["icon"] + + if os.path.exists(_icon): + icon = self.get_icon_from_path(_icon) + else: + icon = self.get_icon_from_gio(icon_theme, _icon) + + button.set_image(icon) + button.set_always_show_image(True) + + button.show_all() + return button + + def get_icon_from_path(self, path): + pixbuf = GdkPixbuf.PixbufAnimation.new_from_file(path) \ + .get_static_image() \ + .scale_simple(32, 32, \ + GdkPixbuf.InterpType.BILINEAR) + + return Gtk.Image.new_from_pixbuf(pixbuf) + + + def get_icon_from_gio(self, icon_theme, icon_name): + gio_icon = Gio.Icon.new_for_string(icon_name) + pixbuf = None + + # Note: https://docs.gtk.org/gtk3/enum.IconSize.html + for i in [6, 5, 3, 4, 2, 1]: + icon_info = Gtk.IconTheme.lookup_by_gicon(icon_theme, gio_icon, i, Gtk.IconLookupFlags.FORCE_REGULAR) + if not icon_info: continue + + pixbuf = icon_info.load_icon().scale_simple(32, 32, 2) # 2 = BILINEAR and is best by default + break + + return Gtk.Image.new_from_pixbuf( pixbuf ) + def test_exec(self, widget, _command): command = _command.split("%")[0] @@ -111,7 +138,7 @@ class Controller(ControllerData): self.setup_toggle_event() return self.core_widget - def on_hide_window(self, data=None): + def on_hide_window(self, data = None): """Handle a request to hide/show the window""" if not self.window.get_property('visible'): self.window.show() @@ -152,4 +179,4 @@ class Controller(ControllerData): proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE) proc.stdin.write(data) proc.stdin.close() - retcode = proc.wait() + retcode = proc.wait() \ No newline at end of file diff --git a/src/core/controller_data.py b/src/core/controller_data.py index 0390ebe..da6efd0 100644 --- a/src/core/controller_data.py +++ b/src/core/controller_data.py @@ -25,12 +25,14 @@ def display_manager(): if display_manager() == 'X11': try: + #gi.require_version('Keybinder', '3.24') gi.require_version('Keybinder', '3.0') from gi.repository import Keybinder Keybinder.init() Keybinder.set_use_cooked_accelerators(False) - except (ImportError, ValueError): - logger.debug('Unable to load Keybinder module. This means the hide_window shortcut will be unavailable') + except (ImportError, ValueError) as e: + logger.warning(e) + logger.warning('Unable to load Keybinder module. This means the hide_window shortcut will be unavailable') @@ -52,14 +54,16 @@ class ControllerData: def setup_toggle_event(self) -> None: self.window = settings.get_builder().get_object(f"{app_name.lower()}") + hidebound = None # Attempt to grab a global hotkey for hiding the window. # If we fail, we'll never hide the window, iconifying instead. if self.guake_key and display_manager() == 'X11': try: hidebound = Keybinder.bind(self.guake_key, self.on_hide_window) - except (KeyError, NameError): - pass + except (KeyError, NameError) as e: + logger.warning(e) + print( repr(e) ) if not hidebound: logger.debug('Unable to bind hide_window key, another instance/window has it.') diff --git a/src/core/core_widget.py b/src/core/core_widget.py index 35f6515..47f4693 100644 --- a/src/core/core_widget.py +++ b/src/core/core_widget.py @@ -10,9 +10,9 @@ gi.require_version('Wnck', '3.0') from gi.repository import Gtk from gi.repository import Wnck from gi.repository import GObject +from gi.repository import GdkPixbuf from xdg.DesktopEntry import DesktopEntry - # Application imports from .desktop_parsing.app_finder import find_apps @@ -23,7 +23,7 @@ class CoreWidget(Gtk.Box): def __init__(self): super(CoreWidget, self).__init__() self.builder = settings.get_builder() - self.time_label = self.builder.get_object("timeLabel") + self.time_label = self.builder.get_object("time_lbl") self.orientation = 1 # 0 = horizontal, 1 = vertical @@ -49,6 +49,9 @@ class CoreWidget(Gtk.Box): apps = find_apps() self.fill_menu_objects(apps) + search_programs_entry = self.builder.get_object("search_programs_entry") + search_programs_entry.hide() + def fill_menu_objects(self, apps=[]): for app in apps: @@ -86,10 +89,18 @@ class CoreWidget(Gtk.Box): else: group = "Other" - self.menu_objects[group].append( {"title": title, "groups": groups, - "comment": comment, "exec": mainExec, - "tryExec": tryExec, "fileName": fPath.split("/")[-1], - "filePath": fPath, "icon": icon}) + self.menu_objects[group].append( + { + "title": title, + "groups": groups, + "comment": comment, + "exec": mainExec, + "tryExec": tryExec, + "fileName": fPath.split("/")[-1], + "filePath": fPath, + "icon": icon + } + ) def get_group(self, group): return self.menu_objects[group] @@ -107,8 +118,8 @@ class CoreWidget(Gtk.Box): def _load_widgets(self): widget_grid_container = self.builder.get_object("widget_grid_container") - timeLabelEveBox = self.builder.get_object("timeLabelEveBox") - timeLabelEveBox.connect("button_release_event", self._toggle_cal_popover) + time_lbl_eve_box = self.builder.get_object("time_lbl_eve_box") + time_lbl_eve_box.connect("button_release_event", self._toggle_cal_popover) widget_grid_container.set_vexpand(True) widget_grid_container.set_hexpand(True) @@ -126,9 +137,9 @@ class CoreWidget(Gtk.Box): pager = Wnck.Pager.new() if self.orientation == 0: - self.builder.get_object('taskBarWorkspacesHor').add(pager) + self.builder.get_object('taskbar_workspaces_hor').add(pager) else: - self.builder.get_object('taskBarWorkspacesVer').add(pager) + self.builder.get_object('taskbar_workspaces_ver').add(pager) pager.set_hexpand(True) pager.show() @@ -140,9 +151,9 @@ class CoreWidget(Gtk.Box): tasklist.set_grouping(1) # 0 = mever group, 1 auto group, 2 = always group if self.orientation == 0: - self.builder.get_object('taskBarButtonsHor').add(tasklist) + self.builder.get_object('taskbar_bttns_hor').add(tasklist) else: - self.builder.get_object('taskBarButtonsVer').add(tasklist) + self.builder.get_object('taskbar_bttns_ver').add(tasklist) tasklist.set_vexpand(True) tasklist.set_include_all_workspaces(False) @@ -162,12 +173,12 @@ class CoreWidget(Gtk.Box): GObject.timeout_add(59000, self.display_clock) - def _close_popup(self, widget, data=None): + def _close_popup(self, widget, data = None): widget.hide() def _toggle_cal_popover(self, widget, eve): - calendarPopup = self.builder.get_object('calendarPopup') - if (calendarPopup.get_visible() == False): + calendar_popup = self.builder.get_object('calendar_popup') + if (calendar_popup.get_visible() == False): calendarWid = self.builder.get_object('calendarWid') now = datetime.now() timeStr = now.strftime("%m/%d/%Y") @@ -177,6 +188,6 @@ class CoreWidget(Gtk.Box): year = int(parts[2]) calendarWid.select_day(day) calendarWid.select_month(month, year) - calendarPopup.popup() + calendar_popup.popup() else: - calendarPopup.popdown() + calendar_popup.popdown() \ No newline at end of file diff --git a/src/core/window.py b/src/core/window.py index 78c3e15..c36f611 100644 --- a/src/core/window.py +++ b/src/core/window.py @@ -30,7 +30,7 @@ class Window(Gtk.ApplicationWindow): self._setup_signals() self._load_widgets(args, unknownargs) - self.show_all() + self.show() def _setup_styling(self): @@ -85,4 +85,4 @@ class Window(Gtk.ApplicationWindow): def _tear_down(self, widget=None, eve=None): settings.clear_pid() time.sleep(event_sleep_time) - Gtk.main_quit() + Gtk.main_quit() \ No newline at end of file diff --git a/user_config/usr/share/utop/Main_Window.glade b/user_config/usr/share/utop/Main_Window.glade index a5bc593..55bbff9 100644 --- a/user_config/usr/share/utop/Main_Window.glade +++ b/user_config/usr/share/utop/Main_Window.glade @@ -12,7 +12,7 @@ True False - + True False start @@ -56,7 +56,7 @@ False vertical - + True True True @@ -255,12 +255,63 @@ True False - - + + True False vertical + 10 + 10 True + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -330,12 +381,21 @@ True False - + True False vertical - + + True + False + application-exit + + + False + True + 0 + @@ -371,7 +431,7 @@ True False - + True False @@ -389,7 +449,7 @@ - + True False start @@ -404,12 +464,12 @@ - + True False True - + 128 True False @@ -439,11 +499,11 @@ - + 420 225 False - timeLabelEveBox + time_lbl_eve_box False