Advertisement
Guest User

Untitled

a guest
May 17th, 2025
7
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import sys
  4. import subprocess
  5. import shutil
  6. import time
  7.  
  8. # Validate required tools
  9. required_tools = ["xprop", "xdpyinfo", "xdotool", "wmctrl"]
  10. for tool in required_tools:
  11. if not shutil.which(tool):
  12. print(f"Error: {tool} is not installed.")
  13. sys.exit(1)
  14.  
  15. def validate_percentage(value, name):
  16. if value < 0 or value > 100:
  17. print(f"Error: {name} must be between 0 and 100.")
  18. sys.exit(1)
  19.  
  20. if len(sys.argv) < 5:
  21. print("Usage: tiling.py <width%> <height%> <x_offset%> <y_offset%>")
  22. sys.exit(1)
  23.  
  24. width_percent = int(sys.argv[1])
  25. height_percent = int(sys.argv[2])
  26. x_offset_percent = int(sys.argv[3])
  27. y_offset_percent = int(sys.argv[4])
  28.  
  29. # Validate percentages
  30. validate_percentage(width_percent, "Width")
  31. validate_percentage(height_percent, "Height")
  32. validate_percentage(x_offset_percent, "X Offset")
  33. validate_percentage(y_offset_percent, "Y Offset")
  34.  
  35. # Buffer for window decorations (px)
  36. BUFFER_W = 10
  37. BUFFER_H = 33 # Default buffer height for titlebars etc.
  38.  
  39. def get_workarea():
  40. try:
  41. xprop_output = subprocess.check_output(["xprop", "-root", "_NET_WORKAREA"]).decode()
  42. parts_all = xprop_output.split('=')[1].strip().split(',')
  43. workarea_values = [part.strip() for part in parts_all[:4]]
  44. if len(workarea_values) == 4:
  45. x, y, w, h = map(int, workarea_values)
  46. return x, y, w, h
  47. else:
  48. raise ValueError("Could not parse _NET_WORKAREA with 4 values.")
  49. except Exception:
  50. screen_info = subprocess.check_output(["xdpyinfo"]).decode()
  51. for line in screen_info.splitlines():
  52. if "dimensions:" in line:
  53. dims = line.strip().split()[1]
  54. w, h = map(int, dims.split("x"))
  55. return 0, 0, w, h
  56.  
  57. def get_window_class(win_id):
  58. try:
  59. output = subprocess.check_output(["xprop", "-id", win_id, "WM_CLASS"]).decode().strip()
  60. if "WM_CLASS(STRING) = " in output:
  61. class_str = output.split("= ")[1].strip().replace('"', '')
  62. return class_str.split(', ')[1] # Usually app name is in second part
  63. return None
  64. except subprocess.CalledProcessError:
  65. return None
  66.  
  67. def is_maximized(win_id):
  68. try:
  69. xprop_output = subprocess.check_output(["xprop", "-id", win_id, "_NET_WM_STATE"]).decode()
  70. return ("_NET_WM_STATE_MAXIMIZED_VERT" in xprop_output or
  71. "_NET_WM_STATE_MAXIMIZED_HORZ" in xprop_output)
  72. except subprocess.CalledProcessError:
  73. return False
  74.  
  75. def unmaximize_window(win_id):
  76. print("Attempting to unmaximize window.")
  77. # Method 1: Try unmaximize using keyboard shortcut (works in XFCE, etc)
  78. subprocess.call(["xdotool", "key", "alt+F10"])
  79. time.sleep(0.2)
  80. # Method 2: Use wmctrl to remove maximized state
  81. subprocess.call(["wmctrl", "-ir", win_id, "-b", "remove,maximized_vert,maximized_horz"])
  82. time.sleep(0.2)
  83.  
  84. # Get active window ID
  85. try:
  86. win_id = subprocess.check_output(["xdotool", "getactivewindow"]).decode().strip()
  87. except subprocess.CalledProcessError:
  88. print("Error: Could not retrieve active window ID.")
  89. sys.exit(1)
  90.  
  91. app_class = get_window_class(win_id)
  92. print(f"Window class: {app_class}")
  93.  
  94. # Check if the window is maximized and unmaximize if it is
  95. if is_maximized(win_id):
  96. unmaximize_window(win_id)
  97.  
  98. # Get workarea dimensions
  99. work_x, work_y, work_w, work_h = get_workarea()
  100.  
  101. # Calculate target size and position
  102. width = max(1, work_w * width_percent // 100 - BUFFER_W)
  103. if x_offset_percent == 0 and app_class in ["Brave-browser", "Google-chrome"]:
  104. width = max(1, int(work_w * (width_percent + 0.5) // 100) - BUFFER_W)
  105.  
  106. height = work_h * height_percent // 100
  107. if app_class not in ["Brave-browser", "Google-chrome"]:
  108. height -= BUFFER_H
  109. height = max(1, height)
  110.  
  111. x = work_x + (work_w * x_offset_percent // 100)
  112. y = work_y + (work_h * y_offset_percent // 100)
  113.  
  114. print(f"Target width: {width}, height: {height}, x: {x}, y: {y}")
  115.  
  116. # Move and resize the window
  117. subprocess.call(["xdotool", "windowmove", win_id, str(x), str(y)])
  118. subprocess.call(["xdotool", "windowsize", win_id, str(width), str(height)])
  119.  
  120. print("Window moved and resized.")
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement