Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions maclib/tray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,16 @@ public func tray_get_status_item_region_for(
let midX = screen.frame.midX
let region = rect.minX < midX ? "top-left" : "top-right"
return strdup(region)
}

// MARK: - Spaces / Virtual Desktop support

/// Sets NSWindowCollectionBehavior.moveToActiveSpace on all app windows
/// so that showing a window moves it to the current Space instead of
/// switching back to the Space where it was originally created.
@_cdecl("tray_set_windows_move_to_active_space")
public func tray_set_windows_move_to_active_space() {
for window in NSApp.windows {
window.collectionBehavior.insert(.moveToActiveSpace)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,6 @@ interface Foundation : Library {

class MacOSWindowManager {

companion object {
// Constants for NSApplication activation policies
const val NSApplicationActivationPolicyRegular = 0L
const val NSApplicationActivationPolicyAccessory = 1L
const val NSApplicationActivationPolicyProhibited = 2L

// Constants for window levels
const val NSNormalWindowLevel = 0L
const val NSFloatingWindowLevel = 3L
const val NSModalPanelWindowLevel = 8L
}

// Detect platform once
private val isMacOs: Boolean = getOperatingSystem() == OperatingSystem.MACOS

Expand Down Expand Up @@ -206,5 +194,51 @@ class MacOSWindowManager {
return getNSApplication() != null
}

/**
* Configure an AWT window so that macOS moves it to the active Space
* when it is ordered front, instead of switching back to the Space
* where the window was originally created.
*/
fun setMoveToActiveSpace(awtWindow: java.awt.Window): Boolean {
if (!isMacOs) return false
val localObjc = objc ?: return false
return try {
val viewPtr = Native.getComponentID(awtWindow)
if (viewPtr == 0L) return false

val nsView = Pointer(viewPtr)
val windowSel = localObjc.sel_registerName("window")
val nsWindow = localObjc.objc_msgSend(nsView, windowSel)
if (nsWindow == Pointer.NULL) return false

// Read current collectionBehavior and add moveToActiveSpace (1 << 1)
val getCollSel = localObjc.sel_registerName("collectionBehavior")
val current = Pointer.nativeValue(localObjc.objc_msgSend(nsWindow, getCollSel))
val setCollSel = localObjc.sel_registerName("setCollectionBehavior:")
localObjc.objc_msgSend(nsWindow, setCollSel, current or NSWindowCollectionBehaviorMoveToActiveSpace)

debugln { "Window configured to move to active Space" }
true
} catch (e: Throwable) {
debugln { "Failed to set moveToActiveSpace: ${e.message}" }
false
}
}

companion object {
// Constants for NSApplication activation policies
const val NSApplicationActivationPolicyRegular = 0L
const val NSApplicationActivationPolicyAccessory = 1L
const val NSApplicationActivationPolicyProhibited = 2L

// Constants for window levels
const val NSNormalWindowLevel = 0L
const val NSFloatingWindowLevel = 3L
const val NSModalPanelWindowLevel = 8L

// NSWindowCollectionBehavior
const val NSWindowCollectionBehaviorMoveToActiveSpace = 2L // 1 << 1
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ internal class MacTrayManager(

@JvmStatic external fun tray_get_status_item_region(): String?
@JvmStatic external fun tray_get_status_item_region_for(tray: MacTray): String?

@JvmStatic external fun tray_set_windows_move_to_active_space()
}

// Structure for a menu item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.ui.window.*
import com.kdroid.composetray.lib.linux.LinuxOutsideClickWatcher
import com.kdroid.composetray.lib.mac.MacOSWindowManager
import com.kdroid.composetray.lib.mac.MacOutsideClickWatcher
import com.kdroid.composetray.lib.mac.MacTrayLoader
import com.kdroid.composetray.lib.windows.WindowsOutsideClickWatcher
import com.kdroid.composetray.menu.api.TrayMenuBuilder
import com.kdroid.composetray.utils.*
Expand Down Expand Up @@ -620,6 +621,11 @@ private fun ApplicationScope.TrayAppImplOriginal(
runCatching { WindowVisibilityMonitor.recompute() }

invokeLater {
// Move the popup to the current Space before bringing it to front (macOS)
if (getOperatingSystem() == MACOS) {
runCatching { MacTrayLoader.lib.tray_set_windows_move_to_active_space() }
runCatching { MacOSWindowManager().setMoveToActiveSpace(window) }
}
runCatching {
window.toFront()
window.requestFocus()
Expand Down
Loading