update
This commit is contained in:
@@ -0,0 +1,456 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from fabric.utils.helpers import exec_shell_command_async, get_relative_path
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.label import Label
|
||||
from gi.repository import Gdk, GLib
|
||||
from loguru import logger
|
||||
|
||||
import config.data as data
|
||||
import modules.icons as icons
|
||||
|
||||
SCREENSHOT_SCRIPT = get_relative_path("../scripts/screenshot.sh")
|
||||
POMODORO_SCRIPT = get_relative_path("../scripts/pomodoro.sh")
|
||||
OCR_SCRIPT = get_relative_path("../scripts/ocr.sh")
|
||||
GAMEMODE_SCRIPT = get_relative_path("../scripts/gamemode.sh")
|
||||
SCREENRECORD_SCRIPT = get_relative_path("../scripts/screenrecord.sh")
|
||||
|
||||
# Tooltips
|
||||
## Screenshot
|
||||
tooltip_ssregion = """<b><u>Region Screenshot</u></b>
|
||||
<b>Left Click:</b> Take a screenshot of a selected region.
|
||||
<b>Right Click:</b> Take a mockup screenshot of a selected region."""
|
||||
|
||||
tooltip_ssfull = """<b><u>Screenshot</u></b>
|
||||
<b>Left Click:</b> Take a fullscreen screenshot.
|
||||
<b>Right Click:</b> Take a mockup fullscreen screenshot."""
|
||||
|
||||
tooltip_sswindow = """<b><u>Window Screenshot</u></b>
|
||||
<b>Left Click:</b> Take a screenshot of the active window.
|
||||
<b>Right Click:</b> Take a mockup screenshot of the active window."""
|
||||
|
||||
tooltip_screenshots = "<b>Screenshots Directory</b>"
|
||||
|
||||
tooltip_screenrecord = "<b>Screen Recorder</b>"
|
||||
tooltip_recordings = "<b>Recordings Directory</b>"
|
||||
|
||||
tooltip_ocr = "<b>OCR</b>"
|
||||
tooltip_colorpicker = """<b><u>Color Picker</u></b>
|
||||
<b>Mouse:</b>
|
||||
Left Click: HEX
|
||||
Middle Click: HSV
|
||||
Right Click: RGB
|
||||
|
||||
<b>Keyboard:</b>
|
||||
Enter: HEX
|
||||
Shift+Enter: RGB
|
||||
Ctrl+Enter: HSV"""
|
||||
|
||||
tooltip_gamemode = "<b>Game Mode</b>\nDisables effects and window animations for better performance."
|
||||
tooltip_pomodoro = "<b>Pomodoro Timer</b>"
|
||||
tooltip_emoji = "<b>Emoji Picker</b>"
|
||||
|
||||
|
||||
class Toolbox(Box):
|
||||
def __init__(self, **kwargs):
|
||||
orientation = "h"
|
||||
if data.PANEL_THEME == "Panel" and (data.BAR_POSITION in ["Left", "Right"] or data.PANEL_POSITION in ["Start", "End"]):
|
||||
orientation = "v"
|
||||
|
||||
super().__init__(
|
||||
name="toolbox",
|
||||
orientation=orientation,
|
||||
spacing=4,
|
||||
v_align="center",
|
||||
h_align="center",
|
||||
visible=True,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
self.notch = kwargs["notch"]
|
||||
|
||||
self.btn_ssregion = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_ssregion,
|
||||
child=Label(name="button-label", markup=icons.ssregion),
|
||||
on_clicked=self.ssregion,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
self.btn_ssregion.set_can_focus(True)
|
||||
self.btn_ssregion.connect("button-press-event", self.on_ssregion_click)
|
||||
self.btn_ssregion.connect("key-press-event", self.on_ssregion_key)
|
||||
|
||||
self.btn_ssfull = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_ssfull,
|
||||
child=Label(name="button-label", markup=icons.ssfull),
|
||||
on_clicked=self.ssfull,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_ssfull.set_can_focus(True)
|
||||
self.btn_ssfull.connect("button-press-event", self.on_ssfull_click)
|
||||
self.btn_ssfull.connect("key-press-event", self.on_ssfull_key)
|
||||
|
||||
self.btn_sswindow = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_sswindow,
|
||||
child=Label(name="button-label", markup=icons.sswindow),
|
||||
on_clicked=self.sswindow,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_sswindow.set_can_focus(True)
|
||||
self.btn_sswindow.connect("button-press-event", self.on_sswindow_click)
|
||||
self.btn_sswindow.connect("key-press-event", self.on_sswindow_key)
|
||||
|
||||
self.btn_screenrecord = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_screenrecord,
|
||||
child=Label(name="button-label", markup=icons.screenrecord),
|
||||
on_clicked=self.screenrecord,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_ocr = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_ocr,
|
||||
child=Label(name="button-label", markup=icons.ocr),
|
||||
on_clicked=self.ocr,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_color = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_colorpicker,
|
||||
child=Label(
|
||||
name="button-bar-label",
|
||||
markup=icons.colorpicker
|
||||
),
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_gamemode = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_gamemode,
|
||||
child=Label(name="button-label", markup=icons.gamemode),
|
||||
on_clicked=self.gamemode,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_pomodoro = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_pomodoro,
|
||||
child=Label(name="button-label", markup=icons.timer_off),
|
||||
on_clicked=self.pomodoro,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_color.set_can_focus(True)
|
||||
|
||||
self.btn_color.connect("button-press-event", self.colorpicker)
|
||||
self.btn_color.connect("key_press_event", self.colorpicker_key)
|
||||
|
||||
self.btn_emoji = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_emoji,
|
||||
child=Label(name="button-label", markup=icons.emoji),
|
||||
on_clicked=self.emoji,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_screenshots_folder = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_screenshots,
|
||||
child=Label(name="button-label", markup=icons.screenshots),
|
||||
on_clicked=self.open_screenshots_folder,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.btn_recordings_folder = Button(
|
||||
name="toolbox-button",
|
||||
tooltip_markup=tooltip_recordings,
|
||||
child=Label(name="button-label", markup=icons.recordings),
|
||||
on_clicked=self.open_recordings_folder,
|
||||
h_expand=False,
|
||||
v_expand=False,
|
||||
h_align="center",
|
||||
v_align="center",
|
||||
)
|
||||
|
||||
self.buttons = [
|
||||
self.btn_ssregion,
|
||||
self.btn_sswindow,
|
||||
self.btn_ssfull,
|
||||
self.btn_screenshots_folder,
|
||||
Box(name="tool-sep", h_expand=False, v_expand=False, h_align="center", v_align="center"),
|
||||
self.btn_screenrecord,
|
||||
self.btn_recordings_folder,
|
||||
Box(name="tool-sep", h_expand=False, v_expand=False, h_align="center", v_align="center"),
|
||||
self.btn_ocr,
|
||||
self.btn_color,
|
||||
Box(name="tool-sep", h_expand=False, v_expand=False, h_align="center", v_align="center"),
|
||||
self.btn_gamemode,
|
||||
self.btn_pomodoro,
|
||||
self.btn_emoji,
|
||||
]
|
||||
|
||||
for button in self.buttons:
|
||||
self.add(button)
|
||||
|
||||
self.show_all()
|
||||
|
||||
self.recorder_timer_id = GLib.timeout_add_seconds(2, self.update_screenrecord_state)
|
||||
self.gamemode_updater = GLib.timeout_add_seconds(2, self.gamemode_check)
|
||||
self.pomodoro_updater = GLib.timeout_add_seconds(2, self.pomodoro_check)
|
||||
|
||||
def close_menu(self):
|
||||
self.notch.close_notch()
|
||||
|
||||
def ssfull(self, *args, mockup=False):
|
||||
cmd = f"bash {SCREENSHOT_SCRIPT} p"
|
||||
if mockup:
|
||||
cmd += " mockup"
|
||||
exec_shell_command_async(cmd)
|
||||
self.close_menu()
|
||||
|
||||
def on_ssfull_click(self, button, event):
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
if event.button == 1:
|
||||
self.ssfull()
|
||||
elif event.button == 3:
|
||||
self.ssfull(mockup=True)
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_ssfull_key(self, widget, event):
|
||||
if event.keyval in {Gdk.KEY_Return, Gdk.KEY_KP_Enter}:
|
||||
modifiers = event.get_state()
|
||||
if modifiers & Gdk.ModifierType.SHIFT_MASK:
|
||||
self.ssfull(mockup=True)
|
||||
else:
|
||||
self.ssfull()
|
||||
return True
|
||||
return False
|
||||
|
||||
def ssregion(self, *args):
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} s")
|
||||
self.close_menu()
|
||||
|
||||
def on_ssregion_click(self, button, event):
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
if event.button == 1:
|
||||
self.ssregion()
|
||||
elif event.button == 3:
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} s mockup")
|
||||
self.close_menu()
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_ssregion_key(self, widget, event):
|
||||
if event.keyval in {Gdk.KEY_Return, Gdk.KEY_KP_Enter}:
|
||||
modifiers = event.get_state()
|
||||
if modifiers & Gdk.ModifierType.SHIFT_MASK:
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} s mockup")
|
||||
self.close_menu()
|
||||
else:
|
||||
self.ssregion()
|
||||
return True
|
||||
return False
|
||||
|
||||
def sswindow(self, *args):
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} w")
|
||||
self.close_menu()
|
||||
|
||||
def on_sswindow_click(self, button, event):
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
if event.button == 1:
|
||||
self.sswindow()
|
||||
elif event.button == 3:
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} w mockup")
|
||||
self.close_menu()
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_sswindow_key(self, widget, event):
|
||||
if event.keyval in {Gdk.KEY_Return, Gdk.KEY_KP_Enter}:
|
||||
modifiers = event.get_state()
|
||||
if modifiers & Gdk.ModifierType.SHIFT_MASK:
|
||||
exec_shell_command_async(f"bash {SCREENSHOT_SCRIPT} w mockup")
|
||||
self.close_menu()
|
||||
else:
|
||||
self.sswindow()
|
||||
return True
|
||||
return False
|
||||
|
||||
def screenrecord(self, *args):
|
||||
|
||||
exec_shell_command_async(f"bash -c 'nohup bash {SCREENRECORD_SCRIPT} > /dev/null 2>&1 & disown'")
|
||||
self.close_menu()
|
||||
|
||||
def pomodoro(self, *args):
|
||||
exec_shell_command_async(f"bash -c 'nohup bash {POMODORO_SCRIPT} > /dev/null 2>&1 & disown'")
|
||||
self.close_menu()
|
||||
|
||||
def pomodoro_check(self):
|
||||
"""Check pomodoro status using proper background threading"""
|
||||
GLib.Thread.new("pomodoro-check", self._pomodoro_check_thread, None)
|
||||
return True
|
||||
|
||||
def _pomodoro_check_thread(self, user_data):
|
||||
"""Background thread to check pomodoro status"""
|
||||
try:
|
||||
result = subprocess.run("pgrep -f pomodoro.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
running = result.returncode == 0
|
||||
except Exception:
|
||||
running = False
|
||||
|
||||
GLib.idle_add(self._update_pomodoro_ui, running)
|
||||
|
||||
def _update_pomodoro_ui(self, running):
|
||||
"""Update pomodoro UI from main thread"""
|
||||
if running:
|
||||
self.btn_pomodoro.get_child().set_markup(icons.timer_on)
|
||||
self.btn_pomodoro.add_style_class("pomodoro")
|
||||
else:
|
||||
self.btn_pomodoro.get_child().set_markup(icons.timer_off)
|
||||
self.btn_pomodoro.remove_style_class("pomodoro")
|
||||
return False
|
||||
|
||||
def ocr(self, *args):
|
||||
exec_shell_command_async(f"bash {OCR_SCRIPT} s")
|
||||
self.close_menu()
|
||||
|
||||
def gamemode(self, *args):
|
||||
exec_shell_command_async(f"bash {GAMEMODE_SCRIPT}")
|
||||
self.gamemode_check()
|
||||
self.close_menu()
|
||||
|
||||
def gamemode_check(self):
|
||||
"""Check gamemode status using proper background threading"""
|
||||
GLib.Thread.new("gamemode-check", self._gamemode_check_thread, None)
|
||||
return True
|
||||
|
||||
def _gamemode_check_thread(self, user_data):
|
||||
"""Background thread to check gamemode status"""
|
||||
try:
|
||||
result = subprocess.run(f"bash {GAMEMODE_SCRIPT} check", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
enabled = result.stdout == b't\n'
|
||||
except Exception:
|
||||
enabled = False
|
||||
|
||||
GLib.idle_add(self._update_gamemode_ui, enabled)
|
||||
|
||||
def _update_gamemode_ui(self, enabled):
|
||||
"""Update gamemode UI from main thread"""
|
||||
if enabled:
|
||||
self.btn_gamemode.get_child().set_markup(icons.gamemode_off)
|
||||
else:
|
||||
self.btn_gamemode.get_child().set_markup(icons.gamemode)
|
||||
return False
|
||||
|
||||
def colorpicker(self, button, event):
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
cmd = {
|
||||
1: "-hex",
|
||||
2: "-hsv",
|
||||
3: "-rgb"
|
||||
}.get(event.button)
|
||||
|
||||
if cmd:
|
||||
exec_shell_command_async(f"bash {get_relative_path('../scripts/hyprpicker.sh')} {cmd}")
|
||||
self.close_menu()
|
||||
|
||||
def colorpicker_key(self, widget, event):
|
||||
if event.keyval in {Gdk.KEY_Return, Gdk.KEY_KP_Enter}:
|
||||
modifiers = event.get_state()
|
||||
cmd = "-hex"
|
||||
|
||||
match modifiers & (Gdk.ModifierType.SHIFT_MASK | Gdk.ModifierType.CONTROL_MASK):
|
||||
case Gdk.ModifierType.SHIFT_MASK:
|
||||
cmd = "-rgb"
|
||||
case Gdk.ModifierType.CONTROL_MASK:
|
||||
cmd = "-hsv"
|
||||
|
||||
exec_shell_command_async(f"bash {get_relative_path('../scripts/hyprpicker.sh')} {cmd}")
|
||||
self.close_menu()
|
||||
return True
|
||||
return False
|
||||
|
||||
def update_screenrecord_state(self):
|
||||
"""Check screen recording status using proper background threading"""
|
||||
GLib.Thread.new("screenrecord-check", self._screenrecord_check_thread, None)
|
||||
return True
|
||||
|
||||
def _screenrecord_check_thread(self, user_data):
|
||||
"""Background thread to check screen recording status"""
|
||||
try:
|
||||
result = subprocess.run("pgrep -f gpu-screen-recorder", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
running = result.returncode == 0
|
||||
except Exception:
|
||||
running = False
|
||||
|
||||
GLib.idle_add(self._update_screenrecord_ui, running)
|
||||
|
||||
def _update_screenrecord_ui(self, running):
|
||||
"""Update screen recording UI from main thread"""
|
||||
if running:
|
||||
self.btn_screenrecord.get_child().set_markup(icons.stop)
|
||||
self.btn_screenrecord.add_style_class("recording")
|
||||
else:
|
||||
self.btn_screenrecord.get_child().set_markup(icons.screenrecord)
|
||||
self.btn_screenrecord.remove_style_class("recording")
|
||||
return False
|
||||
|
||||
def open_screenshots_folder(self, *args):
|
||||
screenshots_dir = os.path.join(os.environ.get('XDG_PICTURES_DIR',
|
||||
os.path.expanduser('~/Pictures')),
|
||||
'Screenshots')
|
||||
|
||||
os.makedirs(screenshots_dir, exist_ok=True)
|
||||
exec_shell_command_async(f"xdg-open {screenshots_dir}")
|
||||
self.close_menu()
|
||||
|
||||
def open_recordings_folder(self, *args):
|
||||
recordings_dir = os.path.join(os.environ.get('XDG_VIDEOS_DIR',
|
||||
os.path.expanduser('~/Videos')),
|
||||
'Recordings')
|
||||
|
||||
os.makedirs(recordings_dir, exist_ok=True)
|
||||
exec_shell_command_async(f"xdg-open {recordings_dir}")
|
||||
self.close_menu()
|
||||
|
||||
def emoji(self, *args):
|
||||
self.notch.open_notch("emoji")
|
||||
Reference in New Issue
Block a user