-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlaunchUniWS.sh
More file actions
executable file
·175 lines (147 loc) · 5.76 KB
/
Copy pathlaunchUniWS.sh
File metadata and controls
executable file
·175 lines (147 loc) · 5.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash
# ==============================================================================
# Study Workspace Orchestrator (RStudio + Moodle + Gemini)
# ==============================================================================
# 0. CONFIG
TOP_BAR=32 # Hardcoded GNOME Panel Height
MOODLE_URL="https://moodle.lmu.de/"
GEMINI_URL="https://gemini.google.com/"
# 1. SETUP
# Create a separate "StudyWS" profile to keep school logins separate
if ! grep -q "Name=StudyWS" ~/.mozilla/firefox/profiles.ini; then
firefox -CreateProfile "StudyWS" >/dev/null 2>&1
fi
get_windows_json() {
python3 -c "
import gi
gi.require_version('Gio', '2.0')
from gi.repository import Gio
try:
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None, 'org.gnome.Shell', '/org/gnome/Shell/Extensions/Windows', 'org.gnome.Shell.Extensions.Windows', None)
print(proxy.call_sync('List', None, Gio.DBusCallFlags.NONE, -1, None).unpack()[0])
except:
print('[]')
" 2>/dev/null
}
# 2. HARDWARE DETECTION
read -r P_X P_Y P_W P_H S_X S_Y S_W S_H <<< $(python3 -c "
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk
display = Gdk.Display.get_default()
monitors = []
for i in range(display.get_n_monitors()):
g = display.get_monitor(i).get_geometry()
monitors.append({'x': g.x, 'y': g.y, 'w': g.width, 'h': g.height})
monitors.sort(key=lambda m: m['w'], reverse=True)
p = monitors[0]
s = monitors[1] if len(monitors) > 1 else {'x':0,'y':0,'w':0,'h':0}
print(f'{p[\"x\"]} {p[\"y\"]} {p[\"w\"]} {p[\"h\"]} {s[\"x\"]} {s[\"y\"]} {s[\"w\"]} {s[\"h\"]}')
")
if [ "$S_W" -gt 0 ]; then MODE="DUAL"; else MODE="SINGLE"; fi
echo "Detected Mode: $MODE"
# 3. SNAPSHOT & LAUNCH
echo "Snapshotting existing windows..."
EXISTING_IDS=$(get_windows_json | jq -r '.[] | select(.wm_class != null and (.wm_class | test("firefox"; "i"))) | .id')
is_old_id() {
local check_id=$1
if echo "$EXISTING_IDS" | grep -q "^$check_id$"; then return 0; else return 1; fi
}
echo "Launching Apps..."
# --- RSTUDIO LAUNCHER ---
# Checks for Flatpak first, falls back to native command
if flatpak list | grep -q org.rstudio.RStudio; then
echo " > Starting RStudio (Flatpak)..."
flatpak run org.rstudio.RStudio >/dev/null 2>&1 &
elif command -v rstudio >/dev/null 2>&1; then
echo " > Starting RStudio (Native)..."
rstudio >/dev/null 2>&1 &
else
echo " > Error: RStudio not found! (Check if installed)"
fi
# --- FIREFOX LAUNCHER ---
FF_CMD="firefox -P StudyWS"
# 1. Moodle (Research Window)
$FF_CMD --no-remote --new-window "$MOODLE_URL" &
sleep 2
# 2. Gemini (Helper Window)
$FF_CMD --new-window "$GEMINI_URL" &
# 4. SMART WAIT LOOP
echo "Scanning for NEW windows..."
MAX_RETRIES=60
count=0
while [ $count -lt $MAX_RETRIES ]; do
WINDOWS=$(get_windows_json)
# Detect RStudio (Matches 'rstudio' or 'org.rstudio...')
ID_RSTUDIO=$(echo "$WINDOWS" | jq -r '.[] | select(.wm_class != null and (.wm_class | test("rstudio"; "i"))) | .id' | head -n 1)
# Detect Firefox
ALL_FF_IDS=$(echo "$WINDOWS" | jq -r '.[] | select(.wm_class != null and (.wm_class | test("firefox"; "i"))) | .id' | sort -rn)
NEW_FF_IDS=()
for id in $ALL_FF_IDS; do
if ! is_old_id "$id"; then NEW_FF_IDS+=("$id"); fi
done
if [ -n "$ID_RSTUDIO" ] && [ "${#NEW_FF_IDS[@]}" -ge 2 ]; then
# Newest = Gemini (Launched Last)
# 2nd Newest = Moodle (Launched First)
ID_GEMINI=${NEW_FF_IDS[0]}
ID_MOODLE=${NEW_FF_IDS[1]}
# Heuristic Swap based on Title
TITLE_GEM=$(echo "$WINDOWS" | jq -r --arg id "$ID_GEMINI" '.[] | select(.id == ($id|tonumber)) | .title')
# If the "Gemini" window actually says "Moodle" or "Login", swap them
if [[ "$TITLE_GEM" =~ "Moodle" ]] || [[ "$TITLE_GEM" =~ "Login" ]]; then
TEMP=$ID_GEMINI; ID_GEMINI=$ID_MOODLE; ID_MOODLE=$TEMP
fi
echo "Targets Locked: RStudio($ID_RSTUDIO), Gemini($ID_GEMINI), Moodle($ID_MOODLE)"
break
fi
sleep 0.5
((count++))
done
# 5. MOVE AND ARRANGE
win_call() {
METHOD=$1; shift; ID=$1; shift;
if [[ "$ID" =~ ^[0-9]+$ ]]; then
gdbus call --session --dest org.gnome.Shell \
--object-path /org/gnome/Shell/Extensions/Windows \
--method org.gnome.Shell.Extensions.Windows."$METHOD" \
"$ID" "$@" >/dev/null 2>&1
fi
}
place_window() {
local WIN_ID=$1; local X=$2; local Y=$3; local W=$4; local H=$5
win_call "Unmaximize" "$WIN_ID"
win_call "MoveResize" "$WIN_ID" "$X" "$Y" "$W" "$H"
}
if [ "$MODE" == "DUAL" ]; then
echo "Applying Dual Monitor Layout..."
# RStudio -> Primary (External)
win_call "Unmaximize" "$ID_RSTUDIO"
SAFE_X=$((P_X + 100))
win_call "Move" "$ID_RSTUDIO" "$SAFE_X" "$P_Y"
win_call "Maximize" "$ID_RSTUDIO"
win_call "Activate" "$ID_RSTUDIO"
# Firefox -> Laptop (Split)
SPLIT_W=$((S_W / 2))
RIGHT_POS=$((S_X + SPLIT_W))
# Moodle Left / Gemini Right
place_window "$ID_MOODLE" "$S_X" "$S_Y" "$SPLIT_W" "$S_H"
place_window "$ID_GEMINI" "$RIGHT_POS" "$S_Y" "$SPLIT_W" "$S_H"
else
echo "Applying Single Monitor Layout (Dashboard Style)..."
# Calculate Safe Geometry
WORK_H=$((P_H - TOP_BAR))
HALF_W=$((P_W / 2))
# 1. Place Browsers (Background)
echo " > Arranging Dashboard (Y=$TOP_BAR)..."
# Moodle Left / Gemini Right
place_window "$ID_MOODLE" 0 "$TOP_BAR" "$HALF_W" "$WORK_H"
place_window "$ID_GEMINI" "$HALF_W" "$TOP_BAR" "$HALF_W" "$WORK_H"
# 2. Place RStudio (Foreground)
echo " > Maximizing RStudio..."
win_call "Unmaximize" "$ID_RSTUDIO"
win_call "Move" "$ID_RSTUDIO" 100 100
win_call "Maximize" "$ID_RSTUDIO"
win_call "Activate" "$ID_RSTUDIO"
fi
echo "Layout Complete."