Bug 484488 - MakeFullWindow support for windows mobile. r=olli.pettay, sr=vlad
authorDoug Turner <dougt@meer.net>
Wed, 01 Jul 2009 12:01:11 -0700
changeset 29944 8312b1fdc8519f4bee84812e92cd24082d53c471
parent 29943 ea19cebaa1efa695b16bb7e4ed8a62f074e81751
child 29945 85acdb9128ce699374a725e7000cb9daff19f22e
push idunknown
push userunknown
push dateunknown
reviewersolli.pettay, vlad
bugs484488
milestone1.9.2a1pre
Bug 484488 - MakeFullWindow support for windows mobile. r=olli.pettay, sr=vlad
browser/components/sessionstore/src/nsSessionStore.js
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/interfaces/base/nsIDOMChromeWindow.idl
dom/tests/mochitest/chrome/Makefile.in
dom/tests/mochitest/chrome/fullscreen.xul
dom/tests/mochitest/chrome/fullscreen_preventdefault.xul
dom/tests/mochitest/chrome/test_fullscreen.xul
dom/tests/mochitest/chrome/test_fullscreen_preventdefault.xul
widget/public/Makefile.in
widget/public/nsEvent.h
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/windows/nsWindowCE.cpp
widget/src/xpwidgets/nsBaseWidget.cpp
xpfe/appshell/src/nsWebShellWindow.cpp
xpfe/appshell/src/nsXULWindow.cpp
xpfe/appshell/src/nsXULWindow.h
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -2577,16 +2577,17 @@ SessionStoreService.prototype = {
    *        Window reference
    * @param aAttribute
    *        String sizemode | width | height | other window attribute
    * @returns string
    */
   _getWindowDimension: function sss_getWindowDimension(aWindow, aAttribute) {
     if (aAttribute == "sizemode") {
       switch (aWindow.windowState) {
+      case aWindow.STATE_FULLSCREEN:
       case aWindow.STATE_MAXIMIZED:
         return "maximized";
       case aWindow.STATE_MINIMIZED:
         return "minimized";
       default:
         return "normal";
       }
     }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -143,17 +143,16 @@
 #include "nsDOMCID.h"
 #include "nsDOMError.h"
 #include "nsDOMWindowUtils.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIWindowWatcher.h"
 #include "nsIContentViewer.h"
 #include "nsDOMClassInfo.h"
 #include "nsIJSNativeInitializer.h"
-#include "nsIFullScreen.h"
 #include "nsIScriptError.h"
 #include "nsIScriptEventManager.h" // For GetInterface()
 #include "nsIConsoleService.h"
 #include "nsIControllers.h"
 #include "nsIControllerContext.h"
 #include "nsGlobalWindowCommands.h"
 #include "nsAutoPtr.h"
 #include "nsContentUtils.h"
@@ -598,17 +597,16 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(n
 //*****************************************************************************
 //***    nsGlobalWindow: Object Management
 //*****************************************************************************
 
 nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
   : nsPIDOMWindow(aOuterWindow),
     mIsFrozen(PR_FALSE),
     mDidInitJavaProperties(PR_FALSE),
-    mFullScreen(PR_FALSE),
     mIsClosed(PR_FALSE), 
     mInClose(PR_FALSE), 
     mHavePendingClose(PR_FALSE),
     mHadOriginalOpener(PR_FALSE),
     mIsPopupSpam(PR_FALSE),
     mBlockScriptedClosingFlag(PR_FALSE),
     mFireOfflineStatusChangeEventOnThaw(PR_FALSE),
     mCreatingInnerWindow(PR_FALSE),
@@ -2108,39 +2106,16 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
 
     // clear all scopes
     NS_STID_FOR_ID(lang_id) {
       langCtx = mScriptContexts[NS_STID_INDEX(lang_id)];
       if (langCtx)
         langCtx->ClearScope(mScriptGlobals[NS_STID_INDEX(lang_id)], PR_TRUE);
     }
 
-    // if we are closing the window while in full screen mode, be sure
-    // to restore os chrome
-    if (mFullScreen) {
-      // only restore OS chrome if the closing window was active
-      nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-      if (fm) {
-        nsCOMPtr<nsIDOMWindow> activeWindow;
-        fm->GetActiveWindow(getter_AddRefs(activeWindow));
-
-        nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
-        nsCOMPtr<nsIDocShellTreeItem> rootItem;
-        treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
-        nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
-        if (rootWin == activeWindow) {
-          nsCOMPtr<nsIFullScreen> fullScreen =
-            do_GetService("@mozilla.org/browser/fullscreen;1");
-
-          if (fullScreen)
-            fullScreen->ShowAllOSChrome();
-        }
-      }
-    }
-
     ClearControllers();
 
     mChromeEventHandler = nsnull; // force release now
 
     if (mArguments) { 
       // We got no new document after someone called
       // SetNewArguments(), drop our reference to the arguments.
       mArguments = nsnull;
@@ -3839,18 +3814,16 @@ nsGlobalWindow::SetFullScreen(PRBool aFu
 
     return NS_OK;
   }
 
   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   if (widget)
     widget->MakeFullScreen(aFullScreen);
 
-  mFullScreen = aFullScreen;
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetFullScreen(PRBool* aFullScreen)
 {
   FORWARD_TO_OUTER(GetFullScreen, (aFullScreen), NS_ERROR_NOT_INITIALIZED);
 
@@ -3862,18 +3835,23 @@ nsGlobalWindow::GetFullScreen(PRBool* aF
     treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
     if (rootItem != treeItem) {
       nsCOMPtr<nsIDOMWindowInternal> window = do_GetInterface(rootItem);
       if (window)
         return window->GetFullScreen(aFullScreen);
     }
   }
 
-  // We are the root window, or something went wrong. Return our internal value.
-  *aFullScreen = mFullScreen;
+  nsCOMPtr<nsIWidget> widget = GetMainWidget();
+  PRInt32 mode;
+  if (!widget)
+    return NS_ERROR_UNEXPECTED;
+
+  widget->GetSizeMode(&mode);
+  *aFullScreen = mode == nsSizeMode_Fullscreen;
   return NS_OK;
 }
 
 PRBool
 nsGlobalWindow::DOMWindowDumpEnabled()
 {
 #if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
   // In optimized builds we check a pref that controls if we should
@@ -6586,30 +6564,16 @@ nsGlobalWindow::GetLocation(nsIDOMLocati
   NS_IF_ADDREF(*aLocation = mLocation);
 
   return NS_OK;
 }
 
 void
 nsGlobalWindow::ActivateOrDeactivate(PRBool aActivate)
 {
-  // if the window is deactivated while in full screen mode,
-  // restore OS chrome, and hide it again upon re-activation
-  nsGlobalWindow* outer = GetOuterWindowInternal();
-  if (outer && outer->mFullScreen) {
-    nsCOMPtr<nsIFullScreen> fullScreen =
-      do_GetService("@mozilla.org/browser/fullscreen;1");
-    if (fullScreen) {
-      if (aActivate)
-        fullScreen->HideAllOSChrome();
-      else
-        fullScreen->ShowAllOSChrome();
-    }
-  }
-
   // Set / unset the "active" attribute on the documentElement
   // of the top level window
   nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
   if (mainWidget) {
     // Get the top level widget (if the main widget is a sheet, this will
     // be the sheet's top (non-sheet) parent).
     nsCOMPtr<nsIWidget> topLevelWidget = mainWidget->GetSheetWindowParent();
     if (!topLevelWidget)
@@ -8762,16 +8726,19 @@ nsGlobalChromeWindow::GetWindowState(PRU
 
   switch (aMode) {
     case nsSizeMode_Minimized:
       *aWindowState = nsIDOMChromeWindow::STATE_MINIMIZED;
       break;
     case nsSizeMode_Maximized:
       *aWindowState = nsIDOMChromeWindow::STATE_MAXIMIZED;
       break;
+    case nsSizeMode_Fullscreen:
+      *aWindowState = nsIDOMChromeWindow::STATE_FULLSCREEN;
+      break;
     case nsSizeMode_Normal:
       *aWindowState = nsIDOMChromeWindow::STATE_NORMAL;
       break;
     default:
       NS_WARNING("Illegal window state for this chrome window");
       break;
   }
 
@@ -8792,26 +8759,18 @@ nsGlobalChromeWindow::Maximize()
 }
 
 NS_IMETHODIMP
 nsGlobalChromeWindow::Minimize()
 {
   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   nsresult rv = NS_OK;
 
-  if (widget) {
-    // minimize doesn't send deactivate events on windows,
-    // so we need to forcefully restore the os chrome
-    nsCOMPtr<nsIFullScreen> fullScreen =
-      do_GetService("@mozilla.org/browser/fullscreen;1");
-    if (fullScreen)
-      fullScreen->ShowAllOSChrome();
-
+  if (widget)
     rv = widget->SetSizeMode(nsSizeMode_Minimized);
-  }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsGlobalChromeWindow::Restore()
 {
   nsCOMPtr<nsIWidget> widget = GetMainWidget();
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -665,17 +665,16 @@ protected:
   PRPackedBool                  mIsFrozen : 1;
 
   // True if the Java properties have been initialized on this
   // window. Only used on inner windows.
   PRPackedBool                  mDidInitJavaProperties : 1;
   
   // These members are only used on outer window objects. Make sure
   // you never set any of these on an inner object!
-  PRPackedBool                  mFullScreen : 1;
   PRPackedBool                  mIsClosed : 1;
   PRPackedBool                  mInClose : 1;
   // mHavePendingClose means we've got a termination function set to
   // close us when the JS stops executing or that we have a close
   // event posted.  If this is set, just ignore window.close() calls.
   PRPackedBool                  mHavePendingClose : 1;
   PRPackedBool                  mHadOriginalOpener : 1;
   PRPackedBool                  mIsPopupSpam : 1;
--- a/dom/interfaces/base/nsIDOMChromeWindow.idl
+++ b/dom/interfaces/base/nsIDOMChromeWindow.idl
@@ -35,22 +35,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
 interface nsIBrowserDOMWindow;
 
-[scriptable, uuid(77a20f5a-68ad-41d3-97ac-6ff721512908)]
+[scriptable, uuid(09A5E148-2A77-4739-9DD9-3D552F5390EE)]
 interface nsIDOMChromeWindow : nsISupports
 {
   const unsigned short STATE_MAXIMIZED = 1;
   const unsigned short STATE_MINIMIZED = 2;
   const unsigned short STATE_NORMAL = 3;
+  const unsigned short STATE_FULLSCREEN = 4;
 
   readonly attribute unsigned short              windowState;
 
   /**
    * browserDOMWindow provides access to yet another layer of
    * utility functions implemented by chrome script. It will be null
    * for DOMWindows not corresponding to browsers.
    */
--- a/dom/tests/mochitest/chrome/Makefile.in
+++ b/dom/tests/mochitest/chrome/Makefile.in
@@ -39,17 +39,22 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = dom/tests/mochitest/chrome
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-_TEST_FILES = test_domstorage.xul \
+_TEST_FILES = \
+		test_fullscreen.xul \
+		fullscreen.xul \
+		test_fullscreen_preventdefault.xul \
+		fullscreen_preventdefault.xul \
+		test_domstorage.xul \
 		domstorage_global.xul \
 		domstorage_global.js \
 		test_focus.xul \
 		window_focus.xul \
 		focus_window2.xul \
 		focus_frameset.html \
 		child_focus_frame.html \
 		test_focus_switchbinding.xul \
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/fullscreen.xul
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+  Test for fullscreen sizemode in chrome
+  -->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        sizemode="fullscreen">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>      
+
+<script>
+
+window.addEventListener("fullscreen", onFullScreen, true);
+
+function onFullScreen()
+{
+  window.opener.wrappedJSObject.done();
+}
+
+</script>
+
+<button id="find-button" label="Find"/>
+<button id="cancel-button" label="Cancel"/>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/fullscreen_preventdefault.xul
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+  Test for fullscreen sizemode in chrome
+  -->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        sizemode="fullscreen">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>      
+
+<script>
+
+window.addEventListener("fullscreen", onFullScreen, true);
+
+function onFullScreen(event)
+{
+  event.preventDefault();
+  window.opener.wrappedJSObject.done();
+}
+
+</script>
+
+<button id="find-button" label="Find"/>
+<button id="cancel-button" label="Cancel"/>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/test_fullscreen.xul
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+  Test for fullscreen sizemode in chrome
+  -->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        sizemode="fullscreen">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>      
+
+<script>
+SimpleTest.waitForExplicitFinish();
+
+newwindow = window.open("fullscreen.xul", "_blank","chrome,resizable=yes");
+
+function done()
+{
+  setTimeout("complete()", 0);
+}
+
+function complete()
+{
+  ok(newwindow.fullScreen, "window.fullScreen is true.");
+  newwindow.close();
+  SimpleTest.finish();
+}
+
+</script>
+
+
+<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/chrome/test_fullscreen_preventdefault.xul
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+  Test for fullscreen sizemode in chrome
+  -->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        sizemode="fullscreen">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>      
+
+<script>
+SimpleTest.waitForExplicitFinish();
+
+newwindow = window.open("fullscreen_preventdefault.xul", "_blank","chrome,resizable=yes");
+
+function done()
+{
+  // because we are cancelling the fullscreen event, it
+  // takes a bit for the fullScreen property to be set
+  setTimeout("complete()", 0);
+}
+
+function complete()
+{
+  ok(!(newwindow.fullScreen), "window.fullScreen is false.");
+  newwindow.close();
+  SimpleTest.finish();
+}
+
+</script>
+
+
+<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
+
+</window>
--- a/widget/public/Makefile.in
+++ b/widget/public/Makefile.in
@@ -92,17 +92,16 @@ XPIDLSRCS	= \
 		nsIDragService.idl \
 		nsIFormatConverter.idl \
 		nsIClipboard.idl \
 		nsIClipboardHelper.idl \
 		nsIClipboardOwner.idl \
 		nsIRollupListener.idl \
 		nsIBaseWindow.idl \
 		nsIBidiKeyboard.idl \
-		nsIFullScreen.idl \
 		nsIScreen.idl \
 		nsIScreenManager.idl \
 		nsIPrintSession.idl \
 		nsIPrintSettings.idl \
 		nsIPrintSettingsService.idl \
 		nsIPrintOptions.idl \
 		nsIIdleService.idl \
 		$(NULL)
--- a/widget/public/nsEvent.h
+++ b/widget/public/nsEvent.h
@@ -58,17 +58,18 @@ enum nsEventStatus {
 };
 
 /**
  * sizemode is an adjunct to widget size
  */
 enum nsSizeMode {
   nsSizeMode_Normal = 0,
   nsSizeMode_Minimized,
-  nsSizeMode_Maximized
+  nsSizeMode_Maximized,
+  nsSizeMode_Fullscreen
 };
 
 class nsEvent;
 
 class nsGUIEvent;
 class nsSizeEvent;
 class nsSizeModeEvent;
 class nsZLevelEvent;
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -1135,22 +1135,32 @@ NS_METHOD nsWindow::Show(PRBool bState)
   // SetWindowPos would get the correct answer.
   mIsVisible = bState;
 
   if (mWnd) {
     if (bState) {
       if (!wasVisible && mWindowType == eWindowType_toplevel) {
         switch (mSizeMode) {
 #ifdef WINCE
+          case nsSizeMode_Fullscreen:
+            ::SetForegroundWindow(mWnd);
+            ::ShowWindow(mWnd, SW_SHOWMAXIMIZED);
+            MakeFullScreen(TRUE);
+            break;
+
           case nsSizeMode_Maximized :
             ::SetForegroundWindow(mWnd);
             ::ShowWindow(mWnd, SW_SHOWMAXIMIZED);
             break;
           // use default for nsSizeMode_Minimized on Windows CE
 #else
+          case nsSizeMode_Fullscreen:
+            ::ShowWindow(mWnd, SW_SHOWMAXIMIZED);
+            break;
+
           case nsSizeMode_Maximized :
             ::ShowWindow(mWnd, SW_SHOWMAXIMIZED);
             break;
           case nsSizeMode_Minimized :
             ::ShowWindow(mWnd, SW_SHOWMINIMIZED);
             break;
 #endif
           default:
@@ -1492,16 +1502,20 @@ NS_IMETHODIMP nsWindow::SetSizeMode(PRIn
     return NS_OK;
 
   // save the requested state
   rv = nsBaseWidget::SetSizeMode(aMode);
   if (NS_SUCCEEDED(rv) && mIsVisible) {
     int mode;
 
     switch (aMode) {
+      case nsSizeMode_Fullscreen :
+        mode = SW_MAXIMIZE;
+        break;
+
       case nsSizeMode_Maximized :
         mode = SW_MAXIMIZE;
         break;
       case nsSizeMode_Minimized :
         mode = sTrimOnMinimize ? SW_MINIMIZE : SW_SHOWMINIMIZED;
         if (!sTrimOnMinimize) {
           // Find the next window that is visible and not minimized.
           HWND hwndBelow = ::GetNextWindow(mWnd, GW_HWNDNEXT);
@@ -2298,16 +2312,37 @@ NS_METHOD nsWindow::Invalidate(const nsI
 
     if (aIsSynchronous) {
       VERIFY(::UpdateWindow(mWnd));
     }
   }
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsWindow::MakeFullScreen(PRBool aFullScreen)
+{
+#if WINCE
+  RECT rc;
+  if (aFullScreen) {
+    SetForegroundWindow(mWnd);
+    SHFullScreen(mWnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
+    SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
+  }
+  else {
+    SHFullScreen(mWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON);
+    SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE);
+  }
+  MoveWindow(mWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
+  return NS_OK;
+#else
+  return nsBaseWidget::MakeFullScreen(aFullScreen);
+#endif
+}
+
 /**************************************************************
  *
  * SECTION: nsIWidget::Update
  *
  * Force a synchronous repaint of the window.
  *
  **************************************************************/
 
@@ -4119,16 +4154,18 @@ PRBool nsWindow::ProcessMessage(UINT msg
           else
             *aRetValue = MA_NOACTIVATE;
 
           if (sSwitchKeyboardLayout && mLastKeyboardLayout)
             ActivateKeyboardLayout(mLastKeyboardLayout, 0);
 #else
           *aRetValue = 0;
 #endif
+          if (mSizeMode == nsSizeMode_Fullscreen)
+            MakeFullScreen(TRUE);
         }
       }
       break;
 
 #ifndef WINCE
     case WM_MOUSEACTIVATE:
       if (mWindowType == eWindowType_popup) {
         // a popup with a parent owner should not be activated when clicked
@@ -4278,17 +4315,17 @@ PRBool nsWindow::ProcessMessage(UINT msg
 
         if (pl.showCmd == SW_SHOWMAXIMIZED)
           event.mSizeMode = nsSizeMode_Maximized;
         else if (pl.showCmd == SW_SHOWMINIMIZED)
           event.mSizeMode = nsSizeMode_Minimized;
         else
           event.mSizeMode = nsSizeMode_Normal;
 #else
-        event.mSizeMode = nsSizeMode_Normal;
+        event.mSizeMode = mSizeMode;
 #endif
         InitEvent(event);
 
         result = DispatchWindowEvent(&event);
       }
     }
     break;
 
@@ -6451,9 +6488,9 @@ PRBool ChildWindow::DispatchMouseEvent(P
 // return the style for a child nsWindow
 DWORD ChildWindow::WindowStyle()
 {
   DWORD style = WS_CLIPCHILDREN | nsWindow::WindowStyle();
   if (!(style & WS_POPUP))
     style |= WS_CHILD; // WS_POPUP and WS_CHILD are mutually exclusive.
   VERIFY_WINDOW_STYLE(style);
   return style;
-}
\ No newline at end of file
+}
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -135,16 +135,17 @@ public:
   NS_IMETHOD              SetFocus(PRBool aRaise);
   NS_IMETHOD              GetBounds(nsIntRect &aRect);
   NS_IMETHOD              GetScreenBounds(nsIntRect &aRect);
   NS_IMETHOD              GetClientBounds(nsIntRect &aRect);
   NS_IMETHOD              SetBackgroundColor(const nscolor &aColor);
   NS_IMETHOD              SetCursor(imgIContainer* aCursor,
                                     PRUint32 aHotspotX, PRUint32 aHotspotY);
   NS_IMETHOD              SetCursor(nsCursor aCursor);
+  NS_IMETHOD              MakeFullScreen(PRBool aFullScreen);
   NS_IMETHOD              HideWindowChrome(PRBool aShouldHide);
   NS_IMETHOD              Validate();
   NS_IMETHOD              Invalidate(PRBool aIsSynchronous);
   NS_IMETHOD              Invalidate(const nsIntRect & aRect, PRBool aIsSynchronous);
   NS_IMETHOD              Update();
   NS_IMETHOD              Scroll(PRInt32 aDx, PRInt32 aDy, nsIntRect *aClipRect);
   virtual void*           GetNativeData(PRUint32 aDataType);
   virtual void            FreeNativeData(void * data, PRUint32 aDataType);
@@ -514,9 +515,9 @@ public:
   PRBool DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, LPARAM lParam,
                             PRBool aIsContextMenuKey = PR_FALSE,
                             PRInt16 aButton = nsMouseEvent::eLeftButton);
 
 protected:
   virtual DWORD WindowStyle();
 };
 
-#endif // Window_h__
\ No newline at end of file
+#endif // Window_h__
--- a/widget/src/windows/nsWindowCE.cpp
+++ b/widget/src/windows/nsWindowCE.cpp
@@ -310,26 +310,28 @@ NS_IMETHODIMP nsWindow::SetSizeMode(PRIn
   // calls us directly, and then the OS triggers another call to us.)
   if (aMode == mSizeMode)
     return NS_OK;
 
 #ifdef WINCE_WINDOWS_MOBILE
   // on windows mobile, dialogs and top level windows are full screen
   // This is partly due to the lack of a GetWindowPlacement.
   if (mWindowType == eWindowType_dialog || mWindowType == eWindowType_toplevel) {
-    aMode = nsSizeMode_Maximized;
+    if (aMode == nsSizeMode_Normal)
+      aMode = nsSizeMode_Maximized;
   }
 #endif
 
   // save the requested state
   rv = nsBaseWidget::SetSizeMode(aMode);
   if (NS_SUCCEEDED(rv) && mIsVisible) {
     int mode;
 
     switch (aMode) {
+      case nsSizeMode_Fullscreen :
       case nsSizeMode_Maximized :
         mode = SW_MAXIMIZE;
         break;
       default :
         mode = SW_RESTORE;
     }
     ::ShowWindow(mWnd, mode);
   }
@@ -428,9 +430,9 @@ PRBool nsWindow::OnHotKey(WPARAM wParam,
       break;
 
     case VK_APP6:
       keybd_event(VK_F6, 0, 0, 0);
       keybd_event(VK_F6, 0, KEYEVENTF_KEYUP, 0);
       break;
   }
   return PR_FALSE;
-}
\ No newline at end of file
+}
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -36,17 +36,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsBaseWidget.h"
 #include "nsIDeviceContext.h"
 #include "nsCOMPtr.h"
 #include "nsGfxCIID.h"
 #include "nsWidgetsCID.h"
-#include "nsIFullScreen.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIScreenManager.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIContent.h"
 
 #ifdef DEBUG
 #include "nsIServiceManager.h"
@@ -437,18 +436,21 @@ NS_IMETHODIMP nsBaseWidget::PlaceBehind(
 //-------------------------------------------------------------------------
 //
 // Maximize, minimize or restore the window. The BaseWidget implementation
 // merely stores the state.
 //
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsBaseWidget::SetSizeMode(PRInt32 aMode) {
 
-  if (aMode == nsSizeMode_Normal || aMode == nsSizeMode_Minimized ||
-      aMode == nsSizeMode_Maximized) {
+
+  if (aMode == nsSizeMode_Normal ||
+      aMode == nsSizeMode_Minimized ||
+      aMode == nsSizeMode_Maximized ||
+      aMode == nsSizeMode_Fullscreen) {
 
     mSizeMode = (nsSizeMode) aMode;
     return NS_OK;
   }
   return NS_ERROR_ILLEGAL_VALUE;
 }
 
 //-------------------------------------------------------------------------
@@ -581,19 +583,19 @@ NS_IMETHODIMP nsBaseWidget::HideWindowCh
 
 //-------------------------------------------------------------------------
 //
 // Put the window into full-screen mode
 //
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsBaseWidget::MakeFullScreen(PRBool aFullScreen)
 {
-  HideWindowChrome(aFullScreen);
+  SetSizeMode(aFullScreen ? nsSizeMode_Fullscreen : nsSizeMode_Normal);
 
-  nsCOMPtr<nsIFullScreen> fullScreen = do_GetService("@mozilla.org/browser/fullscreen;1");
+  HideWindowChrome(aFullScreen);
 
   if (aFullScreen) {
     if (!mOriginalBounds)
       mOriginalBounds = new nsIntRect();
     GetScreenBounds(*mOriginalBounds);
 
     // Move to top-left corner of screen and size to the screen dimensions
     nsCOMPtr<nsIScreenManager> screenManager;
@@ -602,33 +604,24 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScre
     if (screenManager) {
       nsCOMPtr<nsIScreen> screen;
       screenManager->ScreenForRect(mOriginalBounds->x, mOriginalBounds->y,
                                    mOriginalBounds->width, mOriginalBounds->height,
                                    getter_AddRefs(screen));
       if (screen) {
         PRInt32 left, top, width, height;
         if (NS_SUCCEEDED(screen->GetRect(&left, &top, &width, &height))) {
-          SetSizeMode(nsSizeMode_Normal);
           Resize(left, top, width, height, PR_TRUE);
-    
-          // Hide all of the OS chrome
-          if (fullScreen)
-            fullScreen->HideAllOSChrome();
         }
       }
     }
 
   } else if (mOriginalBounds) {
     Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width,
            mOriginalBounds->height, PR_TRUE);
-
-    // Show all of the OS chrome
-    if (fullScreen)
-      fullScreen->ShowAllOSChrome();
   }
 
   return NS_OK;
 }
 
 //-------------------------------------------------------------------------
 //
 // Create a rendering context from this nsBaseWidget
--- a/xpfe/appshell/src/nsWebShellWindow.cpp
+++ b/xpfe/appshell/src/nsWebShellWindow.cpp
@@ -342,17 +342,18 @@ nsWebShellWindow::HandleEvent(nsGUIEvent
       }
       case NS_SIZEMODE: {
         nsSizeModeEvent* modeEvent = (nsSizeModeEvent*)aEvent;
 
         // an alwaysRaised (or higher) window will hide any newly opened
         // normal browser windows. here we just drop a raised window
         // to the normal zlevel if it's maximized. we make no provision
         // for automatically re-raising it when restored.
-        if (modeEvent->mSizeMode == nsSizeMode_Maximized) {
+        if (modeEvent->mSizeMode == nsSizeMode_Maximized ||
+            modeEvent->mSizeMode == nsSizeMode_Fullscreen) {
           PRUint32 zLevel;
           eventWindow->GetZLevel(&zLevel);
           if (zLevel > nsIXULWindow::normalZ)
             eventWindow->SetZLevel(nsIXULWindow::normalZ);
         }
 
         aEvent->widget->SetSizeMode(modeEvent->mSizeMode);
 
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -90,19 +90,20 @@
 #include "nsITimelineService.h"
 #include "nsAppShellCID.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 
 #include "nsWebShellWindow.h" // get rid of this one, too...
 
-#define SIZEMODE_NORMAL    NS_LITERAL_STRING("normal")
-#define SIZEMODE_MAXIMIZED NS_LITERAL_STRING("maximized")
-#define SIZEMODE_MINIMIZED NS_LITERAL_STRING("minimized")
+#define SIZEMODE_NORMAL     NS_LITERAL_STRING("normal")
+#define SIZEMODE_MAXIMIZED  NS_LITERAL_STRING("maximized")
+#define SIZEMODE_MINIMIZED  NS_LITERAL_STRING("minimized")
+#define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
 
 #define WINDOWTYPE_ATTRIBUTE NS_LITERAL_STRING("windowtype")
 
 #define PERSIST_ATTRIBUTE  NS_LITERAL_STRING("persist")
 #define SCREENX_ATTRIBUTE  NS_LITERAL_STRING("screenX")
 #define SCREENY_ATTRIBUTE  NS_LITERAL_STRING("screenY")
 #define WIDTH_ATTRIBUTE    NS_LITERAL_STRING("width")
 #define HEIGHT_ATTRIBUTE   NS_LITERAL_STRING("height")
@@ -250,17 +251,17 @@ NS_IMETHODIMP nsXULWindow::SetZLevel(PRU
     return NS_OK;
 
   /* refuse to raise a maximized window above the normal browser level,
      for fear it could hide newly opened browser windows */
   if (aLevel > nsIXULWindow::normalZ) {
     PRInt32 sizeMode;
     if (mWindow) {
       mWindow->GetSizeMode(&sizeMode);
-      if (sizeMode == nsSizeMode_Maximized)
+      if (sizeMode == nsSizeMode_Maximized || sizeMode == nsSizeMode_Fullscreen)
         return NS_ERROR_FAILURE;
     }
   }
 
   // disallow user script
   nsCOMPtr<nsIScriptSecurityManager> secMan =
            do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
   if (!secMan)
@@ -270,40 +271,17 @@ NS_IMETHODIMP nsXULWindow::SetZLevel(PRU
     return NS_ERROR_FAILURE;
 
   // do it
   mediator->SetZLevel(this, aLevel);
   PersistentAttributesDirty(PAD_MISC);
   SavePersistentAttributes();
 
   // finally, send a notification DOM event
-  nsCOMPtr<nsIContentViewer> cv;
-  mDocShell->GetContentViewer(getter_AddRefs(cv));
-  nsCOMPtr<nsIDocumentViewer> dv(do_QueryInterface(cv));
-  if (dv) {
-    nsCOMPtr<nsIDocument> doc;
-    dv->GetDocument(getter_AddRefs(doc));
-    nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(doc));
-    if (docEvent) {
-      nsCOMPtr<nsIDOMEvent> event;
-      docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-      if (event) {
-        event->InitEvent(NS_LITERAL_STRING("windowZLevel"), PR_TRUE, PR_FALSE);
-
-        nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
-        privateEvent->SetTrusted(PR_TRUE);
-
-        nsCOMPtr<nsIDOMEventTarget> targ(do_QueryInterface(doc));
-        if (targ) {
-          PRBool defaultActionEnabled;
-          targ->DispatchEvent(event, &defaultActionEnabled);
-        }
-      }
-    }
-  }
+  DispatchCustomEvent(NS_LITERAL_STRING("windowZLevel"));
   
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULWindow::GetContextFlags(PRUint32 *aContextFlags)
 {
   NS_ENSURE_ARG_POINTER(aContextFlags);
   *aContextFlags = mContextFlags;
@@ -1197,27 +1175,43 @@ PRBool nsXULWindow::LoadMiscPersistentAt
   // sizemode
   rv = windowElement->GetAttribute(NS_LITERAL_STRING("sizemode"), stateString);
   if (NS_SUCCEEDED(rv)) {
     PRInt32 sizeMode = nsSizeMode_Normal;
     /* ignore request to minimize, to not confuse novices
     if (stateString.Equals(SIZEMODE_MINIMIZED))
       sizeMode = nsSizeMode_Minimized;
     */
-    if (stateString.Equals(SIZEMODE_MAXIMIZED)) {
+    if (stateString.Equals(SIZEMODE_MAXIMIZED) || stateString.Equals(SIZEMODE_FULLSCREEN)) {
       /* Honor request to maximize only if the window is sizable.
          An unsizable, unmaximizable, yet maximized window confuses
          Windows OS and is something of a travesty, anyway. */
       if (mChromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) {
         mIntrinsicallySized = PR_FALSE;
-        sizeMode = nsSizeMode_Maximized;
+        
+        if (stateString.Equals(SIZEMODE_MAXIMIZED))
+          sizeMode = nsSizeMode_Maximized;
+        else
+          sizeMode = nsSizeMode_Fullscreen;
       }
     }
+
+    // Dispatch fullscreen event
+    if (sizeMode == nsSizeMode_Fullscreen) {
+      if (!DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"), PR_TRUE, PR_FALSE)) {
+        // fullscreen event prevented the default, set the window to
+        // maximized instead of fullscreen.
+        sizeMode = nsSizeMode_Maximized;
+        mWindow->SetSizeMode(sizeMode);
+      }
+    }
+
     // the widget had better be able to deal with not becoming visible yet
     mWindow->SetSizeMode(sizeMode);
+
     gotState = PR_TRUE;
   }
 
   // zlevel
   rv = windowElement->GetAttribute(NS_LITERAL_STRING("zlevel"), stateString);
   if (NS_SUCCEEDED(rv) && stateString.Length() > 0) {
     PRInt32  errorCode;
     PRUint32 zLevel = stateString.ToInteger(&errorCode);
@@ -1517,16 +1511,18 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
     }
   }
 
   if (mPersistentAttributesDirty & PAD_MISC) {
     if (sizeMode != nsSizeMode_Minimized &&
         persistString.Find("sizemode") >= 0) {
       if (sizeMode == nsSizeMode_Maximized)
         sizeString.Assign(SIZEMODE_MAXIMIZED);
+      else if (sizeMode == nsSizeMode_Fullscreen)
+        sizeString.Assign(SIZEMODE_FULLSCREEN);
       else
         sizeString.Assign(SIZEMODE_NORMAL);
       docShellElement->SetAttribute(MODE_ATTRIBUTE, sizeString);
       if (ownerXULDoc)
         ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE);
     }
     if (persistString.Find("zlevel") >= 0) {
       PRUint32 zLevel;
@@ -2134,16 +2130,58 @@ PRInt32 nsXULWindow::AppUnitsPerDevPixel
     mAppPerDev = mWindow->GetDeviceContext()->AppUnitsPerDevPixel();
   } else {
     NS_ERROR("nsXULWindow::AppUnitsPerDevPixel called with no window "
              "or no dev context");
   }
   return mAppPerDev;
 }
 
+
+PRBool nsXULWindow::DispatchCustomEvent(const nsAString& eventName, PRBool cancelable, PRBool toDocument)
+{
+  nsCOMPtr<nsIContentViewer> cv;
+  mDocShell->GetContentViewer(getter_AddRefs(cv));
+  nsCOMPtr<nsIDocumentViewer> dv(do_QueryInterface(cv));
+  if (dv) {
+    nsCOMPtr<nsIDocument> doc;
+    dv->GetDocument(getter_AddRefs(doc));
+    nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(doc));
+    if (docEvent) {
+      nsCOMPtr<nsIDOMEvent> event;
+      docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
+      if (event) {
+        event->InitEvent(eventName, PR_TRUE, cancelable);
+        
+        nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
+        privateEvent->SetTrusted(PR_TRUE);
+        
+        if (toDocument) {
+          nsCOMPtr<nsIDOMEventTarget> targ(do_QueryInterface(doc));
+          if (targ) {
+            PRBool defaultActionEnabled;
+            targ->DispatchEvent(event, &defaultActionEnabled);
+            return defaultActionEnabled;
+          }
+        } else {
+          nsCOMPtr<nsIDOMWindowInternal> ourWindow;
+          GetWindowDOMWindow(getter_AddRefs(ourWindow));
+          nsCOMPtr<nsIDOMEventTarget> targ(do_QueryInterface(ourWindow));
+          if (targ) {
+            PRBool defaultActionEnabled;
+            targ->DispatchEvent(event, &defaultActionEnabled);
+            return defaultActionEnabled;
+          }
+        }
+      }
+    }
+  }
+  return PR_TRUE;
+}
+
 //*****************************************************************************
 //*** nsContentShellInfo: Object Management
 //*****************************************************************************   
 
 nsContentShellInfo::nsContentShellInfo(const nsAString& aID,
                                        nsIWeakReference* aContentShell)
   : id(aID),
     child(aContentShell)
--- a/xpfe/appshell/src/nsXULWindow.h
+++ b/xpfe/appshell/src/nsXULWindow.h
@@ -145,16 +145,17 @@ protected:
    PRBool     ConstrainToZLevel(PRBool aImmediate, nsWindowZ *aPlacement,
                                 nsIWidget *aReqBelow, nsIWidget **aActualBelow);
    void       PlaceWindowLayersBehind(PRUint32 aLowLevel, PRUint32 aHighLevel,
                                       nsIXULWindow *aBehind);
    void       SetContentScrollbarVisibility(PRBool aVisible);
    PRBool     GetContentScrollbarVisibility();
    void       PersistentAttributesDirty(PRUint32 aDirtyFlags);
    PRInt32    AppUnitsPerDevPixel();
+   PRBool     DispatchCustomEvent(const nsAString& eventName, PRBool cancelable = PR_FALSE, PRBool toDocument = PR_TRUE);
 
    nsChromeTreeOwner*      mChromeTreeOwner;
    nsContentTreeOwner*     mContentTreeOwner;
    nsContentTreeOwner*     mPrimaryContentTreeOwner;
    nsCOMPtr<nsIWidget>     mWindow;
    nsCOMPtr<nsIDocShell>   mDocShell;
    nsCOMPtr<nsIDOMWindowInternal>  mDOMWindow;
    nsCOMPtr<nsIWeakReference> mParentWindow;