lol
This commit is contained in:
1 parent
93fb89c216
commit
13dae4fba7
9 files changed
+20
-746
No files matched your search
@@ -34,7 +34,7 @@ def handle_application_search(launcher, query: str):
|
||||
def bake_favorite_slot(launcher, app, **kwargs) -> Button:
|
||||
return Button(
|
||||
child=Image(pixbuf=app.get_icon_pixbuf(), size=40),
|
||||
style="background-color: transparent; border-radius: 10px; padding: 10px;",
|
||||
name="fav-item",
|
||||
tooltip_text=app.description,
|
||||
on_clicked=lambda *_: (app.launch(), launcher.set_visible(False)),
|
||||
**kwargs,
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
# desktop_buttons.py
|
||||
|
||||
import subprocess
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.utils import exec_shell_command
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class DesktopButtonManager:
|
||||
def __init__(self, emoji_viewport):
|
||||
self.emoji_viewport = emoji_viewport
|
||||
|
||||
def show_desktop_buttons(self):
|
||||
"""Display buttons for desktop controls like Wi-Fi, Bluetooth, Dark Mode, etc."""
|
||||
self.emoji_viewport.children = []
|
||||
row = Box(orientation="h", spacing=10)
|
||||
desktop_controls = [
|
||||
{
|
||||
"name": "Wi-Fi",
|
||||
"icon": ("", ""),
|
||||
"toggle": self.toggle_wifi,
|
||||
"state": self.check_wifi_state,
|
||||
},
|
||||
{
|
||||
"name": "Bluetooth",
|
||||
"icon": ("", ""),
|
||||
"toggle": self.toggle_bluetooth,
|
||||
"state": self.check_bluetooth_state,
|
||||
},
|
||||
{
|
||||
"name": "Dark Mode",
|
||||
"icon": ("", ""),
|
||||
"toggle": self.toggle_dark_mode,
|
||||
"state": self.check_dark_mode_state,
|
||||
},
|
||||
{
|
||||
"name": "Idle",
|
||||
"icon": ("", ""),
|
||||
"toggle": self.toggle_idle_mode,
|
||||
"state": lambda: False, # Modify as needed
|
||||
},
|
||||
{
|
||||
"name": "Do Not Disturb",
|
||||
"icon": ("", ""),
|
||||
"toggle": self.toggle_dnd,
|
||||
"state": None,
|
||||
},
|
||||
]
|
||||
|
||||
for i, control in enumerate(desktop_controls):
|
||||
if control["state"] and callable(control["state"]):
|
||||
current_state = control["state"]()
|
||||
else:
|
||||
current_state = False
|
||||
|
||||
icon = control["icon"][0] if current_state else control["icon"][1]
|
||||
button = Button(
|
||||
child=Box(
|
||||
orientation="h",
|
||||
spacing=20,
|
||||
children=[
|
||||
Label(
|
||||
label=icon,
|
||||
name="icon-label",
|
||||
style="font-size:32px; margin:0 12px 0 0; padding:12px;",
|
||||
),
|
||||
],
|
||||
),
|
||||
on_clicked=control["toggle"],
|
||||
name="db-item",
|
||||
tooltip_text=f"{control['name']} is {'on' if current_state else 'off'}",
|
||||
)
|
||||
row.add(button)
|
||||
if (i + 1) % 8 == 0:
|
||||
self.emoji_viewport.add(row)
|
||||
row = Box(
|
||||
orientation="h", spacing=10
|
||||
) # New row for next set of buttons
|
||||
|
||||
# Add remaining buttons in last row
|
||||
if len(desktop_controls) % 8 != 0:
|
||||
self.emoji_viewport.add(row)
|
||||
|
||||
def toggle_wifi(self, *_):
|
||||
state = self.check_wifi_state()
|
||||
command = "nmcli radio wifi on" if not state else "nmcli radio wifi off"
|
||||
exec_shell_command(command)
|
||||
logger.info("Toggled Wi-Fi.")
|
||||
|
||||
def check_wifi_state(self):
|
||||
result = subprocess.run(
|
||||
"nmcli radio wifi", shell=True, capture_output=True, text=True
|
||||
)
|
||||
return "enabled" in result.stdout
|
||||
|
||||
def toggle_bluetooth(self, *_):
|
||||
state = self.check_bluetooth_state()
|
||||
command = "bluetoothctl power on" if not state else "bluetoothctl power off"
|
||||
exec_shell_command(command)
|
||||
logger.info("Toggled Bluetooth.")
|
||||
|
||||
def check_bluetooth_state(self):
|
||||
result = exec_shell_command("bluetoothctl show")
|
||||
return "Powered: yes" in result
|
||||
|
||||
def toggle_dark_mode(self, *_):
|
||||
command = os.path.expanduser("~/fabric/assets/scripts/dark-theme.sh --toggle")
|
||||
exec_shell_command(command)
|
||||
logger.info("Toggled Dark Mode.")
|
||||
|
||||
def check_dark_mode_state(self):
|
||||
result = exec_shell_command(
|
||||
"gsettings get org.gnome.desktop.interface color-scheme"
|
||||
)
|
||||
current_mode = result.strip().replace("'", "")
|
||||
return current_mode == "prefer-dark"
|
||||
|
||||
def toggle_idle_mode(self, *_):
|
||||
# Add logic for idle mode toggle if needed
|
||||
logger.info("Toggled Idle Mode.")
|
||||
|
||||
def toggle_dnd(self, *_):
|
||||
current_state = self.check_dnd_state()
|
||||
command = (
|
||||
"gsettings set org.gnome.desktop.notifications show-banners true"
|
||||
if current_state
|
||||
else "gsettings set org.gnome.desktop.notifications show-banners false"
|
||||
)
|
||||
exec_shell_command(command)
|
||||
logger.info("Toggled Do Not Disturb.")
|
||||
|
||||
def check_dnd_state(self):
|
||||
result = exec_shell_command(
|
||||
"gsettings get org.gnome.desktop.notifications show-banners"
|
||||
)
|
||||
return result.strip() == "false"
|
||||
@@ -1,55 +0,0 @@
|
||||
import json
|
||||
import os
|
||||
from loguru import logger
|
||||
from fabric.utils import exec_shell_command_async
|
||||
import subprocess
|
||||
|
||||
|
||||
class EmojiItem:
|
||||
def __init__(self, str: str, name: str, slug: str, group: str):
|
||||
self.str = str
|
||||
self.name = name
|
||||
self.slug = slug
|
||||
self.group = group
|
||||
|
||||
|
||||
class EmojiService:
|
||||
def __init__(self):
|
||||
self.emoji = None
|
||||
self.load_emojis()
|
||||
|
||||
def load_emojis(self):
|
||||
try:
|
||||
# Construct the path using os.path.expanduser to handle the '~' correctly
|
||||
emoji_path = os.path.expanduser("~/fabric/assets/emoji.json")
|
||||
with open(emoji_path, "r") as f:
|
||||
data = json.load(f)
|
||||
self.emoji = [
|
||||
EmojiItem(str, item["name"], item["slug"], item["group"])
|
||||
for str, item in data.items()
|
||||
]
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load emoji data: {e}")
|
||||
self.emoji = []
|
||||
|
||||
def get_emojis(self):
|
||||
return self.emoji
|
||||
|
||||
def query(self, filter: str):
|
||||
if self.emoji is None:
|
||||
return []
|
||||
return [
|
||||
e
|
||||
for e in self.emoji
|
||||
if filter in e.name or filter in e.slug or filter in e.group
|
||||
][:44]
|
||||
|
||||
def copy(self, emoji_item: EmojiItem):
|
||||
try:
|
||||
# Use subprocess to run the wl-copy command to copy emoji
|
||||
subprocess.run(["wl-copy"], input=emoji_item.str.encode(), check=True)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to copy emoji: {e}")
|
||||
|
||||
|
||||
emoji_service = EmojiService()
|
||||
@@ -1,43 +0,0 @@
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
|
||||
class Inhibit:
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
|
||||
@property
|
||||
def is_inhibit(self):
|
||||
"""Check if inhibition is active."""
|
||||
return self._id is not None
|
||||
|
||||
def _inhibit(self, command, data):
|
||||
"""Send a command to the DBus service to inhibit or un-inhibit."""
|
||||
dbus_command = (
|
||||
f"dbus-send --print-reply --dest=org.freedesktop.ScreenSaver "
|
||||
f"/org/freedesktop/ScreenSaver org.freedesktop.ScreenSaver.{command} {data}"
|
||||
)
|
||||
output = subprocess.run(
|
||||
dbus_command, shell=True, capture_output=True, text=True
|
||||
)
|
||||
|
||||
if command == "Inhibit":
|
||||
match = re.search(r"uint32\s+(\d+)", output.stdout)
|
||||
return int(match.group(1)) if match else None
|
||||
return None
|
||||
|
||||
def toggle(self):
|
||||
"""Toggle the inhibition state."""
|
||||
if self._id is None:
|
||||
self._id = self._inhibit("Inhibit", "string:'ags' string:'Manual pause'")
|
||||
else:
|
||||
self._id = self._inhibit("UnInhibit", f"uint32:{self._id}")
|
||||
|
||||
# Notify that the state has changed
|
||||
self.changed("is-inhibit")
|
||||
|
||||
def changed(self, property_name):
|
||||
"""Notify listeners that a property has changed."""
|
||||
print(
|
||||
f"Property '{property_name}' changed. Inhibition is now {'active' if self.is_inhibit else 'inactive'}."
|
||||
)
|
||||
@@ -1,450 +0,0 @@
|
||||
|
||||
* {
|
||||
all: unset;
|
||||
color: @foreground;
|
||||
font-size: 16px;
|
||||
font-family: "Product Sans", Roboto, "Font Awesome 6 Free", Helvetica, Arial,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background-color: @surface;
|
||||
padding: 3px;
|
||||
}
|
||||
#bar label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#modules_left,
|
||||
#modules_center,
|
||||
#modules_right {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
#workspaces {
|
||||
border-radius: 16px;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
color: @onSurface;
|
||||
background: @surfaceContainer;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
#workspaces > button {
|
||||
padding: 0px 5px;
|
||||
margin: 4px 0px;
|
||||
margin-right: 3px;
|
||||
border-radius: 100px;
|
||||
min-width: 20px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
|
||||
#workspaces > button:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
#workspaces > button label {
|
||||
color: @onSurface;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#workspaces > button:hover {
|
||||
color: @onSurface;
|
||||
background-color: mix(@onSurface, @surface, 0.85);
|
||||
}
|
||||
|
||||
#workspaces > button.active {
|
||||
background: @secondaryContainer;
|
||||
}
|
||||
|
||||
#workspaces > button.active label {
|
||||
color: @onSecondaryContainer;
|
||||
}
|
||||
|
||||
#workspaces > button.empty {
|
||||
color: @onSurfaceVariant;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
#datetime {
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 16px;
|
||||
padding: 2px 10px 0px 10px;
|
||||
}
|
||||
|
||||
#kb_layout {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* system tray */
|
||||
#tray {
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 100px;
|
||||
padding: 2px 10px 0px 10px;
|
||||
}
|
||||
|
||||
#tray > button {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#tray image {
|
||||
color: @onSurface;
|
||||
}
|
||||
|
||||
/* menu and menu items (written for the system tray) */
|
||||
menu {
|
||||
border-radius: 10px;
|
||||
background-color: @surfaceContainer;
|
||||
}
|
||||
|
||||
menu > menuitem {
|
||||
border-radius: 0px;
|
||||
padding: 6px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
color: @onSurface;
|
||||
}
|
||||
|
||||
menu > menuitem:first-child {
|
||||
margin-top: 1px;
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
}
|
||||
|
||||
menu > menuitem:last-child {
|
||||
margin-bottom: 1px;
|
||||
border-radius: 0px 0px 8px 8px;
|
||||
}
|
||||
|
||||
menu > menuitem:hover {
|
||||
background-color: mix(@onSurface, @surface, 0.85);
|
||||
}
|
||||
|
||||
tooltip {
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 11px;
|
||||
outline: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
tooltip label {
|
||||
color: @onSurface;
|
||||
outline: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#logo {
|
||||
background-color: @secondaryContainer;
|
||||
color: @onSecondaryContainer;
|
||||
border-radius: 100px;
|
||||
min-width: 38px;
|
||||
padding: 0px;
|
||||
}
|
||||
#logo label,
|
||||
#logo .icon,
|
||||
#logo image {
|
||||
color: @onSecondaryContainer;
|
||||
font-weight: 400;
|
||||
margin: 0px 3px 0px 0px;
|
||||
}
|
||||
|
||||
#logo:hover {
|
||||
background-color: mix(@secondaryContainer, @onSecondaryContainer, 0.05);
|
||||
box-shadow: 00px 3px 3px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#applets {
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 100px;
|
||||
padding: 2px 10px 2px 10px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#applets .icon {
|
||||
color: @onSurface;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#applets > button {
|
||||
color: @onSurface;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#battery {
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 100px;
|
||||
padding: 2px 10px 2px 10px;
|
||||
}
|
||||
|
||||
#battery label {
|
||||
color: @onSurface;
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
#battery .icon {
|
||||
color: @onSurface;
|
||||
}
|
||||
|
||||
#battery.critical {
|
||||
background-color: @error;
|
||||
}
|
||||
|
||||
#battery.critical label,
|
||||
#battery.critical .icon {
|
||||
color: @onError;
|
||||
}
|
||||
|
||||
#power-event {
|
||||
transition: all 0.1s ease;
|
||||
background-color: @surfaceContainer;
|
||||
border-radius: 999px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
|
||||
#power-shutdown > *,
|
||||
#power-reboot > *,
|
||||
#power-logout > *,
|
||||
#power-suspend > *,
|
||||
#power-lock > *{
|
||||
color: @foreground;
|
||||
padding:4px;
|
||||
margin: 4px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
#power-shutdown:hover > *, #power-shutdown:focus > *,
|
||||
#power-reboot:hover > *, #power-reboot:focus > *,
|
||||
#power-logout:hover > *, #power-logout:focus > *,
|
||||
#power-suspend:hover > *, #power-suspend:focus > *,
|
||||
#power-lock:hover > *, #power-lock:focus > *{
|
||||
color: @onSurface;
|
||||
background-color: mix(@onSurface, @surface, 0.85);
|
||||
}
|
||||
|
||||
#shutdown-confirm > *, #reboot-confirm > *, #logout-confirm > *, #suspend-confirm > * {
|
||||
color: @background;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
padding: 4px;
|
||||
margin: 4px;
|
||||
border-radius: 999px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
#shutdown-confirm:hover > *, #reboot-confirm:hover > *, #logout-confirm:hover > *, #suspend-confirm:hover > * {
|
||||
color: @onSurface;
|
||||
background-color: mix(@onSurface, @surface, 0.85);
|
||||
}
|
||||
|
||||
#confirm-box {
|
||||
background-color: @surfaceContainer;
|
||||
margin: 3px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
#accept, #cancel {
|
||||
color: @foreground;
|
||||
padding: 2px;
|
||||
margin: 4px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
#accept:hover, #cancel:hover {
|
||||
color: @onSurface;
|
||||
background-color: mix(@onSurface, @surface, 0.85);
|
||||
}
|
||||
|
||||
|
||||
#launcher {
|
||||
margin: 18px;
|
||||
border: 1px solid @outlineVariant;
|
||||
background-color: @surface;
|
||||
border-radius: 24px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
#launcher button {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
|
||||
#launcher button:focus {
|
||||
box-shadow: inset 0 0 0 1px @primary;
|
||||
background-color: @background;
|
||||
color: @foreground;
|
||||
}
|
||||
|
||||
#launcher button:hover {
|
||||
box-shadow: inset 0 0 0 1px @background;
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
#launcher entry {
|
||||
transition: all 0.1s ease;
|
||||
border-radius: 11px;
|
||||
color: @foreground;
|
||||
background-color:@surfaceContainer;
|
||||
box-shadow: inset 0 0 0 @background;
|
||||
padding: 10px;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
#launcher entry:focus {
|
||||
box-shadow: inset 0 0 0 1px @primary;
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
#launcher entry:hover {
|
||||
box-shadow: inset 0 0 0 1px @background;
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
#launcher entry selection {
|
||||
color: @outline;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#launcher button#app-item {
|
||||
border-radius: 11px;
|
||||
color: @foreground;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
transition: 200ms;
|
||||
padding: 7pt;
|
||||
}
|
||||
|
||||
#launcher button#app-item:hover #title,
|
||||
#launcher button#app-item:focus #title {
|
||||
color: @primary;
|
||||
}
|
||||
|
||||
#launcher button#app-item:hover #description,
|
||||
#launcher button#app-item:focus #description {
|
||||
color: @inversePrimary;
|
||||
}
|
||||
|
||||
#launcher button#app-item:hover image,
|
||||
#launcher button#app-item:focus image {
|
||||
-gtk-icon-shadow: 2px 2px @primary;
|
||||
}
|
||||
|
||||
#launcher button#app-item:active {
|
||||
background-color: @primaryContainer;
|
||||
border-radius: 11px;
|
||||
box-shadow: inset 0 0 0 1px rgba(158, 142, 130, 0.04);
|
||||
}
|
||||
|
||||
#launcher button#app-item:active #title {
|
||||
color: @foreground;
|
||||
}
|
||||
|
||||
#launcher button#emoji-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#launcher button#emoji-item:disabled {
|
||||
color: mix(@onSurface, transparent, 0.38);
|
||||
}
|
||||
|
||||
#launcher button#emoji-item label {
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
#launcher button#emoji-item:hover,
|
||||
#launcher button#emoji-item:focus {
|
||||
text-shadow: 2px 2px 2px @primary;
|
||||
}
|
||||
|
||||
#launcher button#cliphist-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
window#launcher button#cliphist-item:disabled {
|
||||
color: mix(@onSurface, transparent, 0.38);
|
||||
}
|
||||
|
||||
#launcher button#cliphist-item:hover,
|
||||
#launcher button#cliphist-item:focus {
|
||||
text-shadow: 2px 2px 2px @primary;
|
||||
}
|
||||
|
||||
#launcher button#sh-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#launcher button#sh-item:disabled {
|
||||
color: mix(@onSurface, transparent, 0.38);
|
||||
}
|
||||
|
||||
#launcher button#sh-item:hover,
|
||||
#launcher button#sh-item:focus {
|
||||
text-shadow: 2pt 2pt 2pt @primary;
|
||||
}
|
||||
|
||||
#launcher button#help-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#launcher button#help-item:hover label,
|
||||
#launcher button#help-item:focus label{
|
||||
text-shadow: 2px 2px 2px @primary;
|
||||
}
|
||||
|
||||
#launcher button#wall-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#launcher button#wall-item:disabled {
|
||||
color: mix(@onSurface, transparent, 0.38);
|
||||
}
|
||||
|
||||
#launcher button#wall-item:hover,
|
||||
#launcher button#wall-item:focus {
|
||||
text-shadow: 10pt 10pt 10pt @primary;
|
||||
background-color: mix(@onSurface, @surface, 0.92);
|
||||
}
|
||||
|
||||
#launcher button#db-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#launcher button#db-item:hover label,
|
||||
#launcher button#db-item:focus label{
|
||||
text-shadow: 4px 4px 4px @primary;
|
||||
/* margin: 12px;*/
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
CACHE_DIR = os.getenv("XDG_CACHE_HOME", os.path.join(os.path.expanduser("~"), ".cache"))
|
||||
BINS = os.path.join(CACHE_DIR, "binaries")
|
||||
|
||||
|
||||
class Sh:
|
||||
def __init__(self):
|
||||
self.reload() # Load binaries on initialization
|
||||
|
||||
def ls(self, path):
|
||||
if not os.path.exists(path):
|
||||
return []
|
||||
try:
|
||||
return (
|
||||
subprocess.check_output(f"ls {path}", shell=True, text=True)
|
||||
.strip()
|
||||
.splitlines()
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
return []
|
||||
|
||||
def reload(self):
|
||||
"""Reload the binaries from the PATH environment variable."""
|
||||
paths = os.getenv("PATH", "").split(":")
|
||||
bins = []
|
||||
|
||||
for path in paths:
|
||||
bins.extend(self.ls(path))
|
||||
|
||||
# Remove duplicates and save to file
|
||||
unique_bins = set(bins)
|
||||
with open(BINS, "w") as f:
|
||||
f.write("\n".join(unique_bins))
|
||||
|
||||
@staticmethod
|
||||
def query(filter_str):
|
||||
"""Filter binaries using fzf and return the results."""
|
||||
try:
|
||||
result = subprocess.check_output(
|
||||
f"cat {BINS} | fzf -f {filter_str} | head -n 16", shell=True, text=True
|
||||
)
|
||||
return list(dict.fromkeys(result.splitlines())) # Deduplicate results
|
||||
except subprocess.CalledProcessError:
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def run(args: str):
|
||||
"""Execute a command and print its output."""
|
||||
try:
|
||||
output = subprocess.check_output(args, shell=True, text=True)
|
||||
print(f":sh {args.strip()}:")
|
||||
print(output)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print(f"Error running command: {err}")
|
||||
@@ -39,4 +39,4 @@ class ShellCommandManager:
|
||||
Sh.run(cmd) # Run the shell command
|
||||
self.launcher.set_visible(False) # Close the launcher after execution
|
||||
except Exception as e:
|
||||
print(f"Error executing command: {e}")
|
||||
logger.error(f"Error executing command: {e}")
|
||||
@@ -88,7 +88,7 @@ class WallpaperManager:
|
||||
)
|
||||
logger.info(f"Wallpaper applied: {wallpaper_path}")
|
||||
except Exception as e:
|
||||
logger.info(f"Error applying wallpaper: {e}")
|
||||
logger.error(f"Error applying wallpaper: {e}")
|
||||
|
||||
def apply_wallpaper_random(self):
|
||||
script_path = os.path.expanduser("~/dotfiles/hypr/scripts/wallpaper.py")
|
||||
@@ -99,4 +99,4 @@ class WallpaperManager:
|
||||
)
|
||||
logger.info("Random wallpaper applied.")
|
||||
except Exception as e:
|
||||
logger.info(f"Error applying random wallpaper: {e}")
|
||||
logger.error(f"Error applying random wallpaper: {e}")
|
||||
@@ -354,6 +354,22 @@ tooltip label {
|
||||
color: @foreground;
|
||||
}
|
||||
|
||||
#launcher button#fav-item{
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#launcher button#fav-item:hover image,
|
||||
#launcher button#fav-item:focus image {
|
||||
-gtk-icon-shadow: 2px 2px @primary;
|
||||
}
|
||||
|
||||
#launcher button#fav-item:active {
|
||||
background-color: transparent;
|
||||
border-radius: 11px;
|
||||
box-shadow: inset 0 0 0 1px rgba(158, 142, 130, 0.04);
|
||||
}
|
||||
|
||||
#launcher button#emoji-item {
|
||||
border-radius: 11px;
|
||||
background-color: transparent;
|
||||
|
||||
Reference in new issue
Block a user