107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
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 |