comparison gtk3/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 77f530f95826
children a317c2ec1d4c
comparison
equal deleted inserted replaced
1468:b2235efd9914 1469:b9efb744cfbd
106 106
107 GtkWidget *last_window = NULL, *popup = NULL; 107 GtkWidget *last_window = NULL, *popup = NULL;
108 108
109 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0; 109 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0;
110 static pthread_t _dw_thread = (pthread_t)-1; 110 static pthread_t _dw_thread = (pthread_t)-1;
111 /* Use default border size for the default enlightenment theme */
112 static int _dw_border_width = 12, _dw_border_height = 28;
113 111
114 #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; } } 112 #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; } }
115 #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; } } 113 #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; } }
116 114
117 #define DEFAULT_SIZE_WIDTH 12 115 #define DEFAULT_SIZE_WIDTH 12
268 GtkWidget *child; 266 GtkWidget *child;
269 GtkMdi *mdi; 267 GtkMdi *mdi;
270 268
271 gint x; 269 gint x;
272 gint y; 270 gint y;
273 gint width; 271 gint width;
274 gint height; 272 gint height;
275 273
276 GtkMdiChildState state; 274 GtkMdiChildState state;
277 }; 275 };
278 276
1796 * newthread: True if this is the only thread. 1794 * newthread: True if this is the only thread.
1797 * False if there is already a message loop running. 1795 * False if there is already a message loop running.
1798 */ 1796 */
1799 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]) 1797 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[])
1800 { 1798 {
1801 char *tmp;
1802
1803 if(res) 1799 if(res)
1804 { 1800 {
1805 _resources.resource_max = res->resource_max; 1801 _resources.resource_max = res->resource_max;
1806 _resources.resource_id = res->resource_id; 1802 _resources.resource_id = res->resource_id;
1807 _resources.resource_data = res->resource_data; 1803 _resources.resource_data = res->resource_data;
1841 g_thread_init(NULL); 1837 g_thread_init(NULL);
1842 #endif 1838 #endif
1843 gdk_threads_init(); 1839 gdk_threads_init();
1844 1840
1845 gtk_init(argc, argv); 1841 gtk_init(argc, argv);
1846
1847 tmp = getenv("DW_BORDER_WIDTH");
1848 if(tmp)
1849 _dw_border_width = atoi(tmp);
1850 tmp = getenv("DW_BORDER_HEIGHT");
1851 if(tmp)
1852 _dw_border_height = atoi(tmp);
1853 1842
1854 pthread_key_create(&_dw_fg_color_key, NULL); 1843 pthread_key_create(&_dw_fg_color_key, NULL);
1855 pthread_key_create(&_dw_bg_color_key, NULL); 1844 pthread_key_create(&_dw_bg_color_key, NULL);
1856 pthread_key_create(&_dw_mutex_key, NULL); 1845 pthread_key_create(&_dw_mutex_key, NULL);
1857 1846
2304 { 2293 {
2305 gtk_mdi_set_state(GTK_MDI(mdi), handle, CHILD_NORMAL); 2294 gtk_mdi_set_state(GTK_MDI(mdi), handle, CHILD_NORMAL);
2306 } 2295 }
2307 else 2296 else
2308 { 2297 {
2309 if (gtk_widget_get_window(GTK_WIDGET(handle))) 2298 GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(handle));
2299 if (window && gtk_widget_get_mapped(handle))
2310 { 2300 {
2311 int width = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_width")); 2301 int width = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_width"));
2312 int height = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_height")); 2302 int height = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_height"));
2313 2303
2314 if (width && height) 2304 /* If we had a size request before shown */
2305 if (width || height)
2315 { 2306 {
2316 gtk_widget_set_size_request(handle, width, height); 2307 /* Call the size function again now that we are realized */
2317 g_object_set_data(G_OBJECT(handle), "_dw_width", GINT_TO_POINTER(0)); 2308 dw_window_set_size(handle, width, height);
2318 g_object_set_data(G_OBJECT(handle), "_dw_height", GINT_TO_POINTER(0)); 2309 /* Clear out the data so we don't do it again */
2310 g_object_set_data(G_OBJECT(handle), "_dw_width", NULL);
2311 g_object_set_data(G_OBJECT(handle), "_dw_height", NULL);
2319 } 2312 }
2320 2313
2321 gdk_window_raise(gtk_widget_get_window(GTK_WIDGET(handle))); 2314 /* If we had a position request before shown */
2315 if (g_object_get_data(G_OBJECT(handle), "_dw_pos"))
2316 {
2317 int x = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_x"));
2318 int y = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_y"));
2319
2320 /* Call the position function again now that we are realized */
2321 dw_window_set_pos(handle, x, y);
2322 /* Clear out the data so we don't do it again */
2323 g_object_set_data(G_OBJECT(handle), "_dw_pos", NULL);
2324 }
2325
2326 gdk_window_raise(window);
2322 gdk_flush(); 2327 gdk_flush();
2323 gdk_window_show(gtk_widget_get_window(GTK_WIDGET(handle))); 2328 gdk_window_show(window);
2324 gdk_flush(); 2329 gdk_flush();
2325 } 2330 }
2326 defaultitem = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_defaultitem"); 2331 defaultitem = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_defaultitem");
2327 if (defaultitem) 2332 if (defaultitem)
2328 gtk_widget_grab_focus(defaultitem); 2333 gtk_widget_grab_focus(defaultitem);
2902 gtk_widget_show_all(grid); 2907 gtk_widget_show_all(grid);
2903 2908
2904 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL); 2909 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2905 2910
2906 gtk_window_set_title(GTK_WINDOW(tmp), title); 2911 gtk_window_set_title(GTK_WINDOW(tmp), title);
2907 if(!(flStyle & DW_FCF_SIZEBORDER)) 2912 gtk_window_set_resizable(GTK_WINDOW(tmp), (flStyle & DW_FCF_SIZEBORDER) ? TRUE : FALSE);
2908 gtk_window_set_resizable(GTK_WINDOW(tmp), FALSE);
2909 2913
2910 gtk_widget_realize(tmp); 2914 gtk_widget_realize(tmp);
2911 2915
2912 if(flStyle & DW_FCF_TITLEBAR) 2916 if(flStyle & DW_FCF_TITLEBAR)
2913 flags |= GDK_DECOR_TITLE; 2917 flags |= GDK_DECOR_TITLE;
8502 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 8506 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
8503 { 8507 {
8504 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); 8508 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
8505 } 8509 }
8506 8510
8511
8512 union extents_union { guchar **gu_extents; unsigned long **extents; };
8513 static Atom extents_atom = 0;
8514
8515 static Bool property_notify_predicate(Display *xdisplay, XEvent *event, XPointer window_id)
8516 {
8517 unsigned long *window = (unsigned long *)window_id;
8518
8519 if(event->xany.type == PropertyNotify && event->xany.window == *window && event->xproperty.atom == extents_atom)
8520 return True;
8521 return False;
8522 }
8523
8524 /* Internal function to figure out the frame extents of an unmapped window */
8525 void _dw_get_frame_extents(GtkWidget *window, int *vert, int *horz)
8526 {
8527 const char *request = "_NET_REQUEST_FRAME_EXTENTS";
8528 unsigned long *extents = NULL;
8529 union extents_union eu;
8530 GdkAtom request_extents = gdk_atom_intern(request, FALSE);
8531 GdkWindow *gdkwindow = gtk_widget_get_window(window);
8532 GdkDisplay *display = gtk_widget_get_display(window);
8533
8534 /* Set some rational defaults.. just in case */
8535 *vert = 28;
8536 *horz = 12;
8537
8538 /* See if the current window manager supports _NET_REQUEST_FRAME_EXTENTS */
8539 if(gdk_x11_screen_supports_net_wm_hint(gdk_screen_get_default(), request_extents))
8540 {
8541 Display *xdisplay = GDK_DISPLAY_XDISPLAY(display);
8542 GdkWindow *root_window = gdk_get_default_root_window();
8543 Window xroot_window = GDK_WINDOW_XID(root_window);
8544 Atom extents_request_atom = gdk_x11_get_xatom_by_name_for_display(display, request);
8545 unsigned long window_id = GDK_WINDOW_XID(gdkwindow);
8546 XEvent notify_xevent, xevent = {0};
8547
8548 if(!extents_atom)
8549 {
8550 const char *extents_name = "_NET_FRAME_EXTENTS";
8551 extents_atom = gdk_x11_get_xatom_by_name_for_display(display, extents_name);
8552 }
8553
8554 xevent.xclient.type = ClientMessage;
8555 xevent.xclient.message_type = extents_request_atom;
8556 xevent.xclient.display = xdisplay;
8557 xevent.xclient.window = window_id;
8558 xevent.xclient.format = 32;
8559
8560 XSendEvent(xdisplay, xroot_window, False,
8561 (SubstructureRedirectMask | SubstructureNotifyMask),
8562 &xevent);
8563
8564 XIfEvent(xdisplay, &notify_xevent, property_notify_predicate, (XPointer)&window_id);
8565 }
8566
8567 /* Attempt to retrieve window's frame extents. */
8568 eu.extents = &extents;
8569 if(gdk_property_get(gdkwindow,
8570 gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE),
8571 gdk_atom_intern("CARDINAL", FALSE),
8572 0, sizeof(unsigned long)*4, FALSE,
8573 NULL, NULL, NULL, eu.gu_extents))
8574 {
8575 *horz = extents[0] + extents[1];
8576 *vert = extents[2] + extents[3];
8577 }
8578 }
8579
8507 /* 8580 /*
8508 * Sets the size of a given window (widget). 8581 * Sets the size of a given window (widget).
8509 * Parameters: 8582 * Parameters:
8510 * handle: Window (widget) handle. 8583 * handle: Window (widget) handle.
8511 * width: New width in pixels. 8584 * width: New width in pixels.
8512 * height: New height in pixels. 8585 * height: New height in pixels.
8513 */ 8586 */
8514 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height) 8587 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height)
8515 { 8588 {
8516 int _locked_by_me = FALSE; 8589 int _locked_by_me = FALSE;
8517 long default_width = width - _dw_border_width;
8518 long default_height = height - _dw_border_height;
8519 8590
8520 if(!handle) 8591 if(!handle)
8521 return; 8592 return;
8522 8593
8523 DW_MUTEX_LOCK; 8594 DW_MUTEX_LOCK;
8524 if(GTK_IS_WINDOW(handle)) 8595 if(GTK_IS_WINDOW(handle))
8525 { 8596 {
8526 GdkGeometry hints; 8597 GdkWindow *window = gtk_widget_get_window(handle);
8527 8598 int cx = 0, cy = 0;
8528 if ( width == 0 ) 8599
8529 default_width = -1; 8600 /* Window is mapped query the frame size directly */
8530 if ( height == 0 ) 8601 if(window && gtk_widget_get_mapped(handle))
8531 default_height = -1; 8602 {
8532 8603 GdkRectangle frame;
8533 hints.base_width = hints.base_height = 1; 8604 gint gwidth, gheight;
8534 hints.min_width = hints.min_height = 8; 8605
8535 hints.width_inc = hints.height_inc = 1; 8606 /* Calculate the border size */
8536 8607 gdk_window_get_frame_extents(window, &frame);
8537 gtk_window_set_geometry_hints(GTK_WINDOW(handle), NULL, &hints, GDK_HINT_RESIZE_INC|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE); 8608 gdk_window_get_geometry(window, NULL, NULL, &gwidth, &gheight);
8538 8609
8539 if(gtk_widget_get_window(handle) && default_width > 0 && default_height > 0) 8610 cx = frame.width - gwidth;
8540 gdk_window_resize(gtk_widget_get_window(handle), default_width , default_height ); 8611 if(cx < 0)
8541 8612 cx = 0;
8542 gtk_window_set_default_size(GTK_WINDOW(handle), default_width , default_height ); 8613 cy = frame.height - gheight;
8543 if(!g_object_get_data(G_OBJECT(handle), "_dw_size")) 8614 if(cy < 0)
8544 { 8615 cy = 0;
8545 g_object_set_data(G_OBJECT(handle), "_dw_width", GINT_TO_POINTER(default_width) ); 8616 }
8546 g_object_set_data(G_OBJECT(handle), "_dw_height", GINT_TO_POINTER(default_height) ); 8617 else
8547 } 8618 {
8619 /* Check if we have cached frame size values */
8620 if(!((cx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_width"))) |
8621 (cy = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_height")))))
8622 {
8623 /* If not try to ask the window manager for the estimated size...
8624 * and finally if all else fails, guess.
8625 */
8626 _dw_get_frame_extents(handle, &cy, &cx);
8627 /* Cache values for later use */
8628 g_object_set_data(G_OBJECT(handle), "_dw_frame_width", GINT_TO_POINTER(cx));
8629 g_object_set_data(G_OBJECT(handle), "_dw_frame_height", GINT_TO_POINTER(cy));
8630 }
8631 /* Save the size for when it is shown */
8632 g_object_set_data(G_OBJECT(handle), "_dw_width", GINT_TO_POINTER(width));
8633 g_object_set_data(G_OBJECT(handle), "_dw_height", GINT_TO_POINTER(height));
8634 }
8635 /* Resize minus the border size */
8636 gtk_window_resize(GTK_WINDOW(handle), width - cx , height - cy );
8637 gtk_window_set_default_size(GTK_WINDOW(handle), width - cx, height - cy);
8548 } 8638 }
8549 else 8639 else
8550 gtk_widget_set_size_request(handle, width, height); 8640 gtk_widget_set_size_request(handle, width, height);
8551 DW_MUTEX_UNLOCK; 8641 DW_MUTEX_UNLOCK;
8552 } 8642 }
8611 DW_MUTEX_UNLOCK; 8701 DW_MUTEX_UNLOCK;
8612 return retval; 8702 return retval;
8613 } 8703 }
8614 8704
8615 /* 8705 /*
8706 * Sets the gravity of a given window (widget).
8707 * Gravity controls which corner of the screen and window the position is relative to.
8708 * Parameters:
8709 * handle: Window (widget) handle.
8710 * horz: DW_GRAV_LEFT (default), DW_GRAV_RIGHT or DW_GRAV_CENTER.
8711 * vert: DW_GRAV_TOP (default), DW_GRAV_BOTTOM or DW_GRAV_CENTER.
8712 */
8713 void API dw_window_set_gravity(HWND handle, int horz, int vert)
8714 {
8715 dw_window_set_data(handle, "_dw_grav_horz", DW_INT_TO_POINTER(horz));
8716 dw_window_set_data(handle, "_dw_grav_vert", DW_INT_TO_POINTER(vert));
8717 }
8718
8719 /*
8616 * Sets the position of a given window (widget). 8720 * Sets the position of a given window (widget).
8617 * Parameters: 8721 * Parameters:
8618 * handle: Window (widget) handle. 8722 * handle: Window (widget) handle.
8619 * x: X location from the bottom left. 8723 * x: X location from the bottom left.
8620 * y: Y location from the bottom left. 8724 * y: Y location from the bottom left.
8635 else 8739 else
8636 { 8740 {
8637 GdkWindow *window = NULL; 8741 GdkWindow *window = NULL;
8638 8742
8639 if(GTK_IS_WINDOW(handle)) 8743 if(GTK_IS_WINDOW(handle))
8640 gtk_window_move(GTK_WINDOW(handle), x, y); 8744 {
8745 GdkWindow *window = gtk_widget_get_window(handle);
8746 int horz = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_grav_horz"));
8747 int vert = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_grav_vert"));
8748 int newx = x, newy = y, width = 0, height = 0;
8749
8750 /* If the window is mapped */
8751 if(window && gtk_widget_get_mapped(handle))
8752 {
8753 /* If we need the width or height... */
8754 if(horz || vert)
8755 {
8756 GdkRectangle frame;
8757
8758 /* Get the frame size */
8759 gdk_window_get_frame_extents(window, &frame);
8760 width = frame.width;
8761 height = frame.height;
8762 }
8763 }
8764 else
8765 {
8766 int cx , cy;
8767
8768 /* Check if we have cached frame size values */
8769 if(!((cx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_width"))) |
8770 (cy = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_height")))))
8771 {
8772 /* If not try to ask the window manager for the estimated size...
8773 * and finally if all else fails, guess.
8774 */
8775 _dw_get_frame_extents(handle, &cy, &cx);
8776 /* Cache values for later use */
8777 g_object_set_data(G_OBJECT(handle), "_dw_frame_width", GINT_TO_POINTER(cx));
8778 g_object_set_data(G_OBJECT(handle), "_dw_frame_height", GINT_TO_POINTER(cy));
8779 }
8780 /* Save the positions for when it is shown */
8781 g_object_set_data(G_OBJECT(handle), "_dw_x", GINT_TO_POINTER(x));
8782 g_object_set_data(G_OBJECT(handle), "_dw_y", GINT_TO_POINTER(y));
8783 g_object_set_data(G_OBJECT(handle), "_dw_pos", GINT_TO_POINTER(1));
8784 /* Check to see if there is a pending size request too */
8785 width = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_width"));
8786 height = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_height"));
8787 if(width | height)
8788 {
8789 /* Ask what GTK is planning on suggesting for the window size */
8790 gtk_window_get_size(GTK_WINDOW(handle), !width ? &width : NULL, !height ? &height : NULL);
8791 }
8792 /* Add the frame size to it */
8793 width += cx;
8794 height += cy;
8795 }
8796 /* Do any gravity calculations */
8797 if(horz || vert)
8798 {
8799 /* Handle horizontal center gravity */
8800 if((horz & 0xf) == DW_GRAV_CENTER)
8801 newx += ((gdk_screen_width() / 2) - (width / 2));
8802 /* Handle right gravity */
8803 else if((horz & 0xf) == DW_GRAV_RIGHT)
8804 newx = gdk_screen_width() - width - x;
8805 /* Handle vertical center gravity */
8806 if((vert & 0xf) == DW_GRAV_CENTER)
8807 newy += ((gdk_screen_height() / 2) - (height / 2));
8808 else if((vert & 0xf) == DW_GRAV_BOTTOM)
8809 newy = gdk_screen_height() - height - x;
8810 }
8811 /* Finally move the window into place */
8812 gtk_window_move(GTK_WINDOW(handle), newx, newy);
8813 }
8641 else if((window = gtk_widget_get_window(handle))) 8814 else if((window = gtk_widget_get_window(handle)))
8642 gdk_window_move(window, x, y); 8815 gdk_window_move(window, x, y);
8643 } 8816 }
8644 DW_MUTEX_UNLOCK; 8817 DW_MUTEX_UNLOCK;
8645 } 8818 }
8653 * width: Width of the widget. 8826 * width: Width of the widget.
8654 * height: Height of the widget. 8827 * height: Height of the widget.
8655 */ 8828 */
8656 void dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height) 8829 void dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height)
8657 { 8830 {
8658 int _locked_by_me = FALSE; 8831 dw_window_set_size(handle, width, height);
8659 GtkWidget *mdi; 8832 dw_window_set_pos(handle, x, y);
8660
8661 if(!handle)
8662 return;
8663
8664 DW_MUTEX_LOCK;
8665 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi))
8666 {
8667 gtk_mdi_move(GTK_MDI(mdi), handle, x, y);
8668 }
8669 else
8670 {
8671 GdkWindow *window = NULL;
8672
8673 if(GTK_IS_WINDOW(handle))
8674 {
8675 dw_window_set_size(handle, width, height);
8676 gtk_window_move(GTK_WINDOW(handle), x, y);
8677 }
8678 else if((window = gtk_widget_get_window(handle)))
8679 {
8680 gdk_window_resize(window, width, height);
8681 gdk_window_move(window, x, y);
8682 }
8683 }
8684 DW_MUTEX_UNLOCK;
8685 } 8833 }
8686 8834
8687 /* 8835 /*
8688 * Gets the position and size of a given window (widget). 8836 * Gets the position and size of a given window (widget).
8689 * Parameters: 8837 * Parameters:
8694 * height: Height of the widget. 8842 * height: Height of the widget.
8695 */ 8843 */
8696 void dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height) 8844 void dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height)
8697 { 8845 {
8698 int _locked_by_me = FALSE; 8846 int _locked_by_me = FALSE;
8699 gint gx, gy, gwidth, gheight; 8847 gint gx = 0, gy = 0, gwidth = 0, gheight = 0;
8700 GtkWidget *mdi; 8848 GtkWidget *mdi;
8701 8849
8702 DW_MUTEX_LOCK; 8850 DW_MUTEX_LOCK;
8851 /* If it is an MDI window query what we can */
8703 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) 8852 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi))
8704 { 8853 {
8705 gint myx=0, myy=0; 8854 gtk_mdi_get_pos(GTK_MDI(mdi), handle, &gx, &gy);
8706
8707 gtk_mdi_get_pos(GTK_MDI(mdi), handle, &myx, &myy);
8708 *x = myx;
8709 *y = myy;
8710 } 8855 }
8711 else 8856 else
8712 { 8857 {
8713 if(handle && gtk_widget_get_window(handle)) 8858 GdkWindow *window;
8714 { 8859
8715 8860 /* Can only query if the window is realized */
8716 gdk_window_get_geometry(gtk_widget_get_window(handle), &gx, &gy, &gwidth, &gheight); 8861 if(handle && (window = gtk_widget_get_window(handle)))
8717 gdk_window_get_root_origin(gtk_widget_get_window(handle), &gx, &gy); 8862 {
8718 if(x) 8863 /* If it is a toplevel window */
8719 *x = gx;
8720 if(y)
8721 *y = gy;
8722 if(GTK_IS_WINDOW(handle)) 8864 if(GTK_IS_WINDOW(handle))
8723 { 8865 {
8724 if(width) 8866 if(gtk_widget_get_mapped(handle))
8725 *width = gwidth + _dw_border_width; 8867 {
8726 if(height) 8868 GdkRectangle frame;
8727 *height = gheight + _dw_border_height; 8869
8870 /* Calculate the border rectangle */
8871 gdk_window_get_frame_extents(window, &frame);
8872 gx = frame.x;
8873 gy = frame.y;
8874 gwidth = frame.width;
8875 gheight = frame.height;
8876 }
8728 } 8877 }
8729 else 8878 else
8730 { 8879 {
8731 if(width) 8880 /* Get an individual widget coordinates */
8732 *width = gwidth; 8881 gdk_window_get_geometry(window, &gx, &gy, &gwidth, &gheight);
8733 if(height) 8882 gdk_window_get_root_origin(window, &gx, &gy);
8734 *height = gheight;
8735 } 8883 }
8736 } 8884 }
8737 } 8885 }
8886 /* Fill in the requested fields */
8887 if(x)
8888 *x = gx;
8889 if(y)
8890 *y = gy;
8891 if(width)
8892 *width = gwidth;
8893 if(height)
8894 *height = gheight;
8738 DW_MUTEX_UNLOCK; 8895 DW_MUTEX_UNLOCK;
8739 } 8896 }
8740 8897
8741 /* 8898 /*
8742 * Sets the style of a given window (widget). 8899 * Sets the style of a given window (widget).