diff options
author | Owen Taylor <otaylor@redhat.com> | 2001-11-26 02:20:06 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2001-11-26 02:20:06 +0000 |
commit | 6a252271fbc1d57276e35227437ffde77e6181ad (patch) | |
tree | 29688f1f7c95cec4661b80ce283fa893fe761a70 /gdk | |
parent | c117249322ffdab3b85f64a590637abc844d5cf0 (diff) | |
download | gtk+-6a252271fbc1d57276e35227437ffde77e6181ad.tar.gz |
Add long, but horribly sketchy comment about what is going on in this
Sun Nov 25 21:19:02 2001 Owen Taylor <otaylor@redhat.com>
* gdk/x11/gdkgeometry-x11.c: Add long, but horribly sketchy
comment about what is going on in this file.
* gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): Fix
x/y problem.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/x11/gdkgeometry-x11.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index b479ab5e75..db1fc2cfe4 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -22,6 +22,111 @@ * * By Owen Taylor <otaylor@redhat.com> * Copyright Red Hat, Inc. 2000 + * + * The algorithms implemented in this file are an extension of the + * idea of guffaw scrolling, a technique (and name) taken from the classic + * Netscape source code. The basic idea of guffaw scrolling is a trick + * to get around a limitation of X: there is no way of scrolling the + * contents of a window. Guffaw scrolling exploits the X concepts of + * window gravity and bit gravity: + * + * window gravity: the window gravity of a window affects what happens + * to a windows position when _its parent_ is resized, or + * moved and resized simultaneously. + * + * bit gravity: the bit gravity of a window affects what happens to + * the pixels of a window when _it_ is is resized, or moved and + * resized simultaneously. + * + * These were basically intended to do things like have right + * justified widgets in a window automatically stay right justified + * when the window was resized, but there is also the special + * "StaticGravity" which means "do nothing." We can exploit + * StaticGravity to scroll a window: + * + * | VISIBLE | + * + * |abcdefghijk| + * |abcdefghijk | (1) Resize bigger + * | efghijk | (2) Move + * |efghijk | (3) Move-resize back to the original size + * + * Or, going the other way: + + * |abcdefghijk| + * | abcdefghijk| (1) Move-resize bigger + * | abcdefghijk| (2) Move + * | abcdefg| (4) Resize back to the original size + * + * By using this technique, we can simulate scrolling around in a + * large virtual space without having to actually have windows that + * big; for the pixels of the window, this is all we have to do. For + * subwindows, we have to take care of one other detail - since + * coordinates in X are limited to 16 bits, subwindows scrolled off + * will wrap around and come back eventually. So, we have to take care + * to unmap windows that go outside the 16-bit range and remap them as + * they come back in. + * + * Since we are temporarily making the window bigger, this only looks + * good if the edges of the window are obscured. Typically, we do + * this by making the window we are scrolling the immediate child + * of a "clip window". + * + * But, this isn't a perfect API for applications for several reasons: + * + * - We have to use this inefficient technique even for small windows + * if the window _could_ be big. + * - Applications have to use a special scrolling API. + * + * What we'd like is to simply have windows with 32 bit coordinates + * so applications could scroll in the classic way - just move a big + * window around. + * + * It turns out that StaticGravity can also be used to achieve emulation + * of 32 bit coordinates with only 16 bit coordinates if we expand + * our horizons just a bit; what guffaw scrolling really is is a way + * to move the contents of a window a different amount than we move + * the borders of of the window. In the above example pictures we + * ended up with the borders of the window not moving at all, but + * that isn't necessary. + * + * So, what we do is set up a mapping from virtual 32 bit window position/size + * to: + * + * - Real window position/size + * - Offset between virtual coordinates and real coordinates for the window + * - Map state (mapped or unmapped) + * + * By the following rules: + * + * - If the window is less than 32767 pixels in width (resp. height), we use it's + * virtual width and position. + * - Otherwise, we use a width of 32767 and determine the position of the window + * so that the portion of the real window [16384, 16383] in _toplevel window + * coordinates_ is the same as the portion of the real window + * + * This is implemented in gdk_window_compute_position(). Then the algorithm + * for a moving a window (_window_move_resize_child ()) is: + * + * - Compute the new window mappings for the window and all subwindows + * - Expand out the boundary of the window and all subwindows by the amount + * that the real/virtual offset changes for each window. + * (compute_intermediate_position() computes expanded boundary) + * - Move the toplevel by the amount that it's contents need to translate. + * - Move/resize the window and all subwindows to the newly computed + * positions. + * + * If we just are scrolling (gdk_window_guffaw_scroll()), then things + * are similar, except that the final mappings for the toplevel are + * the same as the initial mappings, but we act as if it moved by the + * amount we are scrolling by. + * + * Note that we don't have to worry about a clip window in + * _gdk_window_move_resize() since we have set up our translation so + * that things in the range [16384,16383] in toplevel window + * coordinates look exactly as they would if we were simply moving the + * windows, and nothing outside this range is going to be visible + * unless the user has a _really_ huge screen. */ #include "gdk.h" /* For gdk_rectangle_intersect */ @@ -521,7 +626,7 @@ gdk_window_compute_position (GdkWindowImplX11 *window, if (parent_pos->x + wrapper->x + window->width < 16384) info->x = parent_pos->x + wrapper->x + window->width - info->width - parent_pos->x11_x; else - info->x = -16384 - parent_pos->x11_y; + info->x = -16384 - parent_pos->x11_x; } else info->x = parent_pos->x + wrapper->x - parent_pos->x11_x; |