Bug 617052 - Use ITaskbarList2::MarkFullscreenWindow for proper windows taskbar integration. r=jmathies
authorBrian R. Bondy <netzen@gmail.com>
Thu, 01 Sep 2011 10:15:09 -0400
changeset 77693 6faef8a5901ccfee72d05bb7345d154ef83589aa
parent 77692 59c205c5d0adc4c1b2e6b0bc800594c3989a52fc
child 77694 7a50f9697fb2676af48bbf7d09fb8f39a0c2b024
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs617052
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 617052 - Use ITaskbarList2::MarkFullscreenWindow for proper windows taskbar integration. r=jmathies
widget/public/nsIWinTaskbar.idl
widget/src/windows/WinTaskbar.cpp
widget/src/windows/nsWindow.cpp
--- a/widget/public/nsIWinTaskbar.idl
+++ b/widget/public/nsIWinTaskbar.idl
@@ -78,17 +78,17 @@ interface nsIDOMWindow;
  * When taskbar icons are combined as is the default in Windows 7, the progress
  * for those windows is also combined as defined here:
  * http://msdn.microsoft.com/en-us/library/dd391697%28VS.85%29.aspx
  *
  * Applications may also define custom taskbar jump lists on application shortcuts.
  * See nsIJumpListBuilder for more information.
  */
 
-[scriptable, uuid(a25ad3ed-1ded-4473-bb6e-bf8b89d88949)]
+[scriptable, uuid(9fc572db-1089-4d43-9121-f4833d77a2df)]
 interface nsIWinTaskbar : nsISupports
 {
   /**
    * Returns true if the operating system supports Win7+ taskbar features.
    * This property acts as a replacement for in-place os version checking.
    */
   readonly attribute boolean available;
 
@@ -138,17 +138,17 @@ interface nsIWinTaskbar : nsISupports
 
   /**
    * Retrieve a taskbar jump list builder
    *
    * Fails if a jump list build operation has already been initiated, developers
    * should make use of a single instance of nsIJumpListBuilder for building lists
    * within an application.
    *
-   * @thow NS_ERROR_ALREADY_INITIALIZED if an nsIJumpListBuilder instance is
+   * @throw NS_ERROR_ALREADY_INITIALIZED if an nsIJumpListBuilder instance is
    * currently building a list.
    */
   nsIJumpListBuilder createJumpListBuilder();
 
   /**
    * Application window taskbar group settings
    */
 
@@ -162,15 +162,40 @@ interface nsIWinTaskbar : nsISupports
    *
    * The default group id is based on application.ini vendor, application, and
    * version values, with a format of 'vendor.app.version'. The default can be
    * retrieved via defaultGroupId.
    *
    * Note, when a window changes taskbar window stacks, it is placed at the
    * bottom of the new stack.
    *
-   * @thow NS_ERROR_INVALID_ARG if the window is not a valid top level window
+   * @throw NS_ERROR_INVALID_ARG if the window is not a valid top level window
    * associated with a widget.
-   * @thow NS_ERROR_FAILURE if the property on the window could not be set.
-   * @thow NS_ERROR_UNEXPECTED for general failures.
+   * @throw NS_ERROR_FAILURE if the property on the window could not be set.
+   * @throw NS_ERROR_UNEXPECTED for general failures.
    */
   void setGroupIdForWindow(in nsIDOMWindow aParent, in AString aIdentifier);
+
+  /**
+   * Notify the taskbar that a window is about to enter full screen mode.
+   *
+   * A Windows autohide taskbar will not behave correctly in all cases if
+   * it is not notified when full screen operations start and end.
+   *
+   * @throw NS_ERROR_INVALID_ARG if the window is not a valid top level window
+   * @throw NS_ERROR_UNEXPECTED for general failures.
+   * @throw NS_ERROR_NOT_AVAILABLE if the taskbar cannot be obtained.
+   */
+  void prepareFullScreen(in nsIDOMWindow aWindow, in boolean aFullScreen);
+
+  /**
+   * Notify the taskbar that a window identified by its HWND is about to enter
+   * full screen mode.
+   *
+   * A Windows autohide taskbar will not behave correctly in all cases if
+   * it is not notified when full screen operations start and end.
+   *
+   * @throw NS_ERROR_INVALID_ARG if the window is not a valid top level window
+   * @throw NS_ERROR_UNEXPECTED for general failures.
+   * @throw NS_ERROR_NOT_AVAILABLE if the taskbar cannot be obtained.
+   */
+  [noscript] void prepareFullScreenHWND(in voidPtr aWindow, in boolean aFullScreen);
 };
--- a/widget/src/windows/WinTaskbar.cpp
+++ b/widget/src/windows/WinTaskbar.cpp
@@ -436,12 +436,43 @@ WinTaskbar::CreateJumpListBuilder(nsIJum
 
 /* void setGroupIdForWindow (in nsIDOMWindow aParent, in AString aIdentifier); */
 NS_IMETHODIMP
 WinTaskbar::SetGroupIdForWindow(nsIDOMWindow *aParent,
                                 const nsAString & aIdentifier) {
   return SetWindowAppUserModelProp(aParent, nsString(aIdentifier));
 }
 
+/* void prepareFullScreen(in nsIDOMWindow aWindow, in boolean aFullScreen); */
+NS_IMETHODIMP
+WinTaskbar::PrepareFullScreen(nsIDOMWindow *aWindow, PRBool aFullScreen) {
+  NS_ENSURE_ARG_POINTER(aWindow);
+
+  HWND toplevelHWND = ::GetAncestor(GetHWNDFromDOMWindow(aWindow), GA_ROOT);
+  if (!toplevelHWND)
+    return NS_ERROR_INVALID_ARG;
+  
+  return PrepareFullScreenHWND(toplevelHWND, aFullScreen);
+}
+
+/* void prepareFullScreen(in voidPtr aWindow, in boolean aFullScreen); */
+NS_IMETHODIMP
+WinTaskbar::PrepareFullScreenHWND(void *aHWND, PRBool aFullScreen) {
+  if (!Initialize())
+    return NS_ERROR_NOT_AVAILABLE;
+
+    NS_ENSURE_ARG_POINTER(aHWND);
+
+    if (!::IsWindow((HWND)aHWND)) 
+      return NS_ERROR_INVALID_ARG;
+
+    HRESULT hr = mTaskbar->MarkFullscreenWindow((HWND)aHWND, aFullScreen);
+    if (FAILED(hr)) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    return NS_OK;
+}
+
 } // namespace widget
 } // namespace mozilla
 
 #endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -182,19 +182,18 @@
 #include "oleidl.h"
 #include <winuser.h>
 #include "nsIAccessibleDocument.h"
 #if !defined(WINABLEAPI)
 #include <winable.h>
 #endif // !defined(WINABLEAPI)
 #endif // defined(ACCESSIBILITY)
 
-#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
 #include "nsIWinTaskbar.h"
-#endif
+#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
 
 #if defined(NS_ENABLE_TSF)
 #include "nsTextStore.h"
 #endif // defined(NS_ENABLE_TSF)
 
 // Windowless plugin support
 #include "npapi.h"
 
@@ -2698,22 +2697,31 @@ NS_METHOD nsWindow::Invalidate(const nsI
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::MakeFullScreen(PRBool aFullScreen)
 {
+  // taskbarInfo will be NULL pre Windows 7 until Bug 680227 is resolved.
+  nsCOMPtr<nsIWinTaskbar> taskbarInfo =
+    do_GetService(NS_TASKBAR_CONTRACTID);
+
   mFullscreenMode = aFullScreen;
   if (aFullScreen) {
     if (mSizeMode == nsSizeMode_Fullscreen)
       return NS_OK;
     mOldSizeMode = mSizeMode;
     SetSizeMode(nsSizeMode_Fullscreen);
+
+    // Notify the taskbar that we will be entering full screen mode.
+    if (taskbarInfo) {
+      taskbarInfo->PrepareFullScreenHWND(mWnd, TRUE);
+    }
   } else {
     SetSizeMode(mOldSizeMode);
   }
 
   UpdateNonClientMargins();
 
   PRBool visible = mIsVisible;
   if (mOldSizeMode == nsSizeMode_Normal)
@@ -2724,16 +2732,21 @@ nsWindow::MakeFullScreen(PRBool aFullScr
   // be called once per fullscreen request.
   nsresult rv = nsBaseWidget::MakeFullScreen(aFullScreen);
 
   if (visible) {
     Show(PR_TRUE);
     Invalidate(PR_FALSE);
   }
 
+  // Notify the taskbar that we have exited full screen mode.
+  if (!aFullScreen && taskbarInfo) {
+    taskbarInfo->PrepareFullScreenHWND(mWnd, FALSE);
+  }
+
   // Let the dom know via web shell window
   nsSizeModeEvent event(PR_TRUE, NS_SIZEMODE, this);
   event.mSizeMode = mSizeMode;
   InitEvent(event);
   DispatchWindowEvent(&event);
 
   return rv;
 }