Skip to content

Commit 039bbd8

Browse files
committed
fix: keep the attached panel on its display when working on another one
1 parent cb22c67 commit 039bbd8

2 files changed

Lines changed: 19 additions & 5 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Your PR sits in **In Review** for two days because nobody noticed it. A teammate
3232
## ✨ Features
3333

3434
- 🪟 **Always on top**: a non-activating floating panel that never steals focus, visible on all Spaces and over full-screen apps. Drag it anywhere; near a screen edge or corner it snaps into place like a magnet. Docked at the bottom, the header moves to the bottom row and the tasks open upwards, so the bar never jumps. The panel shrinks to fit short lists (folded sections leave no empty space) and grows back up to the size you dragged it to.
35-
- 📌 **Attach to Menu Bar**: turn it on in the menu, or just drag the panel up onto the menu bar icon (the icon lights up; let go to attach), and the panel hangs right under the menu bar icon, with a popover arrow pointing at it; click the icon to show or hide it, and a click anywhere outside hides it again, like a menu bar popover. Right-click the icon for the options. Drag the panel away (or untick the option) to detach it and float it anywhere again.
35+
- 📌 **Attach to Menu Bar**: turn it on in the menu, or just drag the panel up onto the menu bar icon (the icon lights up; let go to attach), and the panel hangs right under the menu bar icon, with a popover arrow pointing at it; click the icon to show or hide it, and a click anywhere outside hides it again, like a menu bar popover. Right-click the icon for the options. Drag the panel away (or untick the option) to detach it and float it anywhere again. With two displays, the panel stays on its display while you work on the other one; click the menu bar icon there to bring it over.
3636
- 👤 **Mine**: your tasks grouped by status (In Progress, In Review, Reviewed), each with its linked PRs. *User Stories* that have sub-issues are hidden: you follow them through their sub-issues.
3737
- 🗂️ **Your layout**: click a section header to fold it, and drag headers to put the status you care about first (or right-click → *Move Up* / *Move Down*).
3838
- 👀 **Reviewing**: the tasks you are reviewing for teammates, split into *Your turn* and *Waiting on the author*, with a notification when a re-review is requested.

‎Sources/GitHubFloat/main.swift‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSWind
487487
updateOutsideClickMonitor()
488488
return
489489
}
490-
pinToStatusItem()
490+
pinToStatusItem(follow: true)
491491
if !panel.isVisible || popoverAnimating {
492492
// Popover-style entrance: grows out of the menu bar icon.
493493
let wasHidden = !panel.isVisible
@@ -547,7 +547,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSWind
547547
if wanted, outsideClickMonitor == nil {
548548
outsideClickMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown, .rightMouseDown, .otherMouseDown]) { [weak self] _ in
549549
MainActor.assumeIsolated {
550-
guard let self, !self.isOwnClick(at: NSEvent.mouseLocation) else { return }
550+
let point = NSEvent.mouseLocation
551+
// Working on another display leaves the panel where it is.
552+
guard let self, !self.isOwnClick(at: point), self.screenOfPanel?.frame.contains(point) ?? true else { return }
551553
self.hidePanel()
552554
}
553555
}
@@ -638,7 +640,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSWind
638640
}
639641
}
640642

641-
private func pinToStatusItem(expand: Bool = true) {
643+
private var iconScreen: NSScreen? {
644+
guard let window = statusItem?.button?.window else { return nil }
645+
return window.screen ?? NSScreen.screens.first { $0.frame.intersects(window.frame) }
646+
}
647+
648+
/// With several displays the menu bar icon jumps to the display you're using; the panel only follows it when you click the icon.
649+
private var panelOnIconScreen: Bool {
650+
guard NSScreen.screens.count > 1, panel.isVisible, let icon = iconScreen, let mine = screenOfPanel else { return true }
651+
return icon == mine
652+
}
653+
654+
private func pinToStatusItem(expand: Bool = true, follow: Bool = false) {
655+
guard follow || panelOnIconScreen else { return }
642656
if expand, settings.collapsed { settings.collapsed = false }
643657
defer { arrowX = iconMidX().map { $0 - panel.frame.minX }; updateShape() }
644658
guard let f = pinnedFrame(), f != panel.frame else { return }
@@ -721,7 +735,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, NSWind
721735
}
722736

723737
@objc private func togglePanel() {
724-
if panel.isVisible { hidePanel() } else { showPanel() }
738+
if panel.isVisible, panelOnIconScreen { hidePanel() } else { showPanel() }
725739
}
726740

727741
// MARK: Status item

0 commit comments

Comments
 (0)