changeset 1468:b2235efd9914

Rewrite of window position code for GTK2. DW_BORDER_WIDTH and DW_BORDER_HEIGHT are no longer needed, window decorations are now detected automatically. Initial implementation of dw_window_set_gravity().
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 19 Dec 2011 13:16:34 +0000
parents 91bdd9840b9f
children b9efb744cfbd
files dw.h gtk/dw.c
diffstat 2 files changed, 140 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Sun Dec 18 12:12:46 2011 +0000
+++ b/dw.h	Mon Dec 19 13:16:34 2011 +0000
@@ -57,6 +57,14 @@
 #define DW_MIS_CHECKED           (1 << 2)
 #define DW_MIS_UNCHECKED         (1 << 3)
 
+/* Gravity */
+#define DW_GRAV_TOP              0
+#define DW_GRAV_LEFT             0
+#define DW_GRAV_CENTER           1
+#define DW_GRAV_RIGHT            2
+#define DW_GRAV_BOTTOM           2
+#define DW_GRAV_OBSTACLES        (1 << 10)
+
 /* ensure we can build the Gtk port with MingW on Windows */
 #if defined(DW_USE_GTK) && defined(__MINGW32__)
 # ifndef GDK_WINDOWING_WIN32
@@ -1520,6 +1528,7 @@
 void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height);
 void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height);
 void API dw_window_get_preferred_size(HWND handle, int *width, int *height);
+void API dw_window_set_gravity(HWND handle, int horz, int vert);
 void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask);
 void API dw_window_set_icon(HWND handle, HICN icon);
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
--- a/gtk/dw.c	Sun Dec 18 12:12:46 2011 +0000
+++ b/gtk/dw.c	Mon Dec 19 13:16:34 2011 +0000
@@ -142,8 +142,6 @@
 #endif
 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0;
 static pthread_t _dw_thread = (pthread_t)-1;
-/* Use default border size for the default enlightenment theme */
-static int _dw_border_width = 12, _dw_border_height = 28;
 
 #define  DW_MUTEX_LOCK { if(pthread_self() != _dw_thread && !pthread_getspecific(_dw_mutex_key)) { gdk_threads_enter(); pthread_setspecific(_dw_mutex_key, (void *)1); _locked_by_me = TRUE; } }
 #define  DW_MUTEX_UNLOCK { if(pthread_self() != _dw_thread && _locked_by_me == TRUE) { gdk_threads_leave(); pthread_setspecific(_dw_mutex_key, NULL); _locked_by_me = FALSE; } }
@@ -346,7 +344,7 @@
 
    gint x;
    gint y;
-    gint width;
+   gint width;
    gint height;
 
    GtkMdiChildState state;
@@ -2088,7 +2086,6 @@
 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[])
 {
    int z;
-   char *tmp;
    char *fname;
    static char * test_xpm[] = {
       "1 1 1 1",
@@ -2149,13 +2146,6 @@
    for(z=0;z<16;z++)
       gdk_color_alloc(_dw_cmap, &_colors[z]);
 
-   tmp = getenv("DW_BORDER_WIDTH");
-   if(tmp)
-      _dw_border_width = atoi(tmp);
-   tmp = getenv("DW_BORDER_HEIGHT");
-   if(tmp)
-      _dw_border_height = atoi(tmp);
-
    pthread_key_create(&_dw_fg_color_key, NULL);
    pthread_key_create(&_dw_bg_color_key, NULL);
    pthread_key_create(&_dw_mutex_key, NULL);
@@ -2692,15 +2682,32 @@
          int width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_width"));
          int height = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_height"));
 
-         if (width && height)
+         /* If we had a size request before shown */
+         if (width || height)
          {
-            gtk_widget_set_usize(handle, width, height);
-            gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", GINT_TO_POINTER(0));
-            gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", GINT_TO_POINTER(0));
+            /* Call the size function again now that we are realized */
+            dw_window_set_size(handle, width, height);
+            /* Clear out the data so we don't do it again */
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", NULL);
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", NULL);
          }
 
+         /* If we had a position request before shown */
+         if (gtk_object_get_data(GTK_OBJECT(handle), "_dw_pos"))
+         {
+            int x = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_x"));
+            int y = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_y"));
+            
+            /* Call the position function again now that we are realized */
+            dw_window_set_pos(handle, x, y);
+            /* Clear out the data so we don't do it again */
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_pos", NULL);
+         }
+
+         /* Make sure it is the topmost window */
          gdk_window_raise(GTK_WIDGET(handle)->window);
          gdk_flush();
+         /* And visible */
          gdk_window_show(GTK_WIDGET(handle)->window);
          gdk_flush();
       }
@@ -3417,8 +3424,7 @@
       last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
       gtk_window_set_title(GTK_WINDOW(tmp), title);
-      if(!(flStyle & DW_FCF_SIZEBORDER))
-         gtk_window_set_policy(GTK_WINDOW(tmp), FALSE, FALSE, TRUE);
+      gtk_window_set_resizable(GTK_WINDOW(tmp), (flStyle & DW_FCF_SIZEBORDER) ? TRUE : FALSE);
 
       gtk_widget_realize(tmp);
 
@@ -3459,9 +3465,6 @@
       if(hwndOwner)
          gdk_window_reparent(GTK_WIDGET(tmp)->window, GTK_WIDGET(hwndOwner)->window, 0, 0);
 
-      if(flStyle & DW_FCF_SIZEBORDER)
-         gtk_object_set_data(GTK_OBJECT(tmp), "_dw_size", GINT_TO_POINTER(1));
-         
       gtk_table_attach(GTK_TABLE(table), box, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
       gtk_container_add(GTK_CONTAINER(tmp), table);
       gtk_object_set_data(GTK_OBJECT(tmp), "_dw_boxhandle", (gpointer)box);
@@ -10112,8 +10115,7 @@
 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height)
 {
    int _locked_by_me = FALSE;
-   long default_width = width - _dw_border_width;
-   long default_height = height - _dw_border_height;
+   int cx = 0, cy = 0;
 
    if(!handle)
       return;
@@ -10121,21 +10123,37 @@
    DW_MUTEX_LOCK;
    if(GTK_IS_WINDOW(handle))
    {
-      if ( width == 0 )
-         default_width = -1;
-      if ( height == 0 )
-         default_height = -1;
 #ifdef GDK_WINDOWING_X11
       _size_allocate(GTK_WINDOW(handle));
 #endif
-      if(handle->window)
-         gdk_window_resize(handle->window, default_width , default_height );
-      gtk_window_set_default_size(GTK_WINDOW(handle), default_width , default_height );
-      if(!gtk_object_get_data(GTK_OBJECT(handle), "_dw_size"))
-      {
-         gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", GINT_TO_POINTER(default_width) );
-         gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", GINT_TO_POINTER(default_height) );
-      }
+      /* If the window is realized */
+      if(handle->window && gdk_window_is_visible(handle->window))
+      {
+#if GTK_MAJOR_VERSION > 1
+         GdkRectangle frame;
+         gint gwidth, gheight;
+
+         /* Calculate the border size */
+         gdk_window_get_frame_extents(handle->window, &frame);
+         gdk_window_get_geometry(handle->window, NULL, NULL, &gwidth, &gheight, NULL);
+         
+         cx = frame.width - gwidth;
+         if(cx < 0)
+            cx = 0;
+         cy = frame.height - gheight;
+         if(cy < 0)
+            cy = 0;
+#endif
+         /* Resize minus the border size */
+         gdk_window_resize(handle->window, width - cx , height - cy );
+      }
+      if(!cx && !cy)
+      {
+         /* Save the size for when it is shown */
+         gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", GINT_TO_POINTER(width));
+         gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", GINT_TO_POINTER(height));
+      }
+      gtk_window_set_default_size(GTK_WINDOW(handle), width - cx, height - cy );
    }
    else
       gtk_widget_set_usize(handle, width, height);
@@ -10206,6 +10224,20 @@
 }
 
 /*
+ * Sets the gravity of a given window (widget).
+ * Gravity controls which corner of the screen and window the position is relative to.
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          horz: DW_GRAV_LEFT (default), DW_GRAV_RIGHT or DW_GRAV_CENTER.
+ *          vert: DW_GRAV_TOP (default), DW_GRAV_BOTTOM or DW_GRAV_CENTER.
+ */
+void API dw_window_set_gravity(HWND handle, int horz, int vert)
+{
+   dw_window_set_data(handle, "_dw_grav_horz", DW_INT_TO_POINTER(horz));
+   dw_window_set_data(handle, "_dw_grav_vert", DW_INT_TO_POINTER(vert));
+}
+
+/*
  * Sets the position of a given window (widget).
  * Parameters:
  *          handle: Window (widget) handle.
@@ -10236,7 +10268,41 @@
       if(GTK_IS_WINDOW(handle))
       {
 #if GTK_MAJOR_VERSION > 1
-         gtk_window_move(GTK_WINDOW(handle), x, y);
+         /* If the window is visible */
+         if(handle->window && gdk_window_is_visible(handle->window))
+         {
+            int horz = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_horz"));
+            int vert = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_vert"));
+            int newx = x, newy = y;
+
+            if(horz || vert)
+            {
+               GdkRectangle frame;
+
+               /* Get the frame size */
+               gdk_window_get_frame_extents(handle->window, &frame);
+
+               /* Handle horizontal center gravity */
+               if((horz & 0xf) == DW_GRAV_CENTER)
+                  newx += ((gdk_screen_width() / 2) - (frame.width / 2));
+               /* Handle right gravity */
+               else if((horz & 0xf) == DW_GRAV_RIGHT)
+                  newx = gdk_screen_width() - frame.width - x;
+               /* Handle vertical center gravity */
+               if((vert & 0xf) == DW_GRAV_CENTER)
+                  newy += ((gdk_screen_height() / 2) - (frame.height / 2));
+               else if((vert & 0xf) == DW_GRAV_BOTTOM)
+                  newy = gdk_screen_height() - frame.height - x;
+            }
+            gtk_window_move(GTK_WINDOW(handle), newx, newy);
+         }
+         else
+         {
+            /* Save the positions for when it is shown */
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_x", GINT_TO_POINTER(x));
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_y", GINT_TO_POINTER(y));
+            gtk_object_set_data(GTK_OBJECT(handle), "_dw_pos", GINT_TO_POINTER(1));
+         }
 #else
          gtk_widget_set_uposition(handle, x, y);
 #endif
@@ -10258,39 +10324,8 @@
  */
 void dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height)
 {
-   int _locked_by_me = FALSE;
-#if GTK_MAJOR_VERSION > 1
-   GtkWidget *mdi;
-#endif
-
-   if(!handle)
-      return;
-
-   DW_MUTEX_LOCK;
-#if GTK_MAJOR_VERSION > 1
-   if((mdi = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi))
-   {
-      gtk_mdi_move(GTK_MDI(mdi), handle, x, y);
-   }
-   else
-#endif
-   {
-      if(GTK_IS_WINDOW(handle))
-      {
-         dw_window_set_size(handle, width, height);
-#if GTK_MAJOR_VERSION > 1
-         gtk_window_move(GTK_WINDOW(handle), x, y);
-#else
-         gtk_widget_set_uposition(handle, x, y);
-#endif
-      }
-      else if(handle->window)
-      {
-         gdk_window_resize(handle->window, width, height);
-         gdk_window_move(handle->window, x, y);
-      }
-   }
-   DW_MUTEX_UNLOCK;
+   dw_window_set_size(handle, width, height);
+   dw_window_set_pos(handle, x, y);
 }
 
 /*
@@ -10305,49 +10340,56 @@
 void dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height)
 {
    int _locked_by_me = FALSE;
-   gint gx, gy, gwidth, gheight, gdepth;
+   gint gx = 0, gy = 0, gwidth = 0, gheight = 0;
 #if GTK_MAJOR_VERSION > 1
    GtkWidget *mdi;
 #endif
 
    DW_MUTEX_LOCK;
 #if GTK_MAJOR_VERSION > 1
+   /* If it is an MDI window query what we can */
    if((mdi = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi))
    {
-      gint myx=0, myy=0;
-
-      gtk_mdi_get_pos(GTK_MDI(mdi), handle, &myx, &myy);
-      *x = myx;
-      *y = myy;
+      gtk_mdi_get_pos(GTK_MDI(mdi), handle, &gx, &gy);
    }
    else
 #endif
    {
+      /* Can only query if the window is realized */
       if(handle && handle->window)
       {
-
-         gdk_window_get_geometry(handle->window, &gx, &gy, &gwidth, &gheight, &gdepth);
-         gdk_window_get_root_origin(handle->window, &gx, &gy);
-         if(x)
-            *x = gx;
-         if(y)
-            *y = gy;
+         /* If it is a toplevel window */
          if(GTK_IS_WINDOW(handle))
          {
-            if(width)
-               *width = gwidth + _dw_border_width;
-            if(height)
-               *height = gheight + _dw_border_height;
+            if(handle->window && gdk_window_is_visible(handle->window))
+            {
+               GdkRectangle frame;
+
+               /* Calculate the border rectangle */
+               gdk_window_get_frame_extents(handle->window, &frame);
+               gx = frame.x;
+               gy = frame.y;
+               gwidth = frame.width;
+               gheight = frame.height;
+            }
          }
          else
          {
-            if(width)
-               *width = gwidth;
-            if(height)
-               *height = gheight;
+            /* Get an individual widget coordinates */
+            gdk_window_get_geometry(handle->window, &gx, &gy, &gwidth, &gheight, NULL);
+            gdk_window_get_root_origin(handle->window, &gx, &gy);
          }
       }
    }
+   /* Fill in the requested fields */
+   if(x)
+      *x = gx;
+   if(y)
+      *y = gy;
+   if(width)
+      *width = gwidth;
+   if(height)
+      *height = gheight;
    DW_MUTEX_UNLOCK;
 }