Mercurial > dwindows
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, ¬ify_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 /* |