summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>1999-01-27 18:21:20 +0000
committerOwen Taylor <otaylor@src.gnome.org>1999-01-27 18:21:20 +0000
commit14724626395882260fc73ae008a9df4fe7cbd877 (patch)
treed16769df30f0409e3faacd27a94b4a22a2be332d /gdk
parent90c7ea0b9138bb94bef9b01f37c7d3faffcbc6b7 (diff)
downloadgdk-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.h5
-rw-r--r--gdk/gdkprivate.h1
-rw-r--r--gdk/gdkwindow.c168
-rw-r--r--gdk/x11/gdkwindow-x11.c168
4 files changed, 326 insertions, 16 deletions
diff --git a/gdk/gdk.h b/gdk/gdk.h
index e3030b3bc..bae3ebb87 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -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;
+}