Fix GUI focus: Remove makeAccessoryProcess entirely, use NSWindow level trick to float without activation
Browse files
Source/Helper/HelperPluginHost.cpp
CHANGED
|
@@ -9,25 +9,22 @@
|
|
| 9 |
#include <objc/message.h>
|
| 10 |
#endif
|
| 11 |
|
| 12 |
-
//
|
| 13 |
-
static void
|
| 14 |
-
{
|
| 15 |
-
#if JUCE_MAC
|
| 16 |
-
id nsApp = ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSApplication"),
|
| 17 |
-
sel_registerName("sharedApplication"));
|
| 18 |
-
// NSApplicationActivationPolicyAccessory = 1 (windows allowed, no Dock icon, no focus steal)
|
| 19 |
-
((void(*)(id, SEL, long))objc_msgSend)(nsApp, sel_registerName("setActivationPolicy:"), 1);
|
| 20 |
-
#endif
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
// Show window without stealing focus from Ableton
|
| 24 |
-
static void showWindowWithoutFocus(juce::Component* window)
|
| 25 |
{
|
| 26 |
#if JUCE_MAC
|
| 27 |
if (auto* peer = window->getPeer())
|
| 28 |
{
|
| 29 |
auto* nsWindow = (id)peer->getNativeHandle();
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
((void(*)(id, SEL))objc_msgSend)(nsWindow, sel_registerName("orderFrontRegardless"));
|
| 32 |
}
|
| 33 |
#endif
|
|
@@ -41,7 +38,6 @@ public:
|
|
| 41 |
: DocumentWindow(name, juce::Colour(0xff1a1a2e), DocumentWindow::allButtons, true)
|
| 42 |
{
|
| 43 |
setUsingNativeTitleBar(true);
|
| 44 |
-
setAlwaysOnTop(true);
|
| 45 |
}
|
| 46 |
|
| 47 |
void closeButtonPressed() override
|
|
@@ -277,14 +273,11 @@ void HelperPluginHost::showGui()
|
|
| 277 |
{
|
| 278 |
if (!plugin) return;
|
| 279 |
|
| 280 |
-
// Set as accessory app — allows windows without stealing focus
|
| 281 |
-
makeAccessoryProcess();
|
| 282 |
-
|
| 283 |
// If window exists but hidden, just show it
|
| 284 |
if (guiWindow)
|
| 285 |
{
|
| 286 |
guiWindow->setVisible(true);
|
| 287 |
-
|
| 288 |
return;
|
| 289 |
}
|
| 290 |
|
|
@@ -297,8 +290,8 @@ void HelperPluginHost::showGui()
|
|
| 297 |
guiWindow->centreWithSize(editor->getWidth(), editor->getHeight());
|
| 298 |
guiWindow->setVisible(true);
|
| 299 |
|
| 300 |
-
//
|
| 301 |
-
|
| 302 |
});
|
| 303 |
}
|
| 304 |
|
|
|
|
| 9 |
#include <objc/message.h>
|
| 10 |
#endif
|
| 11 |
|
| 12 |
+
// Show window as floating panel without activating this app or stealing focus
|
| 13 |
+
static void showAsFloatingPanel(juce::Component* window)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
{
|
| 15 |
#if JUCE_MAC
|
| 16 |
if (auto* peer = window->getPeer())
|
| 17 |
{
|
| 18 |
auto* nsWindow = (id)peer->getNativeHandle();
|
| 19 |
+
|
| 20 |
+
// Set window level to floating (above normal windows)
|
| 21 |
+
// NSFloatingWindowLevel = 3
|
| 22 |
+
((void(*)(id, SEL, long))objc_msgSend)(nsWindow, sel_registerName("setLevel:"), 3);
|
| 23 |
+
|
| 24 |
+
// Don't hide on deactivate (stay visible when helper loses focus)
|
| 25 |
+
((void(*)(id, SEL, int))objc_msgSend)(nsWindow, sel_registerName("setHidesOnDeactivate:"), 0);
|
| 26 |
+
|
| 27 |
+
// Show without activating this app
|
| 28 |
((void(*)(id, SEL))objc_msgSend)(nsWindow, sel_registerName("orderFrontRegardless"));
|
| 29 |
}
|
| 30 |
#endif
|
|
|
|
| 38 |
: DocumentWindow(name, juce::Colour(0xff1a1a2e), DocumentWindow::allButtons, true)
|
| 39 |
{
|
| 40 |
setUsingNativeTitleBar(true);
|
|
|
|
| 41 |
}
|
| 42 |
|
| 43 |
void closeButtonPressed() override
|
|
|
|
| 273 |
{
|
| 274 |
if (!plugin) return;
|
| 275 |
|
|
|
|
|
|
|
|
|
|
| 276 |
// If window exists but hidden, just show it
|
| 277 |
if (guiWindow)
|
| 278 |
{
|
| 279 |
guiWindow->setVisible(true);
|
| 280 |
+
showAsFloatingPanel(guiWindow.get());
|
| 281 |
return;
|
| 282 |
}
|
| 283 |
|
|
|
|
| 290 |
guiWindow->centreWithSize(editor->getWidth(), editor->getHeight());
|
| 291 |
guiWindow->setVisible(true);
|
| 292 |
|
| 293 |
+
// Make it float without stealing focus
|
| 294 |
+
showAsFloatingPanel(guiWindow.get());
|
| 295 |
});
|
| 296 |
}
|
| 297 |
|