diff --git a/bin/phonescreenctl b/bin/phonescreenctl index 6a1e358..cde2af7 100755 --- a/bin/phonescreenctl +++ b/bin/phonescreenctl @@ -13,6 +13,7 @@ Usage: phonescreenctl state phonescreenctl claim [serial] [--above 0|1] [--borderless 0|1] [--extra "args"] phonescreenctl release + phonescreenctl raise # bring the mirror to the front and keep it there phonescreenctl window [serial] # pop out: movable window (pauses pinned) phonescreenctl lock [serial] # lock the phone (instant hide) phonescreenctl unlock [serial] # wake + PIN-unlock (instant show) @@ -91,13 +92,11 @@ def cmd_release(args): def cmd_raise(): - """Raise the pinned mirror to the top of the stack — used by the tray popup so - its embedded mirror sits above the popup window. No-op if kdotool isn't set up.""" - try: - subprocess.run(["kdotool", "search", "--name", ps.TITLE_TOKEN, "windowraise"], - capture_output=True, timeout=5) - except (OSError, subprocess.TimeoutExpired): - pass + """Bring the pinned mirror to the front and keep it there while a widget claims + it, even if it was pinned below normal windows. No-op if kdotool isn't set up.""" + ps.request_front() + time.sleep(0.4) + ps.raise_window() return 0 diff --git a/plasmoids/org.devl0rd.phonescreen/contents/ui/main.qml b/plasmoids/org.devl0rd.phonescreen/contents/ui/main.qml index 1a73473..6159a59 100644 --- a/plasmoids/org.devl0rd.phonescreen/contents/ui/main.qml +++ b/plasmoids/org.devl0rd.phonescreen/contents/ui/main.qml @@ -73,7 +73,7 @@ PlasmoidItem { if (!_pinTarget || !root.dataWanted) return var r = screenRect() var a = "claim desktop 1 " + r.x + " " + r.y + " " + r.w + " " + r.h + root.serialArg - a += " --above " + (Plasmoid.configuration.keepBelow ? 0 : 1) + a += " --above " + (root.inPanel || !Plasmoid.configuration.keepBelow ? 1 : 0) a += " --borderless " + (Plasmoid.configuration.borderless ? 1 : 0) var extra = (Plasmoid.configuration.extraArgs || "").replace(/'/g, "").trim() if (extra !== "") a += " --extra '" + extra + "'" @@ -83,6 +83,8 @@ PlasmoidItem { if (root.dataWanted) claimMirror() else ctl("release desktop") } + onExpandedChanged: if (root.inPanel && root.expanded) ctl("raise") + function bringToFront() { ctl("raise") } function popOut() { ctl("window" + root.serialArg) } function toggleLock() { root.pendingLock = !root.displayLocked @@ -122,6 +124,16 @@ PlasmoidItem { statusColor: root.statusColor statusText: root.mirrorView.text + PlasmaComponents.ToolButton { + icon.name: "go-top" + display: QQC2.AbstractButton.IconOnly + enabled: feed.ready && feed.reachable && feed.status !== "external" + onClicked: root.bringToFront() + text: i18n("Bring to front") + QQC2.ToolTip.text: text + QQC2.ToolTip.visible: hovered + QQC2.ToolTip.delay: 600 + } PlasmaComponents.ToolButton { icon.name: "window-new" display: QQC2.AbstractButton.IconOnly diff --git a/src/core/phonescreen.py b/src/core/phonescreen.py index b6d1413..cf182b4 100644 --- a/src/core/phonescreen.py +++ b/src/core/phonescreen.py @@ -19,6 +19,7 @@ STATUS_PATH = os.path.join(RUNTIME_DIR, "phonescreen.json") CLAIM_GLOB = os.path.join(RUNTIME_DIR, "phonescreen_claim_*.json") WINDOW_PATH = os.path.join(RUNTIME_DIR, "phonescreen_window") +FRONT_PATH = os.path.join(RUNTIME_DIR, "phonescreen_front") LOG_PATH = os.path.join(RUNTIME_DIR, "phonescreen.log") LAUNCHER = cam.LAUNCHER @@ -70,6 +71,29 @@ def read_claims(): return out +def request_front(): + touch(FRONT_PATH) + + +def clear_front(): + try: + os.remove(FRONT_PATH) + except OSError: + pass + + +def front_requested(): + return os.path.exists(FRONT_PATH) + + +def raise_window(): + try: + subprocess.run(["kdotool", "search", "--name", TITLE_TOKEN, "windowraise"], + capture_output=True, timeout=5) + except (OSError, subprocess.TimeoutExpired): + pass + + def pick_winner(claims): live = [c for c in claims if c.get("visible")] if not live: @@ -581,6 +605,7 @@ def wants(self, serial): def reconcile(self): win = pick_winner(read_claims()) if win is None: + clear_front() if not self.persist or self.last_geom is None: return x, y, w, h, above, borderless = self.last_geom @@ -588,7 +613,7 @@ def reconcile(self): else: x, y = int(win.get("x", 0)), int(win.get("y", 0)) w, h = int(win.get("w", 400)), int(win.get("h", 800)) - above = bool(win.get("above", False)) + above = bool(win.get("above", False)) or front_requested() borderless = bool(win.get("borderless", True)) self.last_geom = (x, y, w, h, above, borderless) serial = win.get("serial") or resolve_serial()