gtk+ r19545 - in branches/gtk-2-12: . gdk/win32



Author: bratsche
Date: Tue Feb 12 21:29:57 2008
New Revision: 19545
URL: http://svn.gnome.org/viewvc/gtk+?rev=19545&view=rev

Log:
2008-02-12  Cody Russell  <bratsche gnome org>

        Merged from trunk:

        * gdk/win32/gdkprivate-win32.h
        * gdk/win32/gdkevents-win32.c
        * gdk/win32/gdkwindow-win32.c
        * gdk/win32/gdkwindow-win32.h
        * gdk/win32/gdkwin32.h:
        Modal window rework.  (#455627, #511111, #514643, #514789)



Modified:
   branches/gtk-2-12/ChangeLog
   branches/gtk-2-12/gdk/win32/gdkevents-win32.c
   branches/gtk-2-12/gdk/win32/gdkprivate-win32.h
   branches/gtk-2-12/gdk/win32/gdkwin32.h
   branches/gtk-2-12/gdk/win32/gdkwindow-win32.c
   branches/gtk-2-12/gdk/win32/gdkwindow-win32.h

Modified: branches/gtk-2-12/gdk/win32/gdkevents-win32.c
==============================================================================
--- branches/gtk-2-12/gdk/win32/gdkevents-win32.c	(original)
+++ branches/gtk-2-12/gdk/win32/gdkevents-win32.c	Tue Feb 12 21:29:57 2008
@@ -94,6 +94,7 @@
 				    gpointer     user_data);
 
 static void append_event (GdkEvent *event);
+static gboolean is_modally_blocked (GdkWindow   *window);
 
 /* Private variable declarations
  */
@@ -1767,6 +1768,13 @@
 doesnt_want_key (gint mask,
 		 MSG *msg)
 {
+  GdkWindow *modal_current = _gdk_modal_current ();
+  GdkWindow *window = (GdkWindow *) gdk_win32_handle_table_lookup ((GdkNativeWindow)msg->hwnd);
+  gboolean modally_blocked = modal_current != NULL ? gdk_window_get_toplevel (window) != modal_current : FALSE;
+
+  if (modally_blocked == TRUE)
+    return TRUE;
+
   return (((msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) &&
 	   !(mask & GDK_KEY_RELEASE_MASK)) ||
 	  ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) &&
@@ -2805,12 +2813,27 @@
       break;
 
      case WM_MOUSEACTIVATE:
-       if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
-	   || !((GdkWindowObject *)window)->accept_focus)
-	 {
-	   *ret_valp = MA_NOACTIVATE;
-	   return_val = TRUE;
-	 }
+       {
+	 GdkWindow *tmp;
+	 if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
+	     || !((GdkWindowObject *)window)->accept_focus)
+	   {
+	     *ret_valp = MA_NOACTIVATE;
+	     return_val = TRUE;
+	   }
+
+	 tmp = _gdk_modal_current ();
+
+	 if (tmp != NULL)
+	   {
+	     if (gdk_window_get_toplevel (window) != tmp)
+	       {
+		 *ret_valp = MA_NOACTIVATEANDEAT;
+		 return_val = TRUE;
+	       }
+	   }
+       }
+
        break;
 
     case WM_KILLFOCUS:
@@ -2916,10 +2939,14 @@
 
     case WM_SYSCOMMAND:
 
-      if (msg->wParam == SC_MINIMIZE || msg->wParam == SC_RESTORE)
+      switch (msg->wParam)
 	{
+	case SC_MINIMIZE:
+	case SC_RESTORE:
 	  show_window_internal (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE);
+	  break;
 	}
+
       break;
 
     case WM_SIZE:
@@ -2971,10 +2998,12 @@
 		}
 	    }
 	  else if (msg->wParam == SIZE_MAXIMIZED)
-	    gdk_synthesize_window_state (window,
-					 GDK_WINDOW_STATE_ICONIFIED |
-					 withdrawn_bit,
-					 GDK_WINDOW_STATE_MAXIMIZED);
+	    {
+	      gdk_synthesize_window_state (window,
+					   GDK_WINDOW_STATE_ICONIFIED |
+					   withdrawn_bit,
+					   GDK_WINDOW_STATE_MAXIMIZED);
+	    }
 
 	  if (((GdkWindowObject *) window)->resize_count > 1)
 	    ((GdkWindowObject *) window)->resize_count -= 1;
@@ -3230,6 +3259,7 @@
 		  break;
 		}
 	    }
+
 	  *ret_valp = TRUE;
 	  return_val = TRUE;
 	  GDK_NOTE (EVENTS, g_print (" (handled ASPECT: %s)",
@@ -3363,7 +3393,10 @@
           append_event (event);
 	}
       else
-	return_val = TRUE;
+	{
+	  return_val = TRUE;
+	}
+
       break;
 
     case WM_RENDERFORMAT:
@@ -3398,7 +3431,9 @@
 
 	  /* Now the clipboard owner should have rendered */
 	  if (!_delayed_rendering_data)
-	    GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)"));
+	    {
+	      GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)"));
+	    }
 	  else
 	    {
 	      if (msg->wParam == CF_DIB)
@@ -3412,6 +3447,7 @@
 		      break;
 		    }
 		}
+
 	      /* The requestor is holding the clipboard, no
 	       * OpenClipboard() is required/possible
 	       */
@@ -3423,6 +3459,18 @@
 
     case WM_ACTIVATE:
 
+      /* We handle mouse clicks for modally-blocked windows under WM_MOUSEACTIVATE,
+       * but we still need to deal with alt-tab, or with SetActiveWindow() type
+       * situations. */
+      if (is_modally_blocked (window) && msg->wParam == WA_ACTIVE)
+	{
+	  GdkWindow *modal_current = _gdk_modal_current ();
+	  SetActiveWindow (GDK_WINDOW_HWND (modal_current));
+	  *ret_valp = 0;
+	  return_val = TRUE;
+	  break;
+	}
+
       /* Bring any tablet contexts to the top of the overlap order when
        * one of our windows is activated.
        * NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
@@ -3458,10 +3506,12 @@
       event = gdk_event_new (GDK_NOTHING);
       event->any.window = window;
       g_object_ref (window);
+
       if (_gdk_input_other_event (event, msg, window))
 	append_event (event);
       else
 	gdk_event_free (event);
+
       break;
     }
 
@@ -3519,11 +3569,15 @@
   GDK_THREADS_ENTER ();
 
   if (event_poll_fd.revents & G_IO_IN)
-    retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
-	      (modal_win32_dialog == NULL &&
-	       PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE)));
+    {
+      retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
+		(modal_win32_dialog == NULL &&
+		 PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE)));
+    }
   else
-    retval = FALSE;
+    {
+      retval = FALSE;
+    }
 
   GDK_THREADS_LEAVE ();
 
@@ -3561,6 +3615,13 @@
   modal_win32_dialog = window;
 }
 
+static gboolean
+is_modally_blocked (GdkWindow *window)
+{
+  GdkWindow *modal_current = _gdk_modal_current ();
+  return modal_current != NULL ? gdk_window_get_toplevel (window) != modal_current : FALSE;
+}
+
 static void
 check_for_too_much_data (GdkEvent *event)
 {
@@ -3568,7 +3629,9 @@
       event->client.data.l[2] ||
       event->client.data.l[3] ||
       event->client.data.l[4])
-    g_warning ("Only four bytes of data are passed in client messages on Win32\n");
+    {
+      g_warning ("Only four bytes of data are passed in client messages on Win32\n");
+    }
 }
 
 gboolean

Modified: branches/gtk-2-12/gdk/win32/gdkprivate-win32.h
==============================================================================
--- branches/gtk-2-12/gdk/win32/gdkprivate-win32.h	(original)
+++ branches/gtk-2-12/gdk/win32/gdkprivate-win32.h	Tue Feb 12 21:29:57 2008
@@ -276,6 +276,11 @@
 							   void *),
 				   void          *arg);
 
+void       _gdk_push_modal_window   (GdkWindow *window);
+void       _gdk_remove_modal_window (GdkWindow *window);
+GdkWindow *_gdk_modal_current       ();
+
+
 #ifdef G_ENABLE_DEBUG
 gchar *_gdk_win32_color_to_string      (const GdkColor *color);
 void   _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,

Modified: branches/gtk-2-12/gdk/win32/gdkwin32.h
==============================================================================
--- branches/gtk-2-12/gdk/win32/gdkwin32.h	(original)
+++ branches/gtk-2-12/gdk/win32/gdkwin32.h	Tue Feb 12 21:29:57 2008
@@ -85,7 +85,7 @@
 					       GdkAtom    *targets);
 
 /* For internal GTK use only */
-GdkPixbuf *   gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon);
+GdkPixbuf    *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon);
 HICON         gdk_win32_pixbuf_to_hicon_libgtk_only (GdkPixbuf *pixbuf);
 void          gdk_win32_set_modal_dialog_libgtk_only (HWND window);
 

Modified: branches/gtk-2-12/gdk/win32/gdkwindow-win32.c
==============================================================================
--- branches/gtk-2-12/gdk/win32/gdkwindow-win32.c	(original)
+++ branches/gtk-2-12/gdk/win32/gdkwindow-win32.c	Tue Feb 12 21:29:57 2008
@@ -51,6 +51,7 @@
 static void gdk_window_impl_win32_finalize   (GObject                 *object);
 
 static gpointer parent_class = NULL;
+static GSList *modal_window_stack = NULL;
 
 static void     update_style_bits         (GdkWindow *window);
 static gboolean _gdk_window_get_functions (GdkWindow     *window,
@@ -154,14 +155,17 @@
     {
       if (GetCursor () == window_impl->hcursor)
 	SetCursor (NULL);
+
       GDI_CALL (DestroyCursor, (window_impl->hcursor));
       window_impl->hcursor = NULL;
     }
+
   if (window_impl->hicon_big != NULL)
     {
       GDI_CALL (DestroyIcon, (window_impl->hicon_big));
       window_impl->hicon_big = NULL;
     }
+
   if (window_impl->hicon_small != NULL)
     {
       GDI_CALL (DestroyIcon, (window_impl->hicon_small));
@@ -338,6 +342,7 @@
   wcl.hInstance = _gdk_app_hmodule;
   wcl.hIcon = 0;
   wcl.hIconSm = 0;
+
   /* initialize once! */
   if (0 == hAppIcon && 0 == hAppIconSm)
     {
@@ -346,12 +351,16 @@
       if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
         {
           ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+
           if (0 == hAppIcon && 0 == hAppIconSm)
             {
               if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
-                ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+		{
+		  ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+		}
             }
         }
+
       if (0 == hAppIcon && 0 == hAppIconSm)
         {
           hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
@@ -362,6 +371,7 @@
                                   GetSystemMetrics (SM_CYSMICON), 0);
         }
     }
+
   if (0 == hAppIcon)
     hAppIcon = hAppIconSm;
   else if (0 == hAppIconSm)
@@ -844,6 +854,9 @@
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
+  /* Remove ourself from the modal stack */
+  _gdk_remove_modal_window (window);
+
   /* Remove all our transient children */
   tmp = window_impl->transient_children;
   while (tmp != NULL)
@@ -1775,7 +1788,9 @@
     
   if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
       ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
-    return FALSE;
+    {
+      return FALSE;
+    }
 
   if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
       (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
@@ -1783,12 +1798,17 @@
       impl->hints.min_height == impl->hints.max_height)
     {
       *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
+
       if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
 	  impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
 	  impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
-	*decoration |= GDK_DECOR_MINIMIZE;
+	{
+	  *decoration |= GDK_DECOR_MINIMIZE;
+	}
       else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
-	*decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
+	{
+	  *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
+	}
 
       return TRUE;
     }
@@ -1798,7 +1818,10 @@
       if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
 	  impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
 	  impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
-	*decoration |= GDK_DECOR_MINIMIZE;
+	{
+	  *decoration |= GDK_DECOR_MINIMIZE;
+	}
+
       return TRUE;
     }
   else
@@ -2013,6 +2036,52 @@
 }
 
 void
+_gdk_push_modal_window (GdkWindow *window)
+{
+  modal_window_stack = g_slist_prepend (modal_window_stack,
+                                        window);
+}
+
+void
+_gdk_remove_modal_window (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+
+  /* It's possible to be NULL here if someone sets the modal hint of the window
+   * to FALSE before a modal window stack has ever been created. */
+  if (modal_window_stack == NULL)
+    return;
+
+  /* Find the requested window in the stack and remove it.  Yeah, I realize this
+   * means we're not a 'real stack', strictly speaking.  Sue me. :) */
+  GSList *tmp = g_slist_find (modal_window_stack, window);
+  if (tmp != NULL)
+    {
+      modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
+    }
+}
+
+GdkWindow *
+_gdk_modal_current ()
+{
+  if (modal_window_stack != NULL)
+    {
+      GSList *tmp = modal_window_stack;
+
+      while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
+	{
+	  tmp = g_slist_next (tmp);
+	}
+
+      return tmp != NULL ? tmp->data : NULL;
+    }
+  else
+    {
+      return NULL;
+    }
+}
+
+void
 gdk_window_set_background (GdkWindow      *window,
 			   const GdkColor *color)
 {
@@ -3470,13 +3539,20 @@
 
   private->modal_hint = modal;
 
-#if 1
+#if 0
   /* Not sure about this one.. -- Cody */
   if (GDK_WINDOW_IS_MAPPED (window))
     API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
 			     modal ? HWND_TOPMOST : HWND_NOTOPMOST,
 			     0, 0, 0, 0,
 			     SWP_NOMOVE | SWP_NOSIZE));
+#else
+
+  if (modal)
+    _gdk_push_modal_window (window);
+  else
+    _gdk_remove_modal_window (window);
+
 #endif
 }
 

Modified: branches/gtk-2-12/gdk/win32/gdkwindow-win32.h
==============================================================================
--- branches/gtk-2-12/gdk/win32/gdkwindow-win32.h	(original)
+++ branches/gtk-2-12/gdk/win32/gdkwindow-win32.h	Tue Feb 12 21:29:57 2008
@@ -96,7 +96,6 @@
 struct _GdkWindowImplWin32Class 
 {
   GdkDrawableImplWin32Class parent_class;
-
 };
 
 GType _gdk_window_impl_win32_get_type (void);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]