comparison gtk/dw.c @ 1469:b9efb744cfbd

Second try and window positioning for GTK2 and port to GTK3. Added dw_window_set_gravity() for GTK3. Switched to requesting the frame extents property directly from the window manager if the window isn't mapped... if the property isn't supported guess using the old values we had been using.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 20 Dec 2011 12:44:41 +0000
parents b2235efd9914
children a317c2ec1d4c
comparison
equal deleted inserted replaced
1468:b2235efd9914 1469:b9efb744cfbd
10103 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 10103 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
10104 { 10104 {
10105 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); 10105 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
10106 } 10106 }
10107 10107
10108 union extents_union { guchar **gu_extents; unsigned long **extents; };
10109 static Atom extents_atom = 0;
10110
10111 static Bool property_notify_predicate(Display *xdisplay, XEvent *event, XPointer window_id)
10112 {
10113 unsigned long *window = (unsigned long *)window_id;
10114
10115 if(event->xany.type == PropertyNotify && event->xany.window == *window && event->xproperty.atom == extents_atom)
10116 return True;
10117 return False;
10118 }
10119
10120 /* Internal function to figure out the frame extents of an unmapped window */
10121 void _dw_get_frame_extents(GtkWidget *window, int *vert, int *horz)
10122 {
10123 const char *request = "_NET_REQUEST_FRAME_EXTENTS";
10124 unsigned long *extents = NULL;
10125 union extents_union eu;
10126 GdkAtom request_extents = gdk_atom_intern(request, FALSE);
10127
10128 /* Set some rational defaults.. just in case */
10129 *vert = 28;
10130 *horz = 12;
10131
10132 /* See if the current window manager supports _NET_REQUEST_FRAME_EXTENTS */
10133 if(gdk_net_wm_supports(request_extents))
10134 {
10135 GdkDisplay *display = gtk_widget_get_display(window);
10136 Display *xdisplay = GDK_DISPLAY_XDISPLAY(display);
10137 GdkWindow *root_window = gdk_get_default_root_window();
10138 Window xroot_window = GDK_WINDOW_XID(root_window);
10139 Atom extents_request_atom = gdk_x11_get_xatom_by_name_for_display(display, request);
10140 unsigned long window_id = GDK_WINDOW_XID(GDK_DRAWABLE(window->window));
10141 XEvent notify_xevent, xevent = {0};
10142
10143 if(!extents_atom)
10144 {
10145 const char *extents_name = "_NET_FRAME_EXTENTS";
10146 extents_atom = gdk_x11_get_xatom_by_name_for_display(display, extents_name);
10147 }
10148
10149 xevent.xclient.type = ClientMessage;
10150 xevent.xclient.message_type = extents_request_atom;
10151 xevent.xclient.display = xdisplay;
10152 xevent.xclient.window = window_id;
10153 xevent.xclient.format = 32;
10154
10155 XSendEvent(xdisplay, xroot_window, False,
10156 (SubstructureRedirectMask | SubstructureNotifyMask),
10157 &xevent);
10158
10159 XIfEvent(xdisplay, &notify_xevent, property_notify_predicate, (XPointer)&window_id);
10160 }
10161
10162 /* Attempt to retrieve window's frame extents. */
10163 eu.extents = &extents;
10164 if(gdk_property_get(window->window,
10165 gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE),
10166 gdk_atom_intern("CARDINAL", FALSE),
10167 0, sizeof(unsigned long)*4, FALSE,
10168 NULL, NULL, NULL, eu.gu_extents))
10169 {
10170 *horz = extents[0] + extents[1];
10171 *vert = extents[2] + extents[3];
10172 }
10173 }
10174
10108 /* 10175 /*
10109 * Sets the size of a given window (widget). 10176 * Sets the size of a given window (widget).
10110 * Parameters: 10177 * Parameters:
10111 * handle: Window (widget) handle. 10178 * handle: Window (widget) handle.
10112 * width: New width in pixels. 10179 * width: New width in pixels.
10113 * height: New height in pixels. 10180 * height: New height in pixels.
10114 */ 10181 */
10115 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height) 10182 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height)
10116 { 10183 {
10117 int _locked_by_me = FALSE; 10184 int _locked_by_me = FALSE;
10118 int cx = 0, cy = 0;
10119 10185
10120 if(!handle) 10186 if(!handle)
10121 return; 10187 return;
10122 10188
10123 DW_MUTEX_LOCK; 10189 DW_MUTEX_LOCK;
10124 if(GTK_IS_WINDOW(handle)) 10190 if(GTK_IS_WINDOW(handle))
10125 { 10191 {
10192 int cx = 0, cy = 0;
10193
10126 #ifdef GDK_WINDOWING_X11 10194 #ifdef GDK_WINDOWING_X11
10127 _size_allocate(GTK_WINDOW(handle)); 10195 _size_allocate(GTK_WINDOW(handle));
10128 #endif 10196 #endif
10129 /* If the window is realized */ 10197 /* If the window is mapped */
10130 if(handle->window && gdk_window_is_visible(handle->window)) 10198 if(handle->window && GTK_WIDGET_MAPPED(handle))
10131 { 10199 {
10132 #if GTK_MAJOR_VERSION > 1 10200 #if GTK_MAJOR_VERSION > 1
10133 GdkRectangle frame; 10201 GdkRectangle frame;
10134 gint gwidth, gheight; 10202 gint gwidth, gheight;
10135 10203
10142 cx = 0; 10210 cx = 0;
10143 cy = frame.height - gheight; 10211 cy = frame.height - gheight;
10144 if(cy < 0) 10212 if(cy < 0)
10145 cy = 0; 10213 cy = 0;
10146 #endif 10214 #endif
10147 /* Resize minus the border size */ 10215 }
10148 gdk_window_resize(handle->window, width - cx , height - cy ); 10216 else
10149 } 10217 {
10150 if(!cx && !cy) 10218 /* Check if we have cached frame size values */
10151 { 10219 if(!((cx = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_frame_width"))) |
10220 (cy = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_frame_height")))))
10221 {
10222 /* If not try to ask the window manager for the estimated size...
10223 * and finally if all else fails, guess.
10224 */
10225 _dw_get_frame_extents(handle, &cy, &cx);
10226 /* Cache values for later use */
10227 gtk_object_set_data(GTK_OBJECT(handle), "_dw_frame_width", GINT_TO_POINTER(cx));
10228 gtk_object_set_data(GTK_OBJECT(handle), "_dw_frame_height", GINT_TO_POINTER(cy));
10229 }
10152 /* Save the size for when it is shown */ 10230 /* Save the size for when it is shown */
10153 gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", GINT_TO_POINTER(width)); 10231 gtk_object_set_data(GTK_OBJECT(handle), "_dw_width", GINT_TO_POINTER(width));
10154 gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", GINT_TO_POINTER(height)); 10232 gtk_object_set_data(GTK_OBJECT(handle), "_dw_height", GINT_TO_POINTER(height));
10155 } 10233 }
10234 /* Resize minus the border size */
10235 gdk_window_resize(handle->window, width - cx , height - cy );
10156 gtk_window_set_default_size(GTK_WINDOW(handle), width - cx, height - cy ); 10236 gtk_window_set_default_size(GTK_WINDOW(handle), width - cx, height - cy );
10157 } 10237 }
10158 else 10238 else
10159 gtk_widget_set_usize(handle, width, height); 10239 gtk_widget_set_usize(handle, width, height);
10160 DW_MUTEX_UNLOCK; 10240 DW_MUTEX_UNLOCK;
10261 gtk_mdi_move(GTK_MDI(mdi), handle, x, y); 10341 gtk_mdi_move(GTK_MDI(mdi), handle, x, y);
10262 } 10342 }
10263 else 10343 else
10264 #endif 10344 #endif
10265 { 10345 {
10266 GdkWindow *window = NULL;
10267
10268 if(GTK_IS_WINDOW(handle)) 10346 if(GTK_IS_WINDOW(handle))
10269 { 10347 {
10270 #if GTK_MAJOR_VERSION > 1 10348 #if GTK_MAJOR_VERSION > 1
10271 /* If the window is visible */ 10349 int horz = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_horz"));
10272 if(handle->window && gdk_window_is_visible(handle->window)) 10350 int vert = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_vert"));
10351 int newx = x, newy = y, width = 0, height = 0;
10352
10353 /* If the window is mapped */
10354 if(handle->window && GTK_WIDGET_MAPPED(handle))
10273 { 10355 {
10274 int horz = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_horz")); 10356 /* If we need the width or height... */
10275 int vert = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_grav_vert"));
10276 int newx = x, newy = y;
10277
10278 if(horz || vert) 10357 if(horz || vert)
10279 { 10358 {
10280 GdkRectangle frame; 10359 GdkRectangle frame;
10281 10360
10282 /* Get the frame size */ 10361 /* Get the frame size */
10283 gdk_window_get_frame_extents(handle->window, &frame); 10362 gdk_window_get_frame_extents(handle->window, &frame);
10284 10363 width = frame.width;
10285 /* Handle horizontal center gravity */ 10364 height = frame.height;
10286 if((horz & 0xf) == DW_GRAV_CENTER) 10365 }
10287 newx += ((gdk_screen_width() / 2) - (frame.width / 2));
10288 /* Handle right gravity */
10289 else if((horz & 0xf) == DW_GRAV_RIGHT)
10290 newx = gdk_screen_width() - frame.width - x;
10291 /* Handle vertical center gravity */
10292 if((vert & 0xf) == DW_GRAV_CENTER)
10293 newy += ((gdk_screen_height() / 2) - (frame.height / 2));
10294 else if((vert & 0xf) == DW_GRAV_BOTTOM)
10295 newy = gdk_screen_height() - frame.height - x;
10296 }
10297 gtk_window_move(GTK_WINDOW(handle), newx, newy);
10298 } 10366 }
10299 else 10367 else
10300 { 10368 {
10369 int cx , cy;
10370
10371 /* Check if we have cached frame size values */
10372 if(!((cx = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_frame_width"))) |
10373 (cy = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_frame_height")))))
10374 {
10375 /* If not try to ask the window manager for the estimated size...
10376 * and finally if all else fails, guess.
10377 */
10378 _dw_get_frame_extents(handle, &cy, &cx);
10379 /* Cache values for later use */
10380 gtk_object_set_data(GTK_OBJECT(handle), "_dw_frame_width", GINT_TO_POINTER(cx));
10381 gtk_object_set_data(GTK_OBJECT(handle), "_dw_frame_height", GINT_TO_POINTER(cy));
10382 }
10301 /* Save the positions for when it is shown */ 10383 /* Save the positions for when it is shown */
10302 gtk_object_set_data(GTK_OBJECT(handle), "_dw_x", GINT_TO_POINTER(x)); 10384 gtk_object_set_data(GTK_OBJECT(handle), "_dw_x", GINT_TO_POINTER(x));
10303 gtk_object_set_data(GTK_OBJECT(handle), "_dw_y", GINT_TO_POINTER(y)); 10385 gtk_object_set_data(GTK_OBJECT(handle), "_dw_y", GINT_TO_POINTER(y));
10304 gtk_object_set_data(GTK_OBJECT(handle), "_dw_pos", GINT_TO_POINTER(1)); 10386 gtk_object_set_data(GTK_OBJECT(handle), "_dw_pos", GINT_TO_POINTER(1));
10387 /* Check to see if there is a pending size request too */
10388 width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_width"));
10389 height = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(handle), "_dw_height"));
10390 if(width | height)
10391 {
10392 /* Ask what GTK is planning on suggesting for the window size */
10393 gtk_window_get_size(GTK_WINDOW(handle), !width ? &width : NULL, !height ? &height : NULL);
10394 }
10395 /* Add the frame size to it */
10396 width += cx;
10397 height += cy;
10305 } 10398 }
10399 /* Do any gravity calculations */
10400 if(horz || vert)
10401 {
10402 /* Handle horizontal center gravity */
10403 if((horz & 0xf) == DW_GRAV_CENTER)
10404 newx += ((gdk_screen_width() / 2) - (width / 2));
10405 /* Handle right gravity */
10406 else if((horz & 0xf) == DW_GRAV_RIGHT)
10407 newx = gdk_screen_width() - width - x;
10408 /* Handle vertical center gravity */
10409 if((vert & 0xf) == DW_GRAV_CENTER)
10410 newy += ((gdk_screen_height() / 2) - (height / 2));
10411 else if((vert & 0xf) == DW_GRAV_BOTTOM)
10412 newy = gdk_screen_height() - height - x;
10413 }
10414 /* Finally move the window into place */
10415 gtk_window_move(GTK_WINDOW(handle), newx, newy);
10306 #else 10416 #else
10307 gtk_widget_set_uposition(handle, x, y); 10417 gtk_widget_set_uposition(handle, x, y);
10308 #endif 10418 #endif
10309 } 10419 }
10310 else if((window = gtk_widget_get_window(handle))) 10420 else if(handle->window)
10311 gdk_window_move(window, x, y); 10421 gdk_window_move(handle->window, x, y);
10312 } 10422 }
10313 DW_MUTEX_UNLOCK; 10423 DW_MUTEX_UNLOCK;
10314 } 10424 }
10315 10425
10316 /* 10426 /*