diff options
author | Owen Taylor <otaylor@redhat.com> | 1999-01-27 18:21:20 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1999-01-27 18:21:20 +0000 |
commit | 14724626395882260fc73ae008a9df4fe7cbd877 (patch) | |
tree | d16769df30f0409e3faacd27a94b4a22a2be332d /gdk | |
parent | 90c7ea0b9138bb94bef9b01f37c7d3faffcbc6b7 (diff) | |
download | gdk-pixbuf-14724626395882260fc73ae008a9df4fe7cbd877.tar.gz |
Use floor() instead of truncating to integer values so we get translation
Wed Jan 20 11:19:00 1999 Owen Taylor <otaylor@redhat.com>
* gtk/gtklabel.c: Use floor() instead of truncating
to integer values so we get translation invariance.
* gtk/gtklayout.c (gtk_layout_size_allocate): Set upper
and lower values for adjustments in size_allocate().
* gdk/gdkwindow.c gdk/gdk.h gdk/gdkprivate.h: New
function gdk_window_set_static_gravities() to set
up a window for guffaw scrolling.
* gdk/gdkwindow.c (gdk_window_internal_destroy): Set flags
indicating destroyed state before cleanup.
* gtk/gtkprivate.h gtk/gtkwidget.c: Add a new
private flag IS_OFFSCREEN. If set, this indicates
to GTK+ that the widget is not to be considered
viewable regardless of its map state. Queued draws
on offscreen widgets are suppressed.
Added new function static gtk_widget_is_offscreen() to
check this flag on a widget and its ancestors.
* gtk/gtklayout.[ch]: Major revisions.
- Use gdk_window_set_static_gravities to set static gravity
on all child windows, and thus avoid having to create a window
for NO_WINDOW children.
- Adjust allocations of children as we scroll them
so queued draws work correctly.
- Don't allocate our children directly in a put()
or move(); just queue a resize() like every other
widget.
* gtk/testgtk.c: Make the arrows on the scrollbars
work, create a larger and more demanding test.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.h | 5 | ||||
-rw-r--r-- | gdk/gdkprivate.h | 1 | ||||
-rw-r--r-- | gdk/gdkwindow.c | 168 | ||||
-rw-r--r-- | gdk/x11/gdkwindow-x11.c | 168 |
4 files changed, 326 insertions, 16 deletions
@@ -227,6 +227,11 @@ void gdk_window_merge_child_shapes (GdkWindow *window); gboolean gdk_window_is_visible (GdkWindow *window); gboolean gdk_window_is_viewable (GdkWindow *window); +/* Set static bit gravity on the parent, and static + * window gravity on all children. + */ +gboolean gdk_window_set_static_gravities (GdkWindow *window, + gboolean use_static); /* * The following function adds a global filter for all client * messages of type message_type diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index 42b6a5ea4..00232970b 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -64,6 +64,7 @@ struct _GdkWindowPrivate guint ref_count; guint destroyed : 2; guint mapped : 1; + guint guffaw_gravity : 1; gint extension_events; diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 7cdde55dc..601c74894 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -69,6 +69,10 @@ const int gdk_event_mask_table[20] = }; const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int); +/* Forward declarations */ +static gboolean gdk_window_gravity_works (void); +static void gdk_window_set_static_win_gravity (GdkWindow *window, + gboolean on); static gboolean gdk_window_have_shape_ext (void); /* internal function created for and used by gdk_window_xid_at_coords */ @@ -274,12 +278,10 @@ gdk_window_new (GdkWindow *parent, private->parent = parent; - if (parent_private) - parent_private->children = g_list_prepend (parent_private->children, window); - private->xdisplay = parent_display; private->destroyed = FALSE; private->mapped = FALSE; + private->guffaw_gravity = FALSE; private->resize_count = 0; private->ref_count = 1; xattributes_mask = 0; @@ -322,13 +324,21 @@ gdk_window_new (GdkWindow *parent, if (xattributes.event_mask) xattributes_mask |= CWEventMask; - if(attributes_mask & GDK_WA_NOREDIR) { - xattributes.override_redirect = + if (attributes_mask & GDK_WA_NOREDIR) + { + xattributes.override_redirect = (attributes->override_redirect == FALSE)?False:True; - xattributes_mask |= CWOverrideRedirect; - } else + xattributes_mask |= CWOverrideRedirect; + } + else xattributes.override_redirect = False; + if (parent_private && parent_private->guffaw_gravity) + { + xattributes.win_gravity = StaticGravity; + xattributes_mask |= CWWinGravity; + } + if (attributes->wclass == GDK_INPUT_OUTPUT) { class = InputOutput; @@ -409,6 +419,9 @@ gdk_window_new (GdkWindow *parent, (attributes->cursor) : NULL)); + if (parent_private) + parent_private->children = g_list_prepend (parent_private->children, window); + switch (private->window_type) { case GDK_WINDOW_DIALOG: @@ -523,6 +536,7 @@ gdk_window_foreign_new (guint32 anid) private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; private->mapped = (attrs.map_state != IsUnmapped); + private->guffaw_gravity = FALSE; private->extension_events = 0; private->colormap = NULL; @@ -877,8 +891,13 @@ gdk_window_reparent (GdkWindow *window, if (old_parent_private) old_parent_private->children = g_list_remove (old_parent_private->children, window); - parent_private->children = g_list_prepend (parent_private->children, window); + + if ((old_parent_private && + (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) || + (!old_parent_private && parent_private->guffaw_gravity)) + gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity); + parent_private->children = g_list_prepend (parent_private->children, window); } void @@ -2547,3 +2566,136 @@ gdk_drawable_set_data (GdkDrawable *drawable, { g_dataset_set_data_full (drawable, key, data, destroy_func); } + + +/* Support for windows that can be guffaw-scrolled + * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt) + */ + +static gboolean +gdk_window_gravity_works (void) +{ + enum { UNKNOWN, NO, YES }; + static gint gravity_works = UNKNOWN; + + if (gravity_works == UNKNOWN) + { + GdkWindowAttr attr; + GdkWindow *parent; + GdkWindow *child; + gint y; + + /* This particular server apparently has a bug so that the test + * works but the actual code crashes it + */ + if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) && + (VendorRelease (gdk_display) == 3400)) + { + gravity_works = NO; + return FALSE; + } + + attr.window_type = GDK_WINDOW_TEMP; + attr.wclass = GDK_INPUT_OUTPUT; + attr.x = 0; + attr.y = 0; + attr.width = 100; + attr.height = 100; + attr.event_mask = 0; + + parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y); + + attr.window_type = GDK_WINDOW_CHILD; + child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y); + + gdk_window_set_static_win_gravity (child, TRUE); + + gdk_window_resize (parent, 100, 110); + gdk_window_move (parent, 0, -10); + gdk_window_move_resize (parent, 0, 0, 100, 100); + + gdk_window_resize (parent, 100, 110); + gdk_window_move (parent, 0, -10); + gdk_window_move_resize (parent, 0, 0, 100, 100); + + gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL); + + gdk_window_destroy (parent); + gdk_window_destroy (child); + + gravity_works = ((y == -20) ? YES : NO); + } + + return (gravity_works == YES); +} + +static void +gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + XSetWindowAttributes xattributes; + + g_return_if_fail (window != NULL); + + xattributes.bit_gravity = on ? StaticGravity : ForgetGravity; + XChangeWindowAttributes (private->xdisplay, + private->xwindow, + CWBitGravity, &xattributes); +} + +static void +gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + XSetWindowAttributes xattributes; + + g_return_if_fail (window != NULL); + + xattributes.win_gravity = on ? StaticGravity : NorthWestGravity; + + XChangeWindowAttributes (private->xdisplay, + private->xwindow, + CWWinGravity, &xattributes); +} + +/************************************************************* + * gdk_window_set_static_gravities: + * Set the bit gravity of the given window to static, + * and flag it so all children get static subwindow + * gravity. + * arguments: + * window: window for which to set static gravity + * use_static: Whether to turn static gravity on or off. + * results: + * Does the XServer support static gravity? + *************************************************************/ + +gboolean +gdk_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GList *tmp_list; + + g_return_val_if_fail (window != NULL, FALSE); + + if (!use_static == !private->guffaw_gravity) + return TRUE; + + if (use_static && !gdk_window_gravity_works ()) + return FALSE; + + private->guffaw_gravity = use_static; + + gdk_window_set_static_bit_gravity (window, use_static); + + tmp_list = private->children; + while (tmp_list) + { + gdk_window_set_static_win_gravity (window, use_static); + + tmp_list = tmp_list->next; + } + + return TRUE; +} diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 7cdde55dc..601c74894 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -69,6 +69,10 @@ const int gdk_event_mask_table[20] = }; const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int); +/* Forward declarations */ +static gboolean gdk_window_gravity_works (void); +static void gdk_window_set_static_win_gravity (GdkWindow *window, + gboolean on); static gboolean gdk_window_have_shape_ext (void); /* internal function created for and used by gdk_window_xid_at_coords */ @@ -274,12 +278,10 @@ gdk_window_new (GdkWindow *parent, private->parent = parent; - if (parent_private) - parent_private->children = g_list_prepend (parent_private->children, window); - private->xdisplay = parent_display; private->destroyed = FALSE; private->mapped = FALSE; + private->guffaw_gravity = FALSE; private->resize_count = 0; private->ref_count = 1; xattributes_mask = 0; @@ -322,13 +324,21 @@ gdk_window_new (GdkWindow *parent, if (xattributes.event_mask) xattributes_mask |= CWEventMask; - if(attributes_mask & GDK_WA_NOREDIR) { - xattributes.override_redirect = + if (attributes_mask & GDK_WA_NOREDIR) + { + xattributes.override_redirect = (attributes->override_redirect == FALSE)?False:True; - xattributes_mask |= CWOverrideRedirect; - } else + xattributes_mask |= CWOverrideRedirect; + } + else xattributes.override_redirect = False; + if (parent_private && parent_private->guffaw_gravity) + { + xattributes.win_gravity = StaticGravity; + xattributes_mask |= CWWinGravity; + } + if (attributes->wclass == GDK_INPUT_OUTPUT) { class = InputOutput; @@ -409,6 +419,9 @@ gdk_window_new (GdkWindow *parent, (attributes->cursor) : NULL)); + if (parent_private) + parent_private->children = g_list_prepend (parent_private->children, window); + switch (private->window_type) { case GDK_WINDOW_DIALOG: @@ -523,6 +536,7 @@ gdk_window_foreign_new (guint32 anid) private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; private->mapped = (attrs.map_state != IsUnmapped); + private->guffaw_gravity = FALSE; private->extension_events = 0; private->colormap = NULL; @@ -877,8 +891,13 @@ gdk_window_reparent (GdkWindow *window, if (old_parent_private) old_parent_private->children = g_list_remove (old_parent_private->children, window); - parent_private->children = g_list_prepend (parent_private->children, window); + + if ((old_parent_private && + (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) || + (!old_parent_private && parent_private->guffaw_gravity)) + gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity); + parent_private->children = g_list_prepend (parent_private->children, window); } void @@ -2547,3 +2566,136 @@ gdk_drawable_set_data (GdkDrawable *drawable, { g_dataset_set_data_full (drawable, key, data, destroy_func); } + + +/* Support for windows that can be guffaw-scrolled + * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt) + */ + +static gboolean +gdk_window_gravity_works (void) +{ + enum { UNKNOWN, NO, YES }; + static gint gravity_works = UNKNOWN; + + if (gravity_works == UNKNOWN) + { + GdkWindowAttr attr; + GdkWindow *parent; + GdkWindow *child; + gint y; + + /* This particular server apparently has a bug so that the test + * works but the actual code crashes it + */ + if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) && + (VendorRelease (gdk_display) == 3400)) + { + gravity_works = NO; + return FALSE; + } + + attr.window_type = GDK_WINDOW_TEMP; + attr.wclass = GDK_INPUT_OUTPUT; + attr.x = 0; + attr.y = 0; + attr.width = 100; + attr.height = 100; + attr.event_mask = 0; + + parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y); + + attr.window_type = GDK_WINDOW_CHILD; + child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y); + + gdk_window_set_static_win_gravity (child, TRUE); + + gdk_window_resize (parent, 100, 110); + gdk_window_move (parent, 0, -10); + gdk_window_move_resize (parent, 0, 0, 100, 100); + + gdk_window_resize (parent, 100, 110); + gdk_window_move (parent, 0, -10); + gdk_window_move_resize (parent, 0, 0, 100, 100); + + gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL); + + gdk_window_destroy (parent); + gdk_window_destroy (child); + + gravity_works = ((y == -20) ? YES : NO); + } + + return (gravity_works == YES); +} + +static void +gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + XSetWindowAttributes xattributes; + + g_return_if_fail (window != NULL); + + xattributes.bit_gravity = on ? StaticGravity : ForgetGravity; + XChangeWindowAttributes (private->xdisplay, + private->xwindow, + CWBitGravity, &xattributes); +} + +static void +gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + XSetWindowAttributes xattributes; + + g_return_if_fail (window != NULL); + + xattributes.win_gravity = on ? StaticGravity : NorthWestGravity; + + XChangeWindowAttributes (private->xdisplay, + private->xwindow, + CWWinGravity, &xattributes); +} + +/************************************************************* + * gdk_window_set_static_gravities: + * Set the bit gravity of the given window to static, + * and flag it so all children get static subwindow + * gravity. + * arguments: + * window: window for which to set static gravity + * use_static: Whether to turn static gravity on or off. + * results: + * Does the XServer support static gravity? + *************************************************************/ + +gboolean +gdk_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + GdkWindowPrivate *private = (GdkWindowPrivate *)window; + GList *tmp_list; + + g_return_val_if_fail (window != NULL, FALSE); + + if (!use_static == !private->guffaw_gravity) + return TRUE; + + if (use_static && !gdk_window_gravity_works ()) + return FALSE; + + private->guffaw_gravity = use_static; + + gdk_window_set_static_bit_gravity (window, use_static); + + tmp_list = private->children; + while (tmp_list) + { + gdk_window_set_static_win_gravity (window, use_static); + + tmp_list = tmp_list->next; + } + + return TRUE; +} |