diff --git a/.gitignore b/.gitignore index 164318a..589a417 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,6 @@ __pycache__/ *.pyc.* *.pyo.* -# SUPERCOPY +SUPERCOPY.py copy.md .vscode \ No newline at end of file diff --git a/core/wayland_utils.py b/core/wayland_utils.py deleted file mode 100644 index 54921a8..0000000 --- a/core/wayland_utils.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -import subprocess -from typing import Tuple, Optional - -def is_wayland() -> bool: - session_type = os.environ.get('XDG_SESSION_TYPE', '').lower() - wayland_display = os.environ.get('WAYLAND_DISPLAY', '') - - return session_type == 'wayland' or bool(wayland_display) - -def get_screen_info() -> Tuple[int, int]: - if is_wayland(): - try: - output = subprocess.check_output(['wlr-randr'], text=True, stderr=subprocess.DEVNULL) - for line in output.splitlines(): - if 'current' in line.lower(): - parts = line.split() - for part in parts: - if 'x' in part and part.replace('x', '').replace('px', '').isdigit(): - dims = part.replace('px', '').split('x') - return int(dims[0]), int(dims[1]) - except (subprocess.CalledProcessError, FileNotFoundError, PermissionError): - pass - - import json - - try: - output = subprocess.check_output(['swaymsg', '-t', 'get_outputs'], text=True) - outputs = json.loads(output) - if outputs and outputs[0].get('current_mode'): - mode = outputs[0]['current_mode'] - return mode['width'], mode['height'] - except (subprocess.CalledProcessError, FileNotFoundError, json.JSONDecodeError, KeyError, PermissionError): - pass - - try: - output = subprocess.check_output(['kscreen-doctor', '-o'], text=True) - for line in output.splitlines(): - if 'Output:' in line: - continue - if 'x' in line and '@' in line: - resolution = line.split('@')[0].strip().split()[-1] - if 'x' in resolution: - dims = resolution.split('x') - return int(dims[0]), int(dims[1]) - except (subprocess.CalledProcessError, FileNotFoundError, PermissionError): - pass - - try: - output = subprocess.check_output(['xrandr'], text=True, stderr=subprocess.DEVNULL) - for line in output.splitlines(): - if ' connected' in line and 'primary' in line: - parts = line.split() - for part in parts: - if 'x' in part and '+' in part: - dims = part.split('+')[0].split('x') - return int(dims[0]), int(dims[1]) - elif ' connected' in line and '*' in line: - parts = line.split() - for i, part in enumerate(parts): - if 'x' in part and i > 0: - dims = part.split('x') - if dims[0].isdigit(): - return int(dims[0]), int(dims[1].split('+')[0] if '+' in dims[1] else dims[1]) - except (subprocess.CalledProcessError, FileNotFoundError, PermissionError): - pass - - # maybe somehow right sometimes - return 1920, 1080 - -def set_window_bottom_right_wayland(window, width: int, height: int): - screen_w, screen_h = get_screen_info() - x = screen_w - width - y = screen_h - height - - try: - window.move(x, y) - except: - pass - -def get_wayland_compositor() -> Optional[str]: - desktop = os.environ.get('XDG_CURRENT_DESKTOP', '').lower() - - if 'sway' in desktop: - return 'sway' - elif 'kde' in desktop or 'plasma' in desktop: - return 'kwin' - elif 'gnome' in desktop: - return 'mutter' - elif 'hypr' in desktop: - return 'hyprland' - - # detect from process list - try: - output = subprocess.check_output(['ps', 'aux'], text=True) - if 'sway' in output: - return 'sway' - elif 'kwin_wayland' in output: - return 'kwin' - elif 'gnome-shell' in output: - return 'mutter' - elif 'Hyprland' in output: - return 'hyprland' - except: - pass - - return None \ No newline at end of file diff --git a/main.py b/main.py index 47a9718..4464762 100644 --- a/main.py +++ b/main.py @@ -69,7 +69,12 @@ def main(): dukto_handler.initialize() dukto_handler.say_hello() - pet.position_bottom_right() + # bottom right corner + screen_geometry = app.primaryScreen().availableGeometry() + pet_geometry = pet.frameGeometry() + x = screen_geometry.width() - pet_geometry.width() + y = screen_geometry.height() - pet_geometry.height() + pet.move(x, y) pet.show() diff --git a/windows/main_window.py b/windows/main_window.py index 1d1bc9d..1563711 100644 --- a/windows/main_window.py +++ b/windows/main_window.py @@ -11,7 +11,6 @@ from core.file_search import find from core.web_search import MullvadLetaWrapper from core.http_share import FileShareServer from core.config import Config -from core.wayland_utils import is_wayland, get_screen_info from windows.app_launcher import AppLauncherDialog from windows.file_search import FileSearchResults @@ -47,35 +46,19 @@ class MainWindow(QtWidgets.QMainWindow): self.strings = strings self.config = config self.listener = None - self.is_wayland = is_wayland() self.restart = restart self.no_quit = no_quit - # Configure window flags based on display server - if self.is_wayland: - # Wayland-compatible flags - flags = ( - QtCore.Qt.FramelessWindowHint #type: ignore - | QtCore.Qt.WindowStaysOnTopHint #type: ignore - | QtCore.Qt.Tool #type: ignore - ) - else: - # X11 flags - flags = ( - QtCore.Qt.FramelessWindowHint #type: ignore - | QtCore.Qt.WindowStaysOnTopHint #type: ignore - | QtCore.Qt.Tool #type: ignore - | QtCore.Qt.WindowDoesNotAcceptFocus #type: ignore - ) + flags = ( + QtCore.Qt.FramelessWindowHint #type: ignore + | QtCore.Qt.WindowStaysOnTopHint #type: ignore + | QtCore.Qt.Tool #type: ignore + | QtCore.Qt.WindowDoesNotAcceptFocus #type: ignore + ) self.setWindowFlags(flags) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) #type: ignore - - # On Wayland, set additional window properties to prevent Alt+Tab - if self.is_wayland: - self.setAttribute(QtCore.Qt.WA_X11NetWmWindowTypeUtility) #type: ignore - pix = QtGui.QPixmap(str(ASSET)) self.label = QtWidgets.QLabel(self) @@ -136,22 +119,6 @@ class MainWindow(QtWidgets.QMainWindow): if config.get("hotkey") != None and config.get("hotkey") != "none" and config.get("hotkey") != "": self.start_hotkey_listener() - def position_bottom_right(self): - """Position window at bottom right corner.""" - if self.is_wayland: - # On Wayland, get screen info and position window - screen_w, screen_h = get_screen_info() - x = screen_w - self.width() - y = screen_h - self.height() - self.move(x, y) - else: - # On X11, use Qt's screen geometry - screen_geometry = QtWidgets.QApplication.primaryScreen().availableGeometry() - pet_geometry = self.frameGeometry() - x = screen_geometry.width() - pet_geometry.width() - y = screen_geometry.height() - pet_geometry.height() - self.move(x, y) - def build_menus(self): s = self.strings["main_window"]["right_menu"] @@ -284,15 +251,10 @@ class MainWindow(QtWidgets.QMainWindow): def ensure_on_top(self): if self.isVisible() and not self.left_menu.isVisible() and not self.tray.contextMenu().isVisible(): self.raise_() - # Re-apply window flags to ensure staying on top on Wayland - if self.is_wayland: - self.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) #type: ignore def showEvent(self, event): super().showEvent(event) self.raise_() - # Ensure bottom right positioning - QtCore.QTimer.singleShot(100, self.position_bottom_right) def mousePressEvent(self, event: QtGui.QMouseEvent): if event.button() == QtCore.Qt.LeftButton: #type: ignore