diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 4a7d670c233da713e32134dd06dfa6b5ceeb4d0e..c1536e85de3640350b1f9b556c3d55022f16a953 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 77240ce5468f6bc09d7957e0982acb8764ded397..c18e2375f94993e782124d101a5e1c36458bd46c 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,21 @@ 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
+
 	while(!plugin->isDone())
 	{
 		timer.reset();
@@ -248,6 +264,80 @@ int main(int argc, char **argv)
 			// Some plugins (webkit at least) will want an event loop.  This qualifies.
 			EventRecord evt;
 			WaitNextEvent(0, &evt, 0, NULL);
+			
+			// 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 b1daf87424d6c18b8f3d98cf77630b6f90c01e02..c4597380e0a803832001988a21b5851ba99d76bf 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>
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 7bc6f63e1f0115719b99c01ff1c87c72e04979fb..8d3852002caa3bc448773ff74239df952eb1c5ed 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -426,7 +426,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
 /*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
 {
 	return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
-		"SLPlugin";
+		"SLPlugin.app/Contents/MacOS/SLPlugin";
 }
 
 /*virtual*/ std::string LLDir_Mac::getLLPluginFilename(std::string base_name)
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 18ac10fe389ef2f91ae46f89605914d8d7056ee0..19b18b3282a7033ece655a466bd4196d347d6712 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -639,10 +639,14 @@ def construct(self):
                 self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
                 self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
 
+                # plugin launcher
+                self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app")
+
                 # our apps dependencies on shared libs
                 if dylibs["llcommon"]:
                     mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources")
                     mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources")
+                    slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources")
                     for libfile in ("libllcommon.dylib",
                                     "libapr-1.0.3.7.dylib",
                                     "libaprutil-1.0.3.8.dylib",
@@ -656,9 +660,10 @@ def construct(self):
                                          {'target': target_lib,
                                           'link' : os.path.join(mac_updater_res_path, libfile)}
                                          )
-
-                # plugin launcher
-                self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
+                        self.run_command("ln -sf %(target)r %(link)r" % 
+                                         {'target': target_lib,
+                                          'link' : os.path.join(slplugin_res_path, libfile)}
+                                         )
 
                 # plugins
                 if self.prefix(src="", dst="llplugin"):