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 76382 6faef8a5901ccfee72d05bb7345d154ef83589aa
parent 76381 59c205c5d0adc4c1b2e6b0bc800594c3989a52fc
child 76383 7a50f9697fb2676af48bbf7d09fb8f39a0c2b024
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersjmathies
bugs617052
milestone9.0a1
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;
 }