update readme

This commit is contained in:
GloriousEggroll 2025-04-04 09:16:41 -06:00
parent f3977d491c
commit 19f2159a6b
4 changed files with 8929 additions and 8411 deletions

View file

@ -36,14 +36,15 @@ DONE:
- Refresh metadata button
- Add install from .flatpakref functionality + drag and drop
- Add install from .flatpakrepo functionality + drag and drop
- Add per-app permission management backend
- Add global permission management backend
- Add per-app permission management GUI
- Add global permission management GUI
TODO:
- Implement global option to allow any flatpak install desktop_app kind to access user home directory (this will be good for new users for things like discord and file sharing)
- Update management GUI (individual apps can already be updated)
- Package information page/section.
- add about section
- permission management GUI + backend
- Update management GUI (individual apps can already be updated)
- General GUI layout/theming improvements
Usage (Temporary until proper packaging is added):

View file

@ -1206,6 +1206,7 @@ def add_file_permissions(app_id: str, path: str, perm_type=None, system=False) -
path (str): The path to grant access to. Can be:
- "home" for home directory access
- "/path/to/directory" for custom directory access
perm_type (str): The type of permissions to remove (e.g. "filesystems", "persistent") default is "filesystems"
system (bool): Whether to modify system-wide or user installation
Returns:
@ -1214,7 +1215,7 @@ def add_file_permissions(app_id: str, path: str, perm_type=None, system=False) -
try:
key_file = get_perm_key_file(app_id, system)
perm_type = perm_type or "filesystem"
perm_type = perm_type or "filesystems"
# Handle special case for home directory
if path.lower() == "host":
filesystem_path = "host"
@ -1277,6 +1278,7 @@ def remove_file_permissions(app_id: str, path: str, perm_type=None, system=False
path (str): The path to revoke access to. Can be:
- "home" for home directory access
- "/path/to/directory" for custom directory access
perm_type (str): The type of permissions to remove (e.g. "filesystems", "persistent") default is "filesystems"
system (bool): Whether to modify system-wide or user installation
Returns:
@ -1284,7 +1286,7 @@ def remove_file_permissions(app_id: str, path: str, perm_type=None, system=False
"""
try:
key_file = get_perm_key_file(app_id, system)
perm_type = perm_type or "filesystem"
perm_type = perm_type or "filesystems"
# Handle special case for home directory
if path.lower() == "host":
@ -1637,7 +1639,7 @@ def remove_permission_value(app_id: str, perm_type: str, value: str, system=Fals
except GLib.Error as e:
return False, f"Error removing permission: {str(e)}"
def global_add_file_permissions(path: str, override=True, system=False) -> tuple[bool, str]:
def global_add_file_permissions(path: str, perm_type=None, override=True, system=False) -> tuple[bool, str]:
"""
Add filesystem permissions to all Flatpak applications globally.
@ -1645,6 +1647,7 @@ def global_add_file_permissions(path: str, override=True, system=False) -> tuple
path (str): The path to grant access to. Can be:
- "home" for home directory access
- "/path/to/directory" for custom directory access
perm_type (str): The type of permissions to remove (e.g. "filesystems", "persistent") default is "filesystems"
override (bool): Whether to use global metadata file instead of per-app.
system (bool): Whether to modify system-wide or user installation
@ -1654,7 +1657,7 @@ def global_add_file_permissions(path: str, override=True, system=False) -> tuple
try:
key_file = get_perm_key_file(None, override, system)
perm_type = perm_type or "filesystems"
# Handle special case for home directory
if path.lower() == "host":
filesystem_path = "host"
@ -1669,21 +1672,21 @@ def global_add_file_permissions(path: str, override=True, system=False) -> tuple
filesystem_path = path.rstrip('/')
if not key_file.has_group("Context"):
key_file.set_string("Context", "filesystems", "")
key_file.set_string("Context", perm_type, "")
# Now get the keys
context_keys = key_file.get_keys("Context")
# Check if perm_type exists in the section
if "filesystems" not in str(context_keys):
if perm_type not in str(context_keys):
# Create the key with an empty string
key_file.set_string("Context", "filesystems", "")
key_file.set_string("Context", perm_type, "")
# Get existing filesystem paths
existing_paths = key_file.get_string("Context", "filesystems")
if existing_paths is None:
existing_paths = key_file.get_string("Context", perm_type)
if existing_paths is None or existing_paths == "":
# If no filesystems entry exists, create it
key_file.set_string("Context", "filesystems", filesystem_path)
key_file.set_string("Context", perm_type, filesystem_path)
else:
# Split existing paths and check if our path already exists
existing_paths_list = existing_paths.split(';')
@ -1694,7 +1697,7 @@ def global_add_file_permissions(path: str, override=True, system=False) -> tuple
# Only add if the path doesn't already exist
if normalized_new_path not in normalized_existing_paths:
key_file.set_string("Context", "filesystems",
key_file.set_string("Context", perm_type,
existing_paths + filesystem_path + ";")
# Write the modified metadata back
@ -1709,7 +1712,7 @@ def global_add_file_permissions(path: str, override=True, system=False) -> tuple
return False, f"Failed to modify permissions: {str(e)}"
def global_remove_file_permissions(path: str, override=True, system=False) -> tuple[bool, str]:
def global_remove_file_permissions(path: str, perm_type=None, override=True, system=False) -> tuple[bool, str]:
"""
Remove filesystem permissions from all Flatpak applications globally.
@ -1717,6 +1720,7 @@ def global_remove_file_permissions(path: str, override=True, system=False) -> tu
path (str): The path to revoke access to. Can be:
- "home" for home directory access
- "/path/to/directory" for custom directory access
perm_type (str): The type of permissions to remove (e.g. "filesystems", "persistent") default is "filesystems"
override (bool): Whether to use global metadata file instead of per-app.
system (bool): Whether to modify system-wide or user installation
@ -1725,7 +1729,7 @@ def global_remove_file_permissions(path: str, override=True, system=False) -> tu
"""
try:
key_file = get_perm_key_file(None, override, system)
perm_type = perm_type or "filesystems"
# Handle special case for home directory
if path.lower() == "host":
filesystem_path = "host"
@ -1740,7 +1744,7 @@ def global_remove_file_permissions(path: str, override=True, system=False) -> tu
filesystem_path = path.rstrip('/')
# Get existing filesystem paths
existing_paths = key_file.get_string("Context", "filesystems")
existing_paths = key_file.get_string("Context", perm_type)
if existing_paths is None:
return True, "No filesystem permissions to remove globally"
@ -1762,9 +1766,9 @@ def global_remove_file_permissions(path: str, override=True, system=False) -> tu
new_permissions = ";".join(filtered_paths_list)
if new_permissions:
# Save changes
key_file.set_string("Context", "filesystems", new_permissions)
key_file.set_string("Context", perm_type, new_permissions)
else:
key_file.remove_key("Context", "filesystems")
key_file.remove_key("Context", perm_type)
# Write the modified metadata back
try:
@ -2017,6 +2021,9 @@ def global_add_permission_value(perm_type: str, value: str, override=True, syste
key, val = parts
if val not in ['talk', 'own']:
return False, "Value must be in format 'key=value' with value as 'talk' or 'own'"
# Set the value
key_file.set_string(perm_type, key, val)
@ -2027,6 +2034,7 @@ def global_add_permission_value(perm_type: str, value: str, override=True, syste
except GLib.Error as e:
return False, f"Error adding permission: {str(e)}"
def global_remove_permission_value(perm_type: str, value: str, override=True, system=False) -> tuple[bool, str]:
"""
Remove a permission value from all Flatpak applications globally.

517
main.py
View file

@ -400,7 +400,15 @@ class MainWindow(Gtk.Window):
self.top_bar.pack_start(self.component_type_combo_label, False, False, 0)
self.top_bar.pack_start(self.component_type_combo, False, False, 0)
# Add repository button
# Add global overrides button
global_overrides_button = Gtk.Button()
global_overrides_button.set_tooltip_text("Global Setting Overrides")
global_overrides_button_icon = Gio.Icon.new_for_string('system-run')
global_overrides_button.set_image(Gtk.Image.new_from_gicon(global_overrides_button_icon, Gtk.IconSize.BUTTON))
global_overrides_button.get_style_context().add_class("dark-install-button")
global_overrides_button.connect("clicked", self.global_on_options_clicked)
# Add refresh metadata button
refresh_metadata_button = Gtk.Button()
refresh_metadata_button.set_tooltip_text("Refresh metadata")
refresh_metadata_button_icon = Gio.Icon.new_for_string('system-reboot-symbolic')
@ -427,6 +435,9 @@ class MainWindow(Gtk.Window):
# Add system controls to header
self.top_bar.pack_end(system_box, False, False, 0)
# Add refresh metadata button
self.top_bar.pack_end(global_overrides_button, False, False, 0)
# Add refresh metadata button
self.top_bar.pack_end(refresh_metadata_button, False, False, 0)
@ -1390,7 +1401,7 @@ class MainWindow(Gtk.Window):
button.get_style_context().add_class(add_rm_style)
buttons_box.pack_end(button, False, False, 0)
# Install/Remove button
# App options button
if is_installed:
button = self.create_button(
self.on_app_options_clicked,
@ -2094,7 +2105,7 @@ class MainWindow(Gtk.Window):
success, message = libflatpak_query.remove_file_permissions(
app_id,
path,
None,
"filesystems",
self.system_mode
)
if success:
@ -2142,7 +2153,7 @@ class MainWindow(Gtk.Window):
success, message = libflatpak_query.add_file_permissions(
app_id,
path,
None,
"filesystems",
self.system_mode
)
if success:
@ -2186,6 +2197,504 @@ class MainWindow(Gtk.Window):
parent_box.add(row)
return row, switch
def _global_add_bus_section(self, listbox, section_title, perm_type):
"""Helper method to add System Bus or Session Bus section"""
# Add separator
sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
listbox.add(sep)
# Add section header
row_header = Gtk.ListBoxRow(selectable=False)
box_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label_header = Gtk.Label(label=f"<b>{section_title}</b>",
use_markup=True, xalign=0)
box_header.pack_start(label_header, True, True, 0)
row_header.add(box_header)
listbox.add(row_header)
# Get permissions
success, perms = libflatpak_query.global_list_other_perm_values(perm_type, True, self.system_mode)
if not success:
perms = {"paths": []}
# Add Talks section
talks_row = Gtk.ListBoxRow(selectable=False)
talks_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
talks_row.add(talks_box)
talks_header = Gtk.Label(label="Talks", xalign=0)
talks_box.pack_start(talks_header, False, False, 0)
# Add separator between header and paths
talks_box.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
False, False, 0)
# Add talk paths
for path in perms["paths"]:
if "talk" in path:
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=path.split("=")[0], xalign=0)
vbox.pack_start(label, True, True, 0)
btn = Gtk.Button(label="Remove")
btn.connect("clicked", self._global_on_remove_path, path, perm_type)
hbox.pack_end(btn, False, True, 0)
talks_box.add(row)
listbox.add(talks_row)
# Add Owns section
owns_row = Gtk.ListBoxRow(selectable=False)
owns_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
owns_row.add(owns_box)
owns_header = Gtk.Label(label="Owns", xalign=0)
owns_box.pack_start(owns_header, False, False, 0)
# Add separator between header and paths
owns_box.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
False, False, 0)
# Add own paths
for path in perms["paths"]:
if "own" in path:
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=path.split("=")[0], xalign=0)
vbox.pack_start(label, True, True, 0)
btn = Gtk.Button(label="Remove")
btn.connect("clicked", self._on_global_remove_path, path, perm_type)
hbox.pack_end(btn, False, True, 0)
owns_box.add(row)
owns_row.show_all()
listbox.add(owns_row)
# Add add button
add_path_row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
add_path_row.add(hbox)
btn = Gtk.Button(label="Add Path")
btn.connect("clicked", self._global_on_add_path, perm_type)
hbox.pack_end(btn, False, True, 0)
listbox.add(add_path_row)
def _global_add_path_section(self, listbox, section_title, perm_type):
"""Helper method to add sections with paths (Persistent, Environment)"""
# Add separator
sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
listbox.add(sep)
# Add section header
row_header = Gtk.ListBoxRow(selectable=False)
box_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label_header = Gtk.Label(label=f"<b>{section_title}</b>",
use_markup=True, xalign=0)
box_header.pack_start(label_header, True, True, 0)
row_header.add(box_header)
listbox.add(row_header)
# Get permissions
if perm_type == "persistent":
success, perms = libflatpak_query.global_list_other_perm_toggles(perm_type, True, self.system_mode)
else:
success, perms = libflatpak_query.global_list_other_perm_values(perm_type, True, self.system_mode)
if not success:
perms = {"paths": []}
# Add paths
for path in perms["paths"]:
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=path, xalign=0)
vbox.pack_start(label, True, True, 0)
btn = Gtk.Button(label="Remove")
btn.connect("clicked", self._global_on_remove_path, path, perm_type)
hbox.pack_end(btn, False, True, 0)
listbox.add(row)
# Add add button
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
btn = Gtk.Button(label="Add Path")
btn.connect("clicked", self._global_on_add_path, perm_type)
hbox.pack_end(btn, False, True, 0)
listbox.add(row)
def _global_add_filesystem_section(self, listbox, section_title):
"""Helper method to add the Filesystems section"""
# Add separator
sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
listbox.add(sep)
# Add section header
row_header = Gtk.ListBoxRow(selectable=False)
box_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label_header = Gtk.Label(label=f"<b>{section_title}</b>",
use_markup=True, xalign=0)
box_header.pack_start(label_header, True, True, 0)
row_header.add(box_header)
listbox.add(row_header)
# Get filesystem permissions
success, perms = libflatpak_query.global_list_file_perms(True, self.system_mode)
if not success:
perms = {"paths": [], "special_paths": []}
# Add special paths as toggles
special_paths = [
("All user files", "home", "Access to all user files"),
("All system files", "host", "Access to all system files"),
("All system libraries, executables and static data", "host-os", "Access to system libraries and executables"),
("All system configurations", "host-etc", "Access to system configurations")
]
for display_text, option, description in special_paths:
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=display_text, xalign=0)
desc = Gtk.Label(label=description, xalign=0)
vbox.pack_start(label, True, True, 0)
vbox.pack_start(desc, True, True, 0)
switch = Gtk.Switch()
switch.props.valign = Gtk.Align.CENTER
switch.set_active(option in perms["special_paths"])
switch.set_sensitive(True)
switch.connect("state-set", self._global_on_switch_toggled, "filesystems", option)
hbox.pack_end(switch, False, True, 0)
listbox.add(row)
# Add normal paths with remove buttons
for path in perms["paths"]:
if path != "":
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=path, xalign=0)
vbox.pack_start(label, True, True, 0)
btn = Gtk.Button(label="Remove")
btn.connect("clicked", self._global_on_remove_path, path)
hbox.pack_end(btn, False, True, 0)
listbox.add(row)
# Add add button
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
btn = Gtk.Button(label="Add Path")
btn.connect("clicked", self._global_on_add_path)
hbox.pack_end(btn, False, True, 0)
listbox.add(row)
def global_on_options_clicked(self, button):
"""Handle the app options click"""
# Create window (as before)
self.global_options_window = Gtk.Window(title="Global Setting Overrides")
self.global_options_window.set_default_size(500, 700)
# Set subtitle
header_bar = Gtk.HeaderBar(title="Global Setting Overrides",
subtitle="Override list of resources selectively granted to applications")
header_bar.set_show_close_button(True)
self.global_options_window.set_titlebar(header_bar)
# Create main container with padding
box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
box_outer.set_border_width(20)
self.global_options_window.add(box_outer)
# Create scrolled window for content
scrolled = Gtk.ScrolledWindow()
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
# Create list box for options
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
# No portals section. Portals are only handled on per-user basis.
# Add other sections with correct permission types
self._global_add_section(listbox, "Shared", "shared", [
("Network", "network", "Can communicate over network"),
("Inter-process communications", "ipc", "Can communicate with other applications")
])
self._global_add_section(listbox, "Sockets", "sockets", [
("X11 windowing system", "x11", "Can access X11 display server"),
("Wayland windowing system", "wayland", "Can access Wayland display server"),
("Fallback to X11 windowing system", "fallback-x11", "Can fallback to X11 if Wayland unavailable"),
("PulseAudio sound server", "pulseaudio", "Can access PulseAudio sound system"),
("D-Bus session bus", "session-bus", "Can communicate with session D-Bus"),
("D-Bus system bus", "system-bus", "Can communicate with system D-Bus"),
("Secure Shell agent", "ssh-auth", "Can access SSH authentication agent"),
("Smart cards", "pcsc", "Can access smart card readers"),
("Printing system", "cups", "Can access printing subsystem"),
("GPG-Agent directories", "gpg-agent", "Can access GPG keyring"),
("Inherit Wayland socket", "inherit-wayland-socket", "Can inherit existing Wayland socket")
])
self._global_add_section(listbox, "Devices", "devices", [
("GPU Acceleration", "dri", "Can use hardware graphics acceleration"),
("Input devices", "input", "Can access input devices"),
("Virtualization", "kvm", "Can access virtualization services"),
("Shared memory", "shm", "Can use shared memory"),
("All devices (e.g. webcam)", "all", "Can access all device files")
])
self._global_add_section(listbox, "Features", "features", [
("Development syscalls", "devel", "Can perform development operations"),
("Programs from other architectures", "multiarch", "Can execute programs from other architectures"),
("Bluetooth", "bluetooth", "Can access Bluetooth hardware"),
("Controller Area Network bus", "canbus", "Can access CAN bus"),
("Application Shared Memory", "per-app-dev-shm", "Can use shared memory for IPC")
])
# Add Filesystems section
self._global_add_filesystem_section(listbox, "Filesystems")
self._global_add_path_section(listbox, "Persistent", "persistent")
self._global_add_path_section(listbox, "Environment", "environment")
self._global_add_bus_section(listbox, "System Bus", "system_bus")
self._global_add_bus_section(listbox, "Session Bus", "session_bus")
# Add widgets to container
box_outer.pack_start(scrolled, True, True, 0)
scrolled.add(listbox)
# Connect destroy signal
self.global_options_window.connect("destroy", lambda w: w.destroy())
# Show window
self.global_options_window.show_all()
def _global_add_section(self, listbox, section_title, perm_type=None, section_options=None):
"""Helper method to add a section with multiple options"""
# Add separator
sep = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
listbox.add(sep)
# Add section header
row_header = Gtk.ListBoxRow(selectable=False)
box_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
label_header = Gtk.Label(label=f"<b>{section_title}</b>",
use_markup=True, xalign=0)
box_header.pack_start(label_header, True, True, 0)
row_header.add(box_header)
listbox.add(row_header)
if section_title in ["Persistent", "Environment", "System Bus", "Session Bus"]:
success, perms = libflatpak_query.global_list_other_perm_toggles(perm_type, True, self.system_mode)
if not success:
perms = {"paths": []}
else:
success, perms = libflatpak_query.global_list_other_perm_toggles(perm_type, True, self.system_mode)
if not success:
perms = {"paths": []}
if section_options:
# Add options
for display_text, option, description in section_options:
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=display_text, xalign=0)
desc = Gtk.Label(label=description, xalign=0)
vbox.pack_start(label, True, True, 0)
vbox.pack_start(desc, True, True, 0)
switch = Gtk.Switch()
switch.props.valign = Gtk.Align.CENTER
# Handle portal permissions differently
if section_title == "Portals":
if option in perms:
switch.set_active(perms[option] == 'yes')
switch.set_sensitive(True)
else:
switch.set_sensitive(False)
else:
switch.set_active(option in [p.lower() for p in perms["paths"]])
switch.set_sensitive(True)
switch.connect("state-set", self._global_on_switch_toggled, perm_type, option)
hbox.pack_end(switch, False, True, 0)
listbox.add(row)
def _global_on_switch_toggled(self, switch, state, perm_type, option):
"""Handle switch toggle events"""
success, message = libflatpak_query.global_toggle_other_perms(
perm_type,
option.lower(),
state,
True,
self.system_mode
)
if not success:
switch.set_active(not state)
print(f"Error: {message}")
def _global_on_remove_path(self, button, path, perm_type=None):
"""Handle remove path button click"""
if perm_type:
if perm_type == "persistent":
success, message = libflatpak_query.global_remove_file_permissions(
path,
"persistent",
True,
self.system_mode
)
else:
success, message = libflatpak_query.global_remove_permission_value(
perm_type,
path,
True,
self.system_mode
)
else:
success, message = libflatpak_query.global_remove_file_permissions(
path,
"filesystems",
True,
self.system_mode
)
if success:
# Refresh the current window
self.global_options_window.destroy()
self.global_on_options_clicked(None)
def _global_on_add_path(self, button, perm_type=None):
"""Handle add path button click"""
dialog = Gtk.Dialog(
title="Add Filesystem Path",
parent=self.global_options_window,
modal=True,
destroy_with_parent=True,
)
# Add buttons separately
dialog.add_button("Cancel", Gtk.ResponseType.CANCEL)
dialog.add_button("Add", Gtk.ResponseType.OK)
entry = Gtk.Entry()
entry.set_placeholder_text("Enter filesystem path")
dialog.vbox.pack_start(entry, True, True, 0)
dialog.show_all()
response = dialog.run()
if response == Gtk.ResponseType.OK:
path = entry.get_text()
if perm_type:
if perm_type == "persistent":
success, message = libflatpak_query.global_add_file_permissions(
path,
"persistent",
True,
self.system_mode
)
else:
success, message = libflatpak_query.global_add_permission_value(
perm_type,
path,
True,
self.system_mode
)
else:
success, message = libflatpak_query.global_add_file_permissions(
path,
"filesystems",
True,
self.system_mode
)
if success:
# Refresh the current window
self.global_options_window.destroy()
self.global_on_options_clicked(None)
message_type = Gtk.MessageType.INFO
else:
message_type = Gtk.MessageType.ERROR
if message:
error_dialog = Gtk.MessageDialog(
transient_for=None, # Changed from self
modal=True,
destroy_with_parent=True,
message_type=message_type,
buttons=Gtk.ButtonsType.OK,
text=message
)
error_dialog.run()
error_dialog.destroy()
dialog.destroy()
def _global_add_option(self, parent_box, label_text, description):
"""Helper method to add an individual option"""
row = Gtk.ListBoxRow(selectable=False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
row.add(hbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox.pack_start(vbox, True, True, 0)
label = Gtk.Label(label=label_text, xalign=0)
desc = Gtk.Label(label=description, xalign=0)
vbox.pack_start(label, True, True, 0)
vbox.pack_start(desc, True, True, 0)
switch = Gtk.Switch()
switch.props.valign = Gtk.Align.CENTER
hbox.pack_end(switch, False, True, 0)
parent_box.add(row)
return row, switch
def on_update_clicked(self, button, app):
"""Handle the Remove button click with removal options"""
details = app.get_details()

File diff suppressed because it is too large Load diff