]> Pileus Git - ~andy/gtk/commitdiff
add g_return_if_fail for monitor number <= 0
authorHavoc Pennington <hp@redhat.com>
Thu, 17 Oct 2002 20:24:03 +0000 (20:24 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Thu, 17 Oct 2002 20:24:03 +0000 (20:24 +0000)
2002-10-16  Havoc Pennington  <hp@redhat.com>

* gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
g_return_if_fail for monitor number <= 0

* gtk/gtkmenu.c (gtk_menu_position): handle case where pointer
is outside the screen.

* gtk/gtkwindow.c (get_monitor_center): factor out
the code to position a window in center
(gtk_window_compute_configure_request): use here
(gtk_window_constrain_position): use here, the
code here wasn't multihead-aware

* gdk/x11/gdkevents-x11.c (get_real_window): function to
return the window the event describes, rather than the window
that received the event.
(gdk_event_translate): use result of that function for
filling in GdkEvent::window, which only matters for
MapNotify/UnmapNotify and ConfigureNotify, in practice.

Unbreaks various things using SubstructureNotifyMask.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/x11/gdkevents-x11.c
gdk/x11/gdkscreen-x11.c
gtk/gtkmenu.c
gtk/gtkwindow.c

index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 33336e8378d3e0b743d62173064661661cc671b8..b8f9ebb9d8ec8e8f2949b8fa8596dd162fb2e283 100644 (file)
@@ -1,3 +1,26 @@
+2002-10-16  Havoc Pennington  <hp@redhat.com>
+
+       * gdk/x11/gdkscreen-x11.c (gdk_screen_get_monitor_geometry): add
+       g_return_if_fail for monitor number <= 0
+
+       * gtk/gtkmenu.c (gtk_menu_position): handle case where pointer 
+       is outside the screen.
+
+       * gtk/gtkwindow.c (get_monitor_center): factor out 
+       the code to position a window in center
+       (gtk_window_compute_configure_request): use here
+       (gtk_window_constrain_position): use here, the 
+       code here wasn't multihead-aware
+
+       * gdk/x11/gdkevents-x11.c (get_real_window): function to
+       return the window the event describes, rather than the window
+       that received the event.
+       (gdk_event_translate): use result of that function for 
+       filling in GdkEvent::window, which only matters for 
+       MapNotify/UnmapNotify and ConfigureNotify, in practice.
+
+       Unbreaks various things using SubstructureNotifyMask.
+
 Thu Oct 17 16:13:28 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkcheckbutton.c gtk/gtkradiobutton.c: Make
index 19fa6c9130d5b34a97feee9360efe16a7dcabffc..e8bedf9e366b5d44fd0c2303e2744c5f2d4e377c 100644 (file)
@@ -512,6 +512,53 @@ set_screen_from_root (GdkDisplay *display,
   gdk_event_set_screen (event, screen);
 }
 
+/* Return the window this has to do with, if any, rather
+ * than the frame or root window that was selecting
+ * for substructure
+ */
+static Window
+get_real_window (XEvent *event)
+{
+  switch (event->type)
+    {      
+    case CreateNotify:
+      return event->xcreatewindow.window;
+      
+    case DestroyNotify:
+      return event->xdestroywindow.window;
+
+    case UnmapNotify:
+      return event->xunmap.window;
+
+    case MapNotify:
+      return event->xmap.window;
+
+    case MapRequest:
+      return event->xmaprequest.window;
+
+    case ReparentNotify:
+     return event->xreparent.window;
+      
+    case ConfigureNotify:
+      return event->xconfigure.window;
+      
+    case ConfigureRequest:
+      return event->xconfigurerequest.window;
+
+    case GravityNotify:
+      return event->xgravity.window;
+
+    case CirculateNotify:
+      return event->xcirculate.window;
+
+    case CirculateRequest:
+      return event->xcirculaterequest.window;
+
+    default:
+      return event->xany.window;
+    }
+}
+
 static gboolean
 gdk_event_translate (GdkDisplay *display,
                     GdkEvent   *event,
@@ -531,6 +578,7 @@ gdk_event_translate (GdkDisplay *display,
   GdkScreen *screen = NULL;
   GdkScreenX11 *screen_x11 = NULL;
   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+  Window xwindow;
   
   return_val = FALSE;
 
@@ -569,9 +617,13 @@ gdk_event_translate (GdkDisplay *display,
        return_val = FALSE;
     }
 
-  /* Find the GdkWindow that this event occurred in. */
+  /* Find the GdkWindow that this event relates to.
+   * Basically this means substructure events
+   * are reported same as structure events
+   */
+  xwindow = get_real_window (xevent);
   
-  window = gdk_window_lookup_for_display (display, xevent->xany.window);
+  window = gdk_window_lookup_for_display (display, xwindow);
   window_private = (GdkWindowObject *) window;
 
   if (window)
@@ -590,16 +642,18 @@ gdk_event_translate (GdkDisplay *display,
       if (GDK_IS_WINDOW (window))
         {
           window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
-         
-          if (xevent->xany.window != GDK_WINDOW_XID (window))
+
+          /* Move key events on focus window to the real toplevel, and
+           * filter out all other events on focus window
+           */          
+          if (xwindow == window_impl->focus_window)
             {
-              g_assert (xevent->xany.window == window_impl->focus_window);
-              
               switch (xevent->type)
                 {
                 case KeyPress:
                 case KeyRelease:
-                  xevent->xany.window = GDK_WINDOW_XID (window);
+                  xwindow = GDK_WINDOW_XID (window);
+                  xevent->xany.window = xwindow;
                   break;
                 default:
                   return FALSE;
@@ -636,7 +690,7 @@ gdk_event_translate (GdkDisplay *display,
     }
       
   if (screen_x11 && screen_x11->wmspec_check_window != None &&
-      xevent->xany.window == screen_x11->wmspec_check_window)
+      xwindow == screen_x11->wmspec_check_window)
     {
       if (xevent->type == DestroyNotify)
         {
index 0cf0529c19473fcd7053447ec9261629a831dd9e..98a60a7fd094666f183a2d3ff9ddfd13b5440ca1 100644 (file)
@@ -330,6 +330,7 @@ gdk_screen_get_monitor_geometry (GdkScreen    *screen,
 {
   g_return_if_fail (GDK_IS_SCREEN (screen));
   g_return_if_fail (monitor_num < GDK_SCREEN_X11 (screen)->num_monitors);
+  g_return_if_fail (monitor_num >= 0);
 
   *dest = GDK_SCREEN_X11 (screen)->monitors[monitor_num];
 }
index f9f8d152c5b280565597bd37b7a5877e53446103..4d93eccfa233d2108b5704bda4f592f538a331dc 100644 (file)
@@ -2422,6 +2422,8 @@ gtk_menu_position (GtkMenu *menu)
 
   screen = gtk_widget_get_screen (widget);
   monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
+  if (monitor_num < 0)
+    monitor_num = 0;
   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
 
   /* We need the requisition to figure out the right place to
index de05e34f358b9ad7032c73641b9b312f7d7d9c5b..b2462c769edee6ee6d41f5200d437fd83f6a1ba1 100644 (file)
@@ -4419,6 +4419,89 @@ get_effective_position (GtkWindow *window)
   return pos;
 }
 
+static int
+get_center_monitor_of_window (GtkWindow *window)
+{
+  /* We could try to sort out the relative positions of the monitors and
+   * stuff, or we could just be losers and assume you have a row
+   * or column of monitors.
+   */
+  return gdk_screen_get_n_monitors (window->screen)) / 2;
+}
+
+static int
+get_monitor_containing_pointer (GtkWindow *window)
+{
+  gint px, py;
+  gint monitor_num;
+  GdkScreen *pointer_screen;
+
+  gdk_display_get_pointer (gdk_screen_get_display (window->screen),
+                           &pointer_screen,
+                           &px, &py, NULL);
+
+  if (pointer_screen == window->screen)
+    monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
+  else
+    monitor_num = -1;
+
+  return monitor_num;
+}
+
+static void
+center_window_on_monitor (GtkWindow *window,
+                          gint       w,
+                          gint       h,
+                          gint      *x,
+                          gint      *y)
+{
+  GdkRectangle monitor;
+  int monitor_num;
+
+  monitor_num = get_monitor_containing_pointer (window);
+  
+  if (monitor_num == -1)
+    monitor_num = get_center_monitor_of_window (window);
+  
+  gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+  
+  *x = (monitor.width - w) / 2 + monitor.x;
+  *y = (monitor.height - h) / 2 + monitor.y;
+
+  /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
+   * and WM decorations.
+   */
+  if (*x < monitor.x)
+    *x = monitor.x;
+  if (*y < monitor.y)
+    *y = monitor.y;
+}
+
+static void
+clamp_window_to_rectangle (gint               *x,
+                           gint               *y,
+                           gint                w,
+                           gint                h,
+                           const GdkRectangle *rect)
+{
+  gint outside_w, outside_h;
+  
+  outside_w = (*x + w) - (rect->x + rect->width);
+  if (outside_w > 0)
+    *x -= outside_w;
+
+  outside_h = (y + h) - (rect->y + rect->height);
+  if (outside_h > 0)
+    *y -= outside_h; 
+
+  /* if larger than the screen, center on the screen. */
+  if (*x < rect->x)
+    *x += (rect->x - *x) / 2;
+  if (*y < rect->y)
+    *y += (rect->y - *y) / 2;
+}
+
+
 static void
 gtk_window_compute_configure_request (GtkWindow    *window,
                                       GdkRectangle *request,
@@ -4471,35 +4554,39 @@ gtk_window_compute_configure_request (GtkWindow    *window,
            */
         case GTK_WIN_POS_CENTER_ALWAYS:
         case GTK_WIN_POS_CENTER:
-          {
-           gint px, py, monitor_num;
-           GdkRectangle monitor;
-
-           gdk_window_get_pointer (gdk_screen_get_root_window (window->screen),
-                                   &px, &py, NULL);
-           
-           monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
-           if (monitor_num == -1)
-             monitor_num = 0;
-           
-           gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
-           
-           x = (monitor.width - w) / 2 + monitor.x;
-           y = (monitor.height - h) / 2 + monitor.y;
-          }
+          center_window_on_monitor (window, w, h, &x, &y);
           break;
       
         case GTK_WIN_POS_CENTER_ON_PARENT:
           {
+            gint monitor_num;
+            GdkRectangle monitor;
+            gint offscreen_w, offscreen_h;
             gint ox, oy;
             
             g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
+
+            if (parent_widget->window != NULL)
+              monitor_num = gdk_screen_get_monitor_at_window (window->screen,
+                                                              parent_widget->window);
+            else
+              monitor_num = -1;
             
             gdk_window_get_origin (parent_widget->window,
                                    &ox, &oy);
             
             x = ox + (parent_widget->allocation.width - w) / 2;
             y = oy + (parent_widget->allocation.height - h) / 2;
+            
+            /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
+             * WM decorations. If parent wasn't on a monitor, just
+             * give up.
+             */
+            if (monitor_num >= 0)
+              {
+                gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+                clamp_window_to_rectangle (&x, &y, w, h, &monitor);
+              }
           }
           break;
 
@@ -4507,14 +4594,35 @@ gtk_window_compute_configure_request (GtkWindow    *window,
           {
             gint screen_width = gdk_screen_get_width (window->screen);
             gint screen_height = gdk_screen_get_height (window->screen);
-            int px, py;
+           gint monitor_num;
+           GdkRectangle monitor;
+            gint offscreen_w, offscreen_h;
+            GdkScreen *pointer_screen;
+            gint px, py;
+            
+            gdk_display_get_pointer (gdk_screen_get_display (window->screen),
+                                     &pointer_screen,
+                                     &px, &py, NULL);
+
+            if (pointer_screen == window->screen)
+              monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py);
+            else
+              monitor_num = -1;
             
-            gdk_window_get_pointer (gdk_screen_get_root_window (window->screen),
-                                   &px, &py, NULL);
             x = px - w / 2;
             y = py - h / 2;
             x = CLAMP (x, 0, screen_width - w);
             y = CLAMP (y, 0, screen_height - h);
+
+            /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
+             * WM decorations. Don't try to figure out what's going
+             * on if the mouse wasn't inside a monitor.
+             */
+            if (monitor_num >= 0)
+              {
+                gdk_screen_get_monitor_geometry (window->screen, monitor_num, &monitor);
+                clamp_window_to_rectangle (&x, &y, w, h, &monitor);
+              }
           }
           break;
 
@@ -4555,11 +4663,8 @@ gtk_window_constrain_position (GtkWindow    *window,
   if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
     {
       gint center_x, center_y;
-      gint screen_width = gdk_screen_get_width (window->screen);
-      gint screen_height = gdk_screen_get_height (window->screen);
-      
-      center_x = (screen_width - new_width) / 2;
-      center_y = (screen_height - new_height) / 2;
+
+      center_window_on_monitor (window, new_width, new_height, &center_x, &center_y);
       
       *x = center_x;
       *y = center_y;