diff --git a/src/common.py b/src/common.py
index 8902814..4b01e4a 100644
--- a/src/common.py
+++ b/src/common.py
@@ -1,17 +1,17 @@
-from gi.repository import GLib, Gtk #Adw, Gdk, Gio
+from gi.repository import GLib, Gtk, Adw #, Gdk, Gio
import os
import subprocess
import pathlib
class myUtils:
def __init__(self, window, **kwargs):
- self.main_window = window
+ self.parent_window = window
self.host_home = str(pathlib.Path.home())
self.user_data_path = self.host_home + "/.var/app/"
self.install_success = True
self.uninstall_success = True
- self.new_env = dict( os.environ )
- self.new_env['LC_ALL'] = 'C'
+ self.new_env = dict( os.environ )
+ self.new_env['LC_ALL'] = 'C'
def trashFolder(self, path):
if not os.path.exists(path):
@@ -67,7 +67,7 @@ class myUtils:
icon_theme.add_search_path(self.host_home + "/.local/share/flatpak/exports/share/icons")
try:
- icon_path = (icon_theme.lookup_icon(app_id, None, 512, 1, self.main_window.get_direction(), 0).get_file().get_path())
+ icon_path = (icon_theme.lookup_icon(app_id, None, 512, 1, self.parent_window.get_direction(), 0).get_file().get_path())
except GLib.GError:
icon_path = None
if icon_path:
@@ -202,4 +202,14 @@ class myUtils:
self.install_success = False
if (len(fails) > 0) and (user_or_system == "user"):
- self.install_success = False
\ No newline at end of file
+ self.install_success = False
+
+ def runApp(self, ref):
+ self.run_app_error = False
+ self.run_app_error_message = ""
+ try:
+ subprocess.run(['flatpak-spawn', '--host', 'flatpak', 'run', ref], check=True, env=self.new_env, start_new_session=True)
+ except subprocess.CalledProcessError as e:
+ self.run_app_error_message = str(e)
+ self.run_app_error = True
+
\ No newline at end of file
diff --git a/src/view-more-symbolic.svg b/src/view-more-symbolic.svg
new file mode 100644
index 0000000..9bb567f
--- /dev/null
+++ b/src/view-more-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 5e6e047..81742b3 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -21,5 +21,6 @@
plus-large-symbolic.svg
funnel-symbolic.svg
right-large-symbolic.svg
+ view-more-symbolic.svg
diff --git a/src/window.blp b/src/window.blp
index 1747c28..2f9c74e 100644
--- a/src/window.blp
+++ b/src/window.blp
@@ -161,4 +161,13 @@ menu copy_menu {
action: "win.copy-refs";
}
}
+}
+
+menu row_menu {
+ section {
+ item {
+ label: _("Open app");
+ //action: "win.open-app";
+ }
+ }
}
\ No newline at end of file
diff --git a/src/window.py b/src/window.py
index 5350488..48bbb10 100644
--- a/src/window.py
+++ b/src/window.py
@@ -67,7 +67,7 @@ class WarehouseWindow(Adw.ApplicationWindow):
currently_uninstalling = False
selected_rows = []
flatpak_rows = []
- # ^ {Row visibility, Row selected, the row itself, properties, trash, select, the flatpak row from `flatpak list`}
+ # ^ {Row visibility, Row selected, the row itself, properties, row menu, select, the flatpak row from `flatpak list`}
def mainPulser(self):
if self.should_pulse:
@@ -87,8 +87,6 @@ class WarehouseWindow(Adw.ApplicationWindow):
if self.currently_uninstalling:
return
self.refresh_button.set_sensitive(should_enable)
- for i in range(len(self.flatpak_rows)):
- self.flatpak_rows[i][4].set_sensitive(should_enable)
if not should_enable:
self.batch_uninstall_button.set_sensitive(False)
@@ -199,6 +197,10 @@ class WarehouseWindow(Adw.ApplicationWindow):
Gtk.Window.present(dialog)
def uninstallButtonHandler(self, _widget, index):
+ if self.currently_uninstalling:
+ self.toast_overlay.add_toast(Adw.Toast.new(_("Cannot uninstall while already uninstalling")))
+ return
+
name = self.host_flatpaks[index][0]
ref = self.host_flatpaks[index][8]
id = self.host_flatpaks[index][2]
@@ -305,27 +307,74 @@ class WarehouseWindow(Adw.ApplicationWindow):
properties_button.connect("clicked", show_properties_window, index, self)
flatpak_row.add_suffix(properties_button)
- trash_button = Gtk.Button(icon_name="user-trash-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Uninstall {}").format(app_name), visible=not self.in_batch_mode)
- trash_button.add_css_class("flat")
- trash_button.connect("clicked", self.uninstallButtonHandler, index)
- flatpak_row.add_suffix(trash_button)
+ # trash_button = Gtk.Button(icon_name="user-trash-symbolic", valign=Gtk.Align.CENTER, tooltip_text=_("Uninstall {}").format(app_name), visible=not self.in_batch_mode)
+ # trash_button.add_css_class("flat")
+ # trash_button.connect("clicked", self.uninstallButtonHandler, index)
+ # flatpak_row.add_suffix(trash_button)
select_flatpak_tickbox = Gtk.CheckButton(visible=self.in_batch_mode)
select_flatpak_tickbox.add_css_class("selection-mode")
select_flatpak_tickbox.connect("toggled", self.rowSelectHandler, index)
flatpak_row.add_suffix(select_flatpak_tickbox)
+ row_menu = Gtk.MenuButton(icon_name="view-more-symbolic", valign=Gtk.Align.CENTER)
+ row_menu.add_css_class("flat")
+ row_menu_model = Gio.Menu()
+
+ # self.create_action(("properties" + str(index)), lambda *_, index=index: show_properties_window(None, index, self))
+ # properties_item = Gio.MenuItem.new(_("Show Properties"), f"win.properties{index}")
+ # row_menu_model.append_item(properties_item)
+
+ if "runtime" not in self.host_flatpaks[index][12]:
+ self.create_action(("run" + str(index)), lambda *_, ref=app_ref: self.runAppThread(ref))
+ run_item = Gio.MenuItem.new(_("Open {}").format(app_name), f"win.run{index}")
+ row_menu_model.append_item(run_item)
+
+ # if os.path.exists(self.user_data_path + app_id):
+ # self.create_action(("open-data" + str(index)), lambda *_, path=(self.user_data_path + app_id): Gio.AppInfo.launch_default_for_uri(f"file://{path}", None))
+ # open_data_item = Gio.MenuItem.new(_("Open Data Folder"), f"win.open-data{index}")
+ # row_menu_model.append_item(open_data_item)
+
+ self.create_action(("uninstall" + str(index)), lambda *_, index=index: self.uninstallButtonHandler(self, index))
+ uninstall_item = Gio.MenuItem.new(_("Uninstall {}").format(app_name), f"win.uninstall{index}")
+ row_menu_model.append_item(uninstall_item)
+
+ # row_menu_model.remove(1)
+
+ row_menu.set_menu_model(row_menu_model)
+ flatpak_row.add_suffix(row_menu)
+
if self.in_batch_mode:
flatpak_row.set_activatable_widget(select_flatpak_tickbox)
self.flatpaks_list_box.append(flatpak_row)
- # {Row visibility, Row selected, the row itself, properties, trash, select, the flatpak row from `flatpak list`}
- self.flatpak_rows.append([True, False, flatpak_row, properties_button, trash_button, select_flatpak_tickbox, self.host_flatpaks[index]])
+ # {Row visibility, Row selected, the row itself, properties, menu button, select, the flatpak row from `flatpak list`}
+ self.flatpak_rows.append([True, False, flatpak_row, properties_button, row_menu, select_flatpak_tickbox, self.host_flatpaks[index]])
self.windowSetEmpty(not self.flatpaks_list_box.get_row_at_index(0))
self.applyFilter(self.filter_list)
self.batchActionsEnable(False)
+ def test(self, _a, _b):
+ if not self.my_utils.run_app_error:
+ return
+
+ error = self.my_utils.run_app_error_message
+ dialog = Adw.MessageDialog.new(self, _("Could not Run App"), error)
+ copy_button = Gtk.Button(label=_("Copy"), halign=Gtk.Align.CENTER, margin_top=12)
+ copy_button.add_css_class("pill")
+ copy_button.add_css_class("suggested-action")
+ copy_button.connect("clicked", lambda *_: self.clipboard.set(error))
+ dialog.set_extra_child(copy_button)
+ dialog.add_response("ok", _("OK"))
+ dialog.set_close_response("ok")
+ dialog.present()
+
+ def runAppThread(self, ref):
+ self.run_app_error = False
+ task = Gio.Task.new(None, None, self.test)
+ task.run_in_thread(lambda *_: self.my_utils.runApp(ref))
+
def refresh_list_of_flatpaks(self, widget, should_toast):
if self.currently_uninstalling:
return
@@ -338,11 +387,11 @@ class WarehouseWindow(Adw.ApplicationWindow):
def batch_mode_handler(self, widget):
for i in range(len(self.flatpak_rows)):
adw_row = self.flatpak_rows[i][2]
- trash_button = self.flatpak_rows[i][4]
+ menu_button = self.flatpak_rows[i][4]
select_tick = self.flatpak_rows[i][5]
+ menu_button.set_visible(not widget.get_active())
select_tick.set_visible(widget.get_active())
- trash_button.set_visible(not widget.get_active())
if widget.get_active():
adw_row.set_activatable(True)