summaryrefslogtreecommitdiff
path: root/indra/llplugin
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin')
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt20
-rw-r--r--indra/llplugin/slplugin/slplugin.cpp105
-rw-r--r--indra/llplugin/slplugin/slplugin_info.plist4
3 files changed, 118 insertions, 11 deletions
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 4a7d670c23..c1536e85de 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -27,9 +27,15 @@ set(SLPlugin_SOURCE_FILES
add_executable(SLPlugin
WIN32
+ MACOSX_BUNDLE
${SLPlugin_SOURCE_FILES}
)
+set_target_properties(SLPlugin
+ PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
+ )
+
target_link_libraries(SLPlugin
${LLPLUGIN_LIBRARIES}
${LLMESSAGE_LIBRARIES}
@@ -44,12 +50,16 @@ add_dependencies(SLPlugin
)
if (DARWIN)
- # Mac version needs to link against carbon, and also needs an embedded plist (to set LSBackgroundOnly)
+ # Mac version needs to link against Carbon
target_link_libraries(SLPlugin ${CARBON_LIBRARY})
- set_target_properties(
- SLPlugin
- PROPERTIES
- LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist"
+ # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
+ add_custom_command(
+ TARGET SLPlugin POST_BUILD
+ COMMAND mkdir
+ ARGS
+ -p
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SLPlugin.app/Contents/Resources
)
endif (DARWIN)
+ll_deploy_sharedlibs_command(SLPlugin)
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 77240ce546..7d6dde1a58 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -51,7 +51,7 @@
#endif
/*
- On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist.
+ On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist.
Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
@@ -60,7 +60,8 @@
which means adding this to the gcc flags:
-Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
-
+
+ Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity.
*/
#if LL_DARWIN || LL_LINUX
@@ -239,6 +240,24 @@ int main(int argc, char **argv)
checkExceptionHandler();
#endif
+#if LL_DARWIN
+ // If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
+ // Use this to track the current frontmost window and bring this process to the front if it changes.
+ WindowRef front_window = NULL;
+ WindowGroupRef layer_group = NULL;
+ int window_hack_state = 0;
+ CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group);
+ if(layer_group)
+ {
+ // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
+ SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
+ SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
+ }
+#endif
+
+#if LL_DARWIN
+ EventTargetRef event_target = GetEventDispatcherTarget();
+#endif
while(!plugin->isDone())
{
timer.reset();
@@ -246,8 +265,86 @@ int main(int argc, char **argv)
#if LL_DARWIN
{
// Some plugins (webkit at least) will want an event loop. This qualifies.
- EventRecord evt;
- WaitNextEvent(0, &evt, 0, NULL);
+ EventRef event;
+ if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr)
+ {
+ SendEventToEventTarget (event, event_target);
+ ReleaseEvent(event);
+ }
+
+ // Check for a change in this process's frontmost window.
+ if(FrontWindow() != front_window)
+ {
+ ProcessSerialNumber self = { 0, kCurrentProcess };
+ ProcessSerialNumber parent = { 0, kNoProcess };
+ ProcessSerialNumber front = { 0, kNoProcess };
+ Boolean this_is_front_process = false;
+ Boolean parent_is_front_process = false;
+ {
+ // Get this process's parent
+ ProcessInfoRec info;
+ info.processInfoLength = sizeof(ProcessInfoRec);
+ info.processName = NULL;
+ info.processAppSpec = NULL;
+ if(GetProcessInformation( &self, &info ) == noErr)
+ {
+ parent = info.processLauncher;
+ }
+
+ // and figure out whether this process or its parent are currently frontmost
+ if(GetFrontProcess(&front) == noErr)
+ {
+ (void) SameProcess(&self, &front, &this_is_front_process);
+ (void) SameProcess(&parent, &front, &parent_is_front_process);
+ }
+ }
+
+ if((FrontWindow() != NULL) && (front_window == NULL))
+ {
+ // Opening the first window
+
+ if(window_hack_state == 0)
+ {
+ // Next time through the event loop, lower the window group layer
+ window_hack_state = 1;
+ }
+
+ if(layer_group)
+ {
+ SetWindowGroup(FrontWindow(), layer_group);
+ }
+
+ if(parent_is_front_process)
+ {
+ // Bring this process's windows to the front.
+ (void) SetFrontProcess( &self );
+ }
+
+ ActivateWindow(FrontWindow(), true);
+ }
+ else if((FrontWindow() == NULL) && (front_window != NULL))
+ {
+ // Closing the last window
+
+ if(this_is_front_process)
+ {
+ // Try to bring this process's parent to the front
+ (void) SetFrontProcess(&parent);
+ }
+ }
+ else if(window_hack_state == 1)
+ {
+ if(layer_group)
+ {
+ // Set the window group level back to something less extreme
+ SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
+ }
+ window_hack_state = 2;
+ }
+
+ front_window = FrontWindow();
+
+ }
}
#endif
F64 elapsed = timer.getElapsedTimeF64();
diff --git a/indra/llplugin/slplugin/slplugin_info.plist b/indra/llplugin/slplugin/slplugin_info.plist
index b1daf87424..c4597380e0 100644
--- a/indra/llplugin/slplugin/slplugin_info.plist
+++ b/indra/llplugin/slplugin/slplugin_info.plist
@@ -6,7 +6,7 @@
<string>English</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
- <key>LSBackgroundOnly</key>
- <true/>
+ <key>LSUIElement</key>
+ <string>1</string>
</dict>
</plist>