summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2001-08-10 03:46:08 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-08-10 03:46:08 +0000
commitf37a0627fc3fe7676dc38b8c32856e375be59de1 (patch)
tree3246680255da5aa2ed168d8deb17a6f2a6c7343f
parent439cd9a3a505424ea64d099ecbe1b4c910b79649 (diff)
downloadgdk-pixbuf-f37a0627fc3fe7676dc38b8c32856e375be59de1.tar.gz
fix a typo.
2001-08-07 Havoc Pennington <hp@pobox.com> * gtk/gtkfilesel.c (open_ref_dir): fix a typo. * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink; some fixage is needed here, but nothing simple. Owen understands it. ;-) * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window sizing and positioning. Also, fix bug in compute_geometry_hints (width/height confusion for setting min size). (gtk_window_move): new function (gtk_window_resize): new function (gtk_window_get_size): new function (gtk_window_get_position): new function (gtk_window_parse_geometry): new function * gtk/gtkwidget.c (gtk_widget_set_size_request): new function (gtk_widget_get_size_request): new function (gtk_widget_get_usize): delete, that was a short-lived function ;-) (gtk_widget_set_usize): deprecate (gtk_widget_set_uposition): deprecate, make it a trivial gtk_window_move() wrapper (gtk_widget_class_init): remove x/y/width/height properties, add width_request height_request * demos/*: update to avoid deprecated functions * gtk/gtklayout.c: add x/y child properties * gtk/gtkfixed.c: add x/y child properties, and get rid of uses of "gint16" * tests/testgtk.c (create_window_sizing): lots of tweaks to window sizing test * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that configure events on toplevel windows are always in root window coordinates, following ICCCM spec that all synthetic events are in root window coords already, while real events are in parent window coords. Previously the code assumed that coords of 0,0 were parent window coords, which was really broken. * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix warning * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS and GDK_HINT_USER_SIZE so we can set USSize and USPosition hints in gtk_window_parse_geometry() * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support new USER_POS USER_SIZE hints
-rw-r--r--ChangeLog55
-rw-r--r--ChangeLog.pre-2-055
-rw-r--r--ChangeLog.pre-2-1055
-rw-r--r--ChangeLog.pre-2-255
-rw-r--r--ChangeLog.pre-2-455
-rw-r--r--ChangeLog.pre-2-655
-rw-r--r--ChangeLog.pre-2-855
-rw-r--r--demos/gtk-demo/colorsel.c2
-rw-r--r--demos/gtk-demo/item_factory.c2
-rw-r--r--demos/gtk-demo/main.c2
-rw-r--r--demos/gtk-demo/panes.c2
-rw-r--r--demos/gtk-demo/pixbufs.c2
-rw-r--r--demos/pixbuf-demo.c5
-rw-r--r--demos/testpixbuf-drawable.c6
-rw-r--r--demos/testpixbuf-save.c6
-rw-r--r--demos/testpixbuf.c2
-rw-r--r--docs/Changes-2.0.txt16
-rw-r--r--docs/reference/gdk/tmpl/windows.sgml2
-rw-r--r--docs/reference/gtk/tmpl/gtk-unused.sgml30
-rw-r--r--docs/reference/gtk/tmpl/gtkrc.sgml1
-rw-r--r--docs/reference/gtk/tmpl/gtkwidget.sgml14
-rw-r--r--docs/reference/gtk/tmpl/gtkwindow.sgml5
-rw-r--r--docs/sizing-test.txt121
-rw-r--r--gdk/gdkwindow.h4
-rw-r--r--gdk/x11/gdkevents-x11.c7
-rw-r--r--gdk/x11/gdkwindow-x11.c10
-rw-r--r--gtk/gtkfixed.c190
-rw-r--r--gtk/gtkfixed.h12
-rw-r--r--gtk/gtklayout.c243
-rw-r--r--gtk/gtkplug.c1
-rw-r--r--gtk/gtkwidget.c259
-rw-r--r--gtk/gtkwidget.h10
-rw-r--r--gtk/gtkwindow.c2062
-rw-r--r--gtk/gtkwindow.h64
-rw-r--r--tests/testgtk.c387
35 files changed, 3040 insertions, 812 deletions
diff --git a/ChangeLog b/ChangeLog
index 587577f0c..05cb01ade 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 587577f0c..05cb01ade 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,58 @@
+2001-08-07 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtkfilesel.c (open_ref_dir): fix a typo.
+
+ * gtk/gtkplug.c (gtk_plug_init): remove setting of auto_shrink;
+ some fixage is needed here, but nothing simple. Owen understands
+ it. ;-)
+
+ * gtk/gtkwindow.h, gtk/gtkwindow.c: Rework code and API for window
+ sizing and positioning. Also, fix bug in compute_geometry_hints
+ (width/height confusion for setting min size).
+ (gtk_window_move): new function
+ (gtk_window_resize): new function
+ (gtk_window_get_size): new function
+ (gtk_window_get_position): new function
+ (gtk_window_parse_geometry): new function
+
+ * gtk/gtkwidget.c (gtk_widget_set_size_request): new function
+ (gtk_widget_get_size_request): new function
+ (gtk_widget_get_usize): delete, that was a short-lived function
+ ;-)
+ (gtk_widget_set_usize): deprecate
+ (gtk_widget_set_uposition): deprecate, make it a trivial
+ gtk_window_move() wrapper
+ (gtk_widget_class_init): remove x/y/width/height properties,
+ add width_request height_request
+
+ * demos/*: update to avoid deprecated functions
+
+ * gtk/gtklayout.c: add x/y child properties
+
+ * gtk/gtkfixed.c: add x/y child properties, and get rid of
+ uses of "gint16"
+
+ * tests/testgtk.c (create_window_sizing): lots of tweaks to window
+ sizing test
+
+ * gdk/x11/gdkevents-x11.c (gdk_event_translate): Ensure that
+ configure events on toplevel windows are always in root window
+ coordinates, following ICCCM spec that all synthetic events
+ are in root window coords already, while real events are
+ in parent window coords. Previously the code assumed that
+ coords of 0,0 were parent window coords, which was
+ really broken.
+
+ * gtk/gtkcontainer.c (gtk_container_get_focus_chain): fix
+ warning
+
+ * gdk/gdkwindow.h (GdkWindowHints): add GDK_HINT_USER_POS
+ and GDK_HINT_USER_SIZE so we can set USSize and USPosition
+ hints in gtk_window_parse_geometry()
+
+ * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): support
+ new USER_POS USER_SIZE hints
+
2001-08-09 Matthias Clasen <matthiasc@waldgeist.poet.de>
* tests/prop-editor.c (properties_from_type): Use
diff --git a/demos/gtk-demo/colorsel.c b/demos/gtk-demo/colorsel.c
index cd178288b..da02ef39c 100644
--- a/demos/gtk-demo/colorsel.c
+++ b/demos/gtk-demo/colorsel.c
@@ -78,7 +78,7 @@ do_colorsel (void)
da = gtk_drawing_area_new ();
/* set a minimum size */
- gtk_widget_set_usize (da, 200, 200);
+ gtk_widget_set_size_request (da, 200, 200);
/* set the color */
gtk_widget_modify_bg (da, GTK_STATE_NORMAL, &color);
diff --git a/demos/gtk-demo/item_factory.c b/demos/gtk-demo/item_factory.c
index 5454a074d..5a55de4b6 100644
--- a/demos/gtk-demo/item_factory.c
+++ b/demos/gtk-demo/item_factory.c
@@ -92,7 +92,7 @@ do_item_factory (void)
FALSE, FALSE, 0);
label = gtk_label_new ("Type\n<alt>\nto start");
- gtk_widget_set_usize (label, 200, 200);
+ gtk_widget_set_size_request (label, 200, 200);
gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
diff --git a/demos/gtk-demo/main.c b/demos/gtk-demo/main.c
index d06070ed0..77fb6bc0c 100644
--- a/demos/gtk-demo/main.c
+++ b/demos/gtk-demo/main.c
@@ -686,7 +686,7 @@ create_tree (void)
gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
GTK_TREE_SELECTION_SINGLE);
- gtk_widget_set_usize (tree_view, 200, -1);
+ gtk_widget_set_size_request (tree_view, 200, -1);
for (i=0; i < G_N_ELEMENTS (testgtk_demos); i++)
{
diff --git a/demos/gtk-demo/panes.c b/demos/gtk-demo/panes.c
index f86d74ac5..3e1032976 100644
--- a/demos/gtk-demo/panes.c
+++ b/demos/gtk-demo/panes.c
@@ -148,7 +148,7 @@ do_panes (void)
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
- gtk_widget_set_usize (frame, 60, 60);
+ gtk_widget_set_size_request (frame, 60, 60);
gtk_paned_add1 (GTK_PANED (hpaned), frame);
button = gtk_button_new_with_mnemonic ("_Hi there");
diff --git a/demos/gtk-demo/pixbufs.c b/demos/gtk-demo/pixbufs.c
index d40c0918c..d0f2f2a4e 100644
--- a/demos/gtk-demo/pixbufs.c
+++ b/demos/gtk-demo/pixbufs.c
@@ -246,7 +246,7 @@ do_pixbufs (void)
}
else
{
- gtk_widget_set_usize (window, back_width, back_height);
+ gtk_widget_set_size_request (window, back_width, back_height);
frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
diff --git a/demos/pixbuf-demo.c b/demos/pixbuf-demo.c
index 11b5e1a15..722007ac7 100644
--- a/demos/pixbuf-demo.c
+++ b/demos/pixbuf-demo.c
@@ -212,8 +212,9 @@ main (int argc, char **argv)
frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_usize (window, back_width, back_height);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+
+ gtk_widget_set_size_request (window, back_width, back_height);
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (destroy_cb), NULL);
diff --git a/demos/testpixbuf-drawable.c b/demos/testpixbuf-drawable.c
index 073b8fa49..be40573cb 100644
--- a/demos/testpixbuf-drawable.c
+++ b/demos/testpixbuf-drawable.c
@@ -104,9 +104,9 @@ int main(int argc, char **argv)
gtk_container_add(GTK_CONTAINER(window), vbox);
drawing_area = gtk_drawing_area_new();
- gtk_widget_set_usize(GTK_WIDGET(drawing_area),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
+ gtk_widget_set_size_request (GTK_WIDGET(drawing_area),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
gtk_signal_connect(GTK_OBJECT(drawing_area), "expose_event",
GTK_SIGNAL_FUNC(expose_cb), NULL);
diff --git a/demos/testpixbuf-save.c b/demos/testpixbuf-save.c
index ed07bd4dd..071352ace 100644
--- a/demos/testpixbuf-save.c
+++ b/demos/testpixbuf-save.c
@@ -142,9 +142,9 @@ main (int argc, char **argv)
gtk_container_add (GTK_CONTAINER (window), vbox);
drawing_area = gtk_drawing_area_new ();
- gtk_widget_set_usize (GTK_WIDGET (drawing_area),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
+ gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
GTK_SIGNAL_FUNC (expose_cb), NULL);
diff --git a/demos/testpixbuf.c b/demos/testpixbuf.c
index 8f80d3118..707398f8d 100644
--- a/demos/testpixbuf.c
+++ b/demos/testpixbuf.c
@@ -393,7 +393,7 @@ new_testrgb_window (GdkPixbuf *pixbuf, gchar *title)
drawing_area = gtk_drawing_area_new ();
temp_box = gtk_hbox_new (FALSE, 0);
- gtk_widget_set_usize (GTK_WIDGET(drawing_area), w, h);
+ gtk_widget_set_size_request (GTK_WIDGET(drawing_area), w, h);
gtk_box_pack_start (GTK_BOX (temp_box), drawing_area, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), temp_box, FALSE, FALSE, 0);
diff --git a/docs/Changes-2.0.txt b/docs/Changes-2.0.txt
index ffce736df..9b82b2d85 100644
--- a/docs/Changes-2.0.txt
+++ b/docs/Changes-2.0.txt
@@ -397,6 +397,22 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
using gdk_image_get() should really be ported to
gdk_pixbuf_get_from_drawable().
+* gtk_widget_set_usize() has been renamed to
+ gtk_widget_set_size_request(), however the old name still exists
+ unless you define GTK_DISABLE_DEPRECATED.
+
+* gtk_widget_set_uposition() is deprecated; use gtk_window_move(),
+ gtk_fixed_put(), or gtk_layout_put() instead.
+
+* gtk_window_set_policy() is deprecated. To get the effect of
+ "allow_shrink", call gtk_widget_set_size_request(window, 0, 0). To
+ get the effect of "allow_grow", call
+ gtk_window_set_resizable(window, TRUE). You didn't want the effect
+ of auto_shrink, it made no sense. But maybe if you were using it you
+ want to use gtk_window_resize (window, 1, 1) to snap a window back
+ to its minimum size (the 1, 1 will be rounded up to the minimum
+ window size).
+
* The core GTK+ now takes care of handling mapping, unmapping and
realizing the child widgets of containers in
gtk_widget_set_parent(). In most cases, this allows container
diff --git a/docs/reference/gdk/tmpl/windows.sgml b/docs/reference/gdk/tmpl/windows.sgml
index 78e0bc8f1..c21b8f46f 100644
--- a/docs/reference/gdk/tmpl/windows.sgml
+++ b/docs/reference/gdk/tmpl/windows.sgml
@@ -87,6 +87,8 @@ Windows
@GDK_HINT_ASPECT:
@GDK_HINT_RESIZE_INC:
@GDK_HINT_WIN_GRAVITY:
+@GDK_HINT_USER_POS:
+@GDK_HINT_USER_SIZE:
<!-- ##### STRUCT GdkGeometry ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtk-unused.sgml b/docs/reference/gtk/tmpl/gtk-unused.sgml
index 8c126874d..3c9c63eeb 100644
--- a/docs/reference/gtk/tmpl/gtk-unused.sgml
+++ b/docs/reference/gtk/tmpl/gtk-unused.sgml
@@ -1004,6 +1004,36 @@ the #GtkAdjustment which sets the range of the scale.
@widget: the object which received the signal.
+<!-- ##### ARG GtkWidget:height ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:width ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:x ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWidget:y ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkWindow:auto-shrink ##### -->
+<para>
+If the window shrinks automatically when widgets within it shrink.
+</para>
+
+
<!-- ##### FUNCTION gtk_arg_copy ##### -->
<para>
It will either copy data into an existing argument or allocate a new argument
diff --git a/docs/reference/gtk/tmpl/gtkrc.sgml b/docs/reference/gtk/tmpl/gtkrc.sgml
index cc0b23b6d..30ffca823 100644
--- a/docs/reference/gtk/tmpl/gtkrc.sgml
+++ b/docs/reference/gtk/tmpl/gtkrc.sgml
@@ -495,7 +495,6 @@ This can later be composited together with other
#GtkRcStyle structures to form a #GtkStyle.
</para>
-@parent_instance:
@name:
@bg_pixmap_name:
@font_desc:
diff --git a/docs/reference/gtk/tmpl/gtkwidget.sgml b/docs/reference/gtk/tmpl/gtkwidget.sgml
index 01e7f0763..b92fb889e 100644
--- a/docs/reference/gtk/tmpl/gtkwidget.sgml
+++ b/docs/reference/gtk/tmpl/gtkwidget.sgml
@@ -1874,22 +1874,12 @@ a widget changes from un-anchored to anchored or vice-versa.
</para>
-<!-- ##### ARG GtkWidget:x ##### -->
+<!-- ##### ARG GtkWidget:width-request ##### -->
<para>
</para>
-<!-- ##### ARG GtkWidget:y ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkWidget:width ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkWidget:height ##### -->
+<!-- ##### ARG GtkWidget:height-request ##### -->
<para>
</para>
diff --git a/docs/reference/gtk/tmpl/gtkwindow.sgml b/docs/reference/gtk/tmpl/gtkwindow.sgml
index 7d43fb870..3fb16a1c6 100644
--- a/docs/reference/gtk/tmpl/gtkwindow.sgml
+++ b/docs/reference/gtk/tmpl/gtkwindow.sgml
@@ -509,11 +509,6 @@ The type of the window.
The title of the window.
</para>
-<!-- ##### ARG GtkWindow:auto-shrink ##### -->
-<para>
-If the window shrinks automatically when widgets within it shrink.
-</para>
-
<!-- ##### ARG GtkWindow:allow-shrink ##### -->
<para>
If the window can be resized to a smaller size by the user.
diff --git a/docs/sizing-test.txt b/docs/sizing-test.txt
new file mode 100644
index 000000000..6954612d4
--- /dev/null
+++ b/docs/sizing-test.txt
@@ -0,0 +1,121 @@
+This is a list of things to check when testing window size/pos functions.
+===
+
+gtk_widget_set_size_request():
+ - causes the widget to request the given size
+ - for toplevel windows, changes the default-requested size if
+ no default size is set and gtk_window_resize() has not been called
+ - passing -1 for either width or height reverts to "natural" request
+ in that dimension
+ - passing 0 is allowed, and results in requisition of 1x1
+ (0x0 is a permitted requisition, but equivalent to 1x1,
+ we use 1x1 for implementation convenience)
+ - causes notifies on width_request, height_request properties
+
+gtk_window_resize():
+ - causes a configure request in all cases if the window is mapped,
+ unless the new size is the same as the old size
+ - overrides the default size on map if the window is unmapped
+ - allows size of 0, equivalent to 1
+ - clamped to geometry hints
+
+gtk_window_set_default_size():
+ - has no effect after the window has been mapped the first time,
+ unless the window has been unrealized in which case it should
+ have an effect
+ - allows size of 0, equivalent to 1
+ - allows size of -1 to unset the default size
+ - clamped to geometry hints
+ - gtk_window_resize() overrides it
+ - causes notifies on default_width, default_height properties
+
+gtk_window_get_default_size():
+ - returns the values last passed to set_default_size(), including
+ -1. If set_default_size() has not been called, returns -1.
+
+gtk_window_move():
+ - always causes a configure request if the window is mapped,
+ unless the last configure request we sent was for the same
+ position being moved to
+ - position may be negative to move windows offscreen
+ - if GTK_WIN_POS_CENTER_ALWAYS (or other future position
+ constraints we may add) is in effect, the move
+ request is clamped to obey the constraints. thus
+ calling gtk_window_move() on a CENTER_ALWAYS window
+ may trigger the window to bounce back to center if it
+ wasn't there
+ - overrides all GTK_WIN_POS_ except CENTER_ALWAYS
+
+gtk_window_get_size():
+ - obtains the client-side known size of widget->window,
+ as last received from a configure event
+ - prior to mapping, returns the default size we will request
+ - between realization and mapping, computes default size
+ rather than looking at widget->window up-to-date size,
+ so the size will be correct after force-realizing a window
+
+gtk_window_get_position():
+ - obtains the point to be passed to gtk_window_move() in order
+ to keep the window in its current position
+ - round-trips to the server to get the position; this is suboptimal
+ from both a race condition and speed standpoint but required to get
+ window frame size
+ - if the window is unmapped, returns the default position we will
+ request
+
+gtk_window_set_position():
+ - not the inverse of get_position(), sadly
+ - modifies the default positioning of the window
+ - if set to CENTER_ALWAYS and the window is mapped, results in a
+ configure request moving the window to the center, unless the
+ window was already centered
+ - ignored if gtk_window_move() called, with the exception
+ of CENTER_ALWAYS
+
+gtk_window_parse_geometry():
+ - parses a standard X geometry string
+ - toggles on one or both of GDK_HINT_USER_SIZE, GDK_HINT_USER_POS
+ - "xprop" shows user size/position are set on the window
+ - calls gtk_window_set_default_size() to set the window size
+ - calls gtk_window_move() to set the window position
+ - calls gtk_window_set_gravity() to set the window gravity
+
+gtk_window_reshow_with_initial_size():
+ - for use by GUI builders; unrealizes and re-shows the window,
+ using default size (and also position, but position
+ is reset on any hide anyway)
+ - window should be positioned and sized as it was on initial map,
+ barring odd window managers
+
+gtk_window_set_geometry_hints():
+ - if a hint is set with this function, we do not override it
+ in other parts of the code
+
+General behavior
+===
+
+ - no infinite loops or nasty fighting-the-user flicker during
+ operations such as moving/resizing a window
+
+Properties
+===
+
+GtkWindow::default_width, GtkWindow::default_height:
+ - default_width is -1 if unset, or >= 0 if
+ a default width is set
+ - default_height is -1 if unset, or >= 0 if
+ a default height is set
+
+GtkWindow::allow_grow, GtkWindow::resizable:
+ - equivalent properties; changing one notifies on the other
+ - if FALSE, we set the min size to the max size in the geometry
+ hints.
+ - If the app programmer has called gtk_window_set_geometry_hints()
+ however and set min or max size, we don't replace the hint they
+ set.
+
+GtkWidget::width_request, GtkWidget::height_request:
+ - if -1, default requisition of widget is used
+ - otherwise, override default requisition
+
+
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 03263adef..425cfe871 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -82,7 +82,9 @@ typedef enum
GDK_HINT_BASE_SIZE = 1 << 3,
GDK_HINT_ASPECT = 1 << 4,
GDK_HINT_RESIZE_INC = 1 << 5,
- GDK_HINT_WIN_GRAVITY = 1 << 6
+ GDK_HINT_WIN_GRAVITY = 1 << 6,
+ GDK_HINT_USER_POS = 1 << 7,
+ GDK_HINT_USER_SIZE = 1 << 8
} GdkWindowHints;
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 593c8d720..a757e6bbf 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -1309,7 +1309,9 @@ gdk_event_translate (GdkEvent *event,
(window_private->extension_events != 0))
_gdk_input_configure_event (&xevent->xconfigure, window);
- if (!window || GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
+ if (!window ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
return_val = FALSE;
else
{
@@ -1318,8 +1320,7 @@ gdk_event_translate (GdkEvent *event,
event->configure.width = xevent->xconfigure.width;
event->configure.height = xevent->xconfigure.height;
- if (!xevent->xconfigure.x &&
- !xevent->xconfigure.y &&
+ if (!xevent->xconfigure.send_event &&
!GDK_WINDOW_DESTROYED (window))
{
gint tx = 0;
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index c94f7a463..169cdb3a1 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1387,6 +1387,16 @@ gdk_window_set_geometry_hints (GdkWindow *window,
size_hints.x = 0;
size_hints.y = 0;
}
+
+ if (geom_mask & GDK_HINT_USER_POS)
+ {
+ size_hints.flags |= USPosition;
+ }
+
+ if (geom_mask & GDK_HINT_USER_SIZE)
+ {
+ size_hints.flags |= USSize;
+ }
if (geom_mask & GDK_HINT_MIN_SIZE)
{
diff --git a/gtk/gtkfixed.c b/gtk/gtkfixed.c
index 3b214886a..7e3cdff7d 100644
--- a/gtk/gtkfixed.c
+++ b/gtk/gtkfixed.c
@@ -25,7 +25,13 @@
*/
#include "gtkfixed.h"
+#include "gtkintl.h"
+enum {
+ CHILD_PROP_0,
+ CHILD_PROP_X,
+ CHILD_PROP_Y
+};
static void gtk_fixed_class_init (GtkFixedClass *klass);
static void gtk_fixed_init (GtkFixed *fixed);
@@ -44,6 +50,16 @@ static void gtk_fixed_forall (GtkContainer *container,
gpointer callback_data);
static GtkType gtk_fixed_child_type (GtkContainer *container);
+static void gtk_fixed_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_fixed_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
static GtkContainerClass *parent_class = NULL;
@@ -94,6 +110,29 @@ gtk_fixed_class_init (GtkFixedClass *class)
container_class->remove = gtk_fixed_remove;
container_class->forall = gtk_fixed_forall;
container_class->child_type = gtk_fixed_child_type;
+
+ container_class->set_child_property = gtk_fixed_set_child_property;
+ container_class->get_child_property = gtk_fixed_get_child_property;
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_X,
+ g_param_spec_int ("x",
+ _("X position"),
+ _("X position of child widget"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_Y,
+ g_param_spec_int ("y",
+ _("Y position"),
+ _("Y position of child widget"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
}
static GtkType
@@ -119,11 +158,32 @@ gtk_fixed_new (void)
return GTK_WIDGET (fixed);
}
+static GtkFixedChild*
+get_child (GtkFixed *fixed,
+ GtkWidget *widget)
+{
+ GList *children;
+
+ children = fixed->children;
+ while (children)
+ {
+ GtkFixedChild *child;
+
+ child = children->data;
+ children = children->next;
+
+ if (child->widget == widget)
+ return child;
+ }
+
+ return NULL;
+}
+
void
gtk_fixed_put (GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y)
+ gint x,
+ gint y)
{
GtkFixedChild *child_info;
@@ -137,20 +197,121 @@ gtk_fixed_put (GtkFixed *fixed,
gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
- fixed->children = g_list_append (fixed->children, child_info);
+ fixed->children = g_list_append (fixed->children, child_info);
+}
+
+static void
+gtk_fixed_move_internal (GtkFixed *fixed,
+ GtkWidget *widget,
+ gboolean change_x,
+ gint x,
+ gboolean change_y,
+ gint y)
+{
+ GtkFixedChild *child;
+
+ g_return_if_fail (GTK_IS_FIXED (fixed));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
+
+ child = get_child (fixed, widget);
+
+ g_assert (child);
+
+ gtk_widget_freeze_child_notify (widget);
+
+ if (change_x)
+ {
+ child->x = x;
+ gtk_widget_child_notify (widget, "x");
+ }
+
+ if (change_y)
+ {
+ child->y = y;
+ gtk_widget_child_notify (widget, "y");
+ }
+
+ gtk_widget_thaw_child_notify (widget);
+
+ if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
+ gtk_widget_queue_resize (GTK_WIDGET (fixed));
}
void
gtk_fixed_move (GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y)
+ gint x,
+ gint y)
+{
+ g_return_if_fail (GTK_IS_FIXED (fixed));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (widget->parent == GTK_WIDGET (fixed));
+
+ gtk_fixed_move_internal (fixed, widget, TRUE, x, TRUE, y);
+}
+
+static void
+gtk_fixed_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_X:
+ gtk_fixed_move_internal (GTK_FIXED (container),
+ child,
+ TRUE, g_value_get_int (value),
+ FALSE, 0);
+ break;
+ case CHILD_PROP_Y:
+ gtk_fixed_move_internal (GTK_FIXED (container),
+ child,
+ FALSE, 0,
+ TRUE, g_value_get_int (value));
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_fixed_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
+ GtkFixedChild *fixed_child;
+
+ fixed_child = get_child (GTK_FIXED (container), child);
+
+ switch (property_id)
+ {
+ case CHILD_PROP_X:
+ g_value_set_int (value, fixed_child->x);
+ break;
+ case CHILD_PROP_Y:
+ g_value_set_int (value, fixed_child->y);
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_fixed_map (GtkWidget *widget)
+{
+ GtkFixed *fixed;
GtkFixedChild *child;
GList *children;
- g_return_if_fail (GTK_IS_FIXED (fixed));
- g_return_if_fail (widget != NULL);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+ fixed = GTK_FIXED (widget);
children = fixed->children;
while (children)
@@ -158,17 +319,12 @@ gtk_fixed_move (GtkFixed *fixed,
child = children->data;
children = children->next;
- if (child->widget == widget)
- {
- child->x = x;
- child->y = y;
-
- if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
- gtk_widget_queue_resize (GTK_WIDGET (fixed));
-
- break;
- }
+ if (GTK_WIDGET_VISIBLE (child->widget) &&
+ !GTK_WIDGET_MAPPED (child->widget))
+ gtk_widget_map (child->widget);
}
+
+ gdk_window_show (widget->window);
}
static void
diff --git a/gtk/gtkfixed.h b/gtk/gtkfixed.h
index 95b49d68e..6e0bc593a 100644
--- a/gtk/gtkfixed.h
+++ b/gtk/gtkfixed.h
@@ -64,8 +64,8 @@ struct _GtkFixedClass
struct _GtkFixedChild
{
GtkWidget *widget;
- gint16 x;
- gint16 y;
+ gint x;
+ gint y;
};
@@ -73,12 +73,12 @@ GtkType gtk_fixed_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_fixed_new (void);
void gtk_fixed_put (GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y);
+ gint x,
+ gint y);
void gtk_fixed_move (GtkFixed *fixed,
GtkWidget *widget,
- gint16 x,
- gint16 y);
+ gint x,
+ gint y);
#ifdef __cplusplus
}
diff --git a/gtk/gtklayout.c b/gtk/gtklayout.c
index c50290509..07c0a89b5 100644
--- a/gtk/gtklayout.c
+++ b/gtk/gtklayout.c
@@ -51,44 +51,56 @@ enum {
PROP_HEIGHT
};
-static void gtk_layout_class_init (GtkLayoutClass *class);
-static void gtk_layout_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_layout_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_layout_init (GtkLayout *layout);
-
-static void gtk_layout_finalize (GObject *object);
-static void gtk_layout_realize (GtkWidget *widget);
-static void gtk_layout_unrealize (GtkWidget *widget);
-static void gtk_layout_map (GtkWidget *widget);
-static void gtk_layout_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_layout_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gint gtk_layout_expose (GtkWidget *widget,
- GdkEventExpose *event);
-
-static void gtk_layout_remove (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_layout_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void gtk_layout_set_adjustments (GtkLayout *layout,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj);
-
-static void gtk_layout_allocate_child (GtkLayout *layout,
- GtkLayoutChild *child);
-
-
-static void gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
- GtkLayout *layout);
+enum {
+ CHILD_PROP_0,
+ CHILD_PROP_X,
+ CHILD_PROP_Y
+};
+
+static void gtk_layout_class_init (GtkLayoutClass *class);
+static void gtk_layout_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_layout_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_layout_init (GtkLayout *layout);
+static void gtk_layout_finalize (GObject *object);
+static void gtk_layout_realize (GtkWidget *widget);
+static void gtk_layout_unrealize (GtkWidget *widget);
+static void gtk_layout_map (GtkWidget *widget);
+static void gtk_layout_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_layout_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gint gtk_layout_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_layout_remove (GtkContainer *container,
+ GtkWidget *widget);
+static void gtk_layout_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void gtk_layout_set_adjustments (GtkLayout *layout,
+ GtkAdjustment *hadj,
+ GtkAdjustment *vadj);
+static void gtk_layout_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_layout_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_layout_allocate_child (GtkLayout *layout,
+ GtkLayoutChild *child);
+static void gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
+ GtkLayout *layout);
+
static GtkWidgetClass *parent_class = NULL;
@@ -213,6 +225,26 @@ gtk_layout_set_vadjustment (GtkLayout *layout,
g_object_notify (G_OBJECT (layout), "vadjustment");
}
+static GtkLayoutChild*
+get_child (GtkLayout *layout,
+ GtkWidget *widget)
+{
+ GList *children;
+
+ children = layout->children;
+ while (children)
+ {
+ GtkLayoutChild *child;
+
+ child = children->data;
+ children = children->next;
+
+ if (child->widget == widget)
+ return child;
+ }
+
+ return NULL;
+}
void
gtk_layout_put (GtkLayout *layout,
@@ -235,38 +267,59 @@ gtk_layout_put (GtkLayout *layout,
if (GTK_WIDGET_REALIZED (layout))
gtk_widget_set_parent_window (child->widget, layout->bin_window);
-
+
gtk_widget_set_parent (child_widget, GTK_WIDGET (layout));
}
-void
-gtk_layout_move (GtkLayout *layout,
- GtkWidget *child_widget,
- gint x,
- gint y)
+static void
+gtk_layout_move_internal (GtkLayout *layout,
+ GtkWidget *widget,
+ gboolean change_x,
+ gint x,
+ gboolean change_y,
+ gint y)
{
- GList *tmp_list;
GtkLayoutChild *child;
g_return_if_fail (GTK_IS_LAYOUT (layout));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (widget->parent == GTK_WIDGET (layout));
+
+ child = get_child (layout, widget);
- tmp_list = layout->children;
- while (tmp_list)
+ g_assert (child);
+
+ gtk_widget_freeze_child_notify (widget);
+
+ if (change_x)
{
- child = tmp_list->data;
- tmp_list = tmp_list->next;
+ child->x = x;
+ gtk_widget_child_notify (widget, "x");
+ }
- if (child->widget == child_widget)
- {
- child->x = x;
- child->y = y;
+ if (change_y)
+ {
+ child->y = y;
+ gtk_widget_child_notify (widget, "y");
+ }
+
+ gtk_widget_thaw_child_notify (widget);
+
+ if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (layout))
+ gtk_widget_queue_resize (GTK_WIDGET (layout));
+}
- if (GTK_WIDGET_VISIBLE (child_widget) && GTK_WIDGET_VISIBLE (layout))
- gtk_widget_queue_resize (child_widget);
+void
+gtk_layout_move (GtkLayout *layout,
+ GtkWidget *child_widget,
+ gint x,
+ gint y)
+{
+ g_return_if_fail (GTK_IS_LAYOUT (layout));
+ g_return_if_fail (GTK_IS_WIDGET (child_widget));
+ g_return_if_fail (child_widget->parent == GTK_WIDGET (layout));
- return;
- }
- }
+ gtk_layout_move_internal (layout, child_widget, TRUE, x, TRUE, y);
}
static void
@@ -413,6 +466,29 @@ gtk_layout_class_init (GtkLayoutClass *class)
gobject_class->get_property = gtk_layout_get_property;
gobject_class->finalize = gtk_layout_finalize;
+ container_class->set_child_property = gtk_layout_set_child_property;
+ container_class->get_child_property = gtk_layout_get_child_property;
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_X,
+ g_param_spec_int ("x",
+ _("X position"),
+ _("X position of child widget"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_Y,
+ g_param_spec_int ("y",
+ _("Y position"),
+ _("Y position of child widget"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class,
PROP_HADJUSTMENT,
g_param_spec_object ("hadjustment",
@@ -528,6 +604,57 @@ gtk_layout_set_property (GObject *object,
}
}
+static void
+gtk_layout_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_X:
+ gtk_layout_move_internal (GTK_LAYOUT (container),
+ child,
+ TRUE, g_value_get_int (value),
+ FALSE, 0);
+ break;
+ case CHILD_PROP_Y:
+ gtk_layout_move_internal (GTK_LAYOUT (container),
+ child,
+ FALSE, 0,
+ TRUE, g_value_get_int (value));
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_layout_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkLayoutChild *layout_child;
+
+ layout_child = get_child (GTK_LAYOUT (container), child);
+
+ switch (property_id)
+ {
+ case CHILD_PROP_X:
+ g_value_set_int (value, layout_child->x);
+ break;
+ case CHILD_PROP_Y:
+ g_value_set_int (value, layout_child->y);
+ break;
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
static void
gtk_layout_init (GtkLayout *layout)
diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c
index e27fd1f43..bb81a3acf 100644
--- a/gtk/gtkplug.c
+++ b/gtk/gtkplug.c
@@ -156,7 +156,6 @@ gtk_plug_init (GtkPlug *plug)
window = GTK_WINDOW (plug);
window->type = GTK_WINDOW_TOPLEVEL;
- window->auto_shrink = TRUE;
}
static void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 12c4fc129..7e6c457d4 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -121,10 +121,8 @@ enum {
PROP_0,
PROP_NAME,
PROP_PARENT,
- PROP_X,
- PROP_Y,
- PROP_WIDTH,
- PROP_HEIGHT,
+ PROP_WIDTH_REQUEST,
+ PROP_HEIGHT_REQUEST,
PROP_VISIBLE,
PROP_SENSITIVE,
PROP_APP_PAINTABLE,
@@ -213,7 +211,6 @@ static gint gtk_widget_event_internal (GtkWidget *widget,
static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
static void gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
-static void gtk_widget_do_uposition (GtkWidget *widget);
static AtkObject* gtk_widget_real_get_accessible (GtkWidget *widget);
static void gtk_widget_accessible_interface_init (AtkImplementorIface *iface);
static AtkObject* gtk_widget_ref_accessible (AtkImplementor *implementor);
@@ -400,38 +397,21 @@ gtk_widget_class_init (GtkWidgetClass *klass)
_("The parent widget of this widget. Must be a Container widget."),
GTK_TYPE_CONTAINER,
G_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class,
- PROP_X,
- g_param_spec_int ("x",
- _("x coordinate"),
- _("The x coordinate of the top-left corner of the widget, or -1 if not set"),
- -G_MAXINT,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_Y,
- g_param_spec_int ("y",
- _("y coordinate"),
- _("The y coordinate of the top-left corner of the widget, or -1 if not set"),
- -G_MAXINT,
- G_MAXINT,
- -1,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_WIDTH,
- g_param_spec_int ("width",
- _("Width"),
- _("The width of the widget, or -1 if unset."),
+ PROP_WIDTH_REQUEST,
+ g_param_spec_int ("width_request",
+ _("Width request"),
+ _("Override for width request of the widget, or -1 if natural request should be used."),
-1,
G_MAXINT,
-1,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
- PROP_HEIGHT,
- g_param_spec_int ("height",
- _("Height"),
- _("The height of the widget, or -1 if unset."),
+ PROP_HEIGHT_REQUEST,
+ g_param_spec_int ("height_request",
+ _("Height request"),
+ _("Override for height request of the widget, or -1 if natural request should be used."),
-1,
G_MAXINT,
-1,
@@ -1078,7 +1058,6 @@ gtk_widget_set_property (GObject *object,
GParamSpec *pspec)
{
GtkWidget *widget;
- GtkWidgetAuxInfo *aux_info;
widget = GTK_WIDGET (object);
@@ -1092,32 +1071,10 @@ gtk_widget_set_property (GObject *object,
case PROP_PARENT:
gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
break;
- case PROP_X:
- aux_info = _gtk_widget_get_aux_info (widget, TRUE);
- if (g_value_get_int (value) == -1)
- aux_info->x_set = FALSE;
- else
- {
- aux_info->x_set = TRUE;
- aux_info->x = g_value_get_int (value);
- }
- gtk_widget_do_uposition (widget);
- break;
- case PROP_Y:
- aux_info = _gtk_widget_get_aux_info (widget, TRUE);
- if (g_value_get_int (value) == -1)
- aux_info->y_set = FALSE;
- else
- {
- aux_info->y_set = TRUE;
- aux_info->y = g_value_get_int (value);
- }
- gtk_widget_do_uposition (widget);
- break;
- case PROP_WIDTH:
+ case PROP_WIDTH_REQUEST:
gtk_widget_set_usize (widget, g_value_get_int (value), -2);
break;
- case PROP_HEIGHT:
+ case PROP_HEIGHT_REQUEST:
gtk_widget_set_usize (widget, -2, g_value_get_int (value));
break;
case PROP_VISIBLE:
@@ -1191,7 +1148,6 @@ gtk_widget_get_property (GObject *object,
switch (prop_id)
{
- GtkWidgetAuxInfo *aux_info;
gint *eventp;
GdkExtensionMode *modep;
@@ -1207,33 +1163,19 @@ gtk_widget_get_property (GObject *object,
else
g_value_set_object (value, NULL);
break;
- case PROP_X:
- aux_info =_gtk_widget_get_aux_info (widget, FALSE);
- if (!aux_info || !aux_info->x_set)
- g_value_set_int (value, -1);
- else
- g_value_set_int (value, aux_info->x);
- break;
- case PROP_Y:
- aux_info =_gtk_widget_get_aux_info (widget, FALSE);
- if (!aux_info || !aux_info->y_set)
- g_value_set_int (value, -1);
- else
- g_value_set_int (value, aux_info->y);
- break;
- case PROP_WIDTH:
- aux_info =_gtk_widget_get_aux_info (widget, FALSE);
- if (!aux_info)
- g_value_set_int (value, -1);
- else
- g_value_set_int (value, aux_info->width);
+ case PROP_WIDTH_REQUEST:
+ {
+ int w;
+ gtk_widget_get_size_request (widget, &w, NULL);
+ g_value_set_int (value, w);
+ }
break;
- case PROP_HEIGHT:
- aux_info =_gtk_widget_get_aux_info (widget, FALSE);
- if (!aux_info)
- g_value_set_int (value, -1);
- else
- g_value_set_int (value, aux_info->height);
+ case PROP_HEIGHT_REQUEST:
+ {
+ int h;
+ gtk_widget_get_size_request (widget, NULL, &h);
+ g_value_set_int (value, h);
+ }
break;
case PROP_VISIBLE:
g_value_set_boolean (value, (GTK_WIDGET_VISIBLE (widget) != FALSE));
@@ -2247,10 +2189,20 @@ gtk_widget_draw (GtkWidget *widget,
* @widget: a #GtkWidget
* @requisition: a #GtkRequisition to be filled in
*
- * This function is only used when implementing a #GtkContainer subclass.
- * Obtains the preferred size of a widget. The container uses this
- * information to arrange its child widgets and decide what size allocations
- * to give them with gtk_widget_size_allocate().
+ * This function is typically used when implementing a #GtkContainer
+ * subclass. Obtains the preferred size of a widget. The container
+ * uses this information to arrange its child widgets and decide what
+ * size allocations to give them with gtk_widget_size_allocate().
+ *
+ * You can also call this function from an application, with some
+ * caveats. Most notably, getting a size request requires the widget
+ * to be associated with a screen, because font information may be
+ * needed. Multihead-aware applications should keep this in mind.
+ *
+ * Also remember that the size request is not necessarily the size
+ * a widget will actually be allocated.
+ *
+ * See also gtk_widget_get_child_requisition().
**/
void
gtk_widget_size_request (GtkWidget *widget,
@@ -2282,6 +2234,19 @@ gtk_widget_size_request (GtkWidget *widget,
* @widget->requisition, unless someone has forced a particular
* geometry on the widget (e.g. with gtk_widget_set_usize()), in which
* case it returns that geometry instead of the widget's requisition.
+ *
+ * This function differs from gtk_widget_size_request() in that
+ * it retrieves the last size request value from widget->requisition,
+ * while gtk_widget_size_request() actually calls the "size_request" method
+ * on @widget to compute the size request and fill in widget->requisition,
+ * and only then returns widget->requisition.
+ *
+ * Because this function does not call the "size_request" method, it
+ * can only be used when you know that widget->requisition is
+ * up-to-date, that is, gtk_widget_size_request() has been called
+ * since the last time a resize was queued. In general, only container
+ * implementations have this information; applications should use
+ * gtk_widget_size_request().
**/
void
gtk_widget_get_child_requisition (GtkWidget *widget,
@@ -4306,28 +4271,6 @@ gtk_widget_child_focus (GtkWidget *widget,
return return_val;
}
-/* Update the position from aux_info. Used from gtk_widget_set_uposition
- * and gtk_widget_set_property().
- */
-static void
-gtk_widget_do_uposition (GtkWidget *widget)
-{
- GtkWidgetAuxInfo *aux_info =_gtk_widget_get_aux_info (widget, FALSE);
-
- if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
- _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
-
- if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
- gtk_widget_size_allocate (widget, &widget->allocation);
-
- g_object_freeze_notify (G_OBJECT (widget));
- if (aux_info->x_set)
- g_object_notify (G_OBJECT (widget), "x");
- if (aux_info->y_set)
- g_object_notify (G_OBJECT (widget), "y");
- g_object_thaw_notify (G_OBJECT (widget));
-}
-
/**
* gtk_widget_set_uposition:
* @widget: a #GtkWidget
@@ -4356,6 +4299,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
gint x,
gint y)
{
+ /* FIXME this function is the only place that aux_info->x and
+ * aux_info->y are even used I believe, and this function is
+ * deprecated. Should be cleaned up.
+ */
+
GtkWidgetAuxInfo *aux_info;
g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -4384,7 +4332,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
}
}
- gtk_widget_do_uposition (widget);
+ if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
+ _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
+
+ if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
+ gtk_widget_size_allocate (widget, &widget->allocation);
}
/**
@@ -4393,6 +4345,9 @@ gtk_widget_set_uposition (GtkWidget *widget,
* @width: minimum width, or -1 to unset
* @height: minimum height, or -1 to unset
*
+ * This function is deprecated; use gtk_widget_set_size_request()
+ * instead.
+ *
* Sets the minimum size of a widget; that is, the widget's size
* request will be @width by @height. You can use this function to
* force a widget to be either larger or smaller than it is. The
@@ -4427,12 +4382,12 @@ gtk_widget_set_usize (GtkWidget *widget,
if (width > -2)
{
- g_object_notify (G_OBJECT (widget), "width");
+ g_object_notify (G_OBJECT (widget), "width_request");
aux_info->width = width;
}
if (height > -2)
{
- g_object_notify (G_OBJECT (widget), "height");
+ g_object_notify (G_OBJECT (widget), "height_request");
aux_info->height = height;
}
@@ -4443,21 +4398,79 @@ gtk_widget_set_usize (GtkWidget *widget,
}
/**
- * gtk_widget_get_usize:
+ * gtk_widget_set_size_request:
+ * @widget: a #GtkWidget
+ * @width: width @widget should request, or -1 to unset
+ * @height: height @widget should request, or -1 to unset
+ *
+ * Sets the minimum size of a widget; that is, the widget's size
+ * request will be @width by @height. You can use this function to
+ * force a widget to be either larger or smaller than it normally
+ * would be.
+ *
+ * In most cases, gtk_window_set_default_size() is a better choice for
+ * toplevel windows than this function; setting the default size will
+ * still allow users to shrink the window. Setting the size request
+ * will force them to leave the window at least as large as the size
+ * request. When dealing with window sizes,
+ * gtk_window_set_geometry_hints() can be a useful function as well.
+ *
+ * Note the inherent danger of setting any fixed size - themes,
+ * translations into other languages, different fonts, and user action
+ * can all change the appropriate size for a given widget. So, it's
+ * basically impossible to hardcode a size that will always be
+ * correct.
+ *
+ * The size request of a widget is the smallest size a widget can
+ * accept while still functioning well and drawing itself correctly.
+ * However in some strange cases a widget may be allocated less than
+ * its requested size, and in many cases a widget may be allocated more
+ * space than it requested.
+ *
+ * If the size request in a given direction is -1 (unset), then
+ * the "natural" size request of the widget will be used instead.
+ *
+ * Widgets can't actually be allocated a size less than 1 by 1, but
+ * you can pass 0,0 to this function to mean "as small as possible."
+ **/
+void
+gtk_widget_set_size_request (GtkWidget *widget,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ gtk_widget_set_usize (widget, width, height);
+}
+
+
+/**
+ * gtk_widget_get_size_request:
* @widget: a #GtkWidget
- * @width: location to store the width, or %NULL
- * @height: location to store the height, or %NULL
+ * @width: return location for width, or %NULL
+ * @height: return location for height, or %NULL
*
- * Gets the size that has explicitely set for the widget to request,
- * if any. A value of -1 stored in @width or @height indicates that
- * that dimension has not been set explicitely and the natural
- * requisition of the widget will be used intead. See
- * gtk_widget_set_usize().
+ * Gets the size request that was explicitly set for the widget using
+ * gtk_widget_set_size_request(). A value of -1 stored in @width or
+ * @height indicates that that dimension has not been set explicitly
+ * and the natural requisition of the widget will be used intead. See
+ * gtk_widget_set_size_request(). To get the size a widget will
+ * actually use, call gtk_widget_size_request() instead of
+ * this function.
+ *
**/
+
void
-gtk_widget_get_usize (GtkWidget *widget,
- gint *width,
- gint *height)
+gtk_widget_get_size_request (GtkWidget *widget,
+ gint *width,
+ gint *height)
{
GtkWidgetAuxInfo *aux_info;
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index fcd48c1ad..a6a7044e6 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -562,6 +562,14 @@ GtkWidget *gtk_widget_get_parent (GtkWidget *widget);
GdkWindow *gtk_widget_get_parent_window (GtkWidget *widget);
gboolean gtk_widget_child_focus (GtkWidget *widget,
GtkDirectionType direction);
+
+void gtk_widget_set_size_request (GtkWidget *widget,
+ gint width,
+ gint height);
+void gtk_widget_get_size_request (GtkWidget *widget,
+ gint *width,
+ gint *height);
+#ifndef GTK_DISABLE_DEPRECATED
void gtk_widget_set_uposition (GtkWidget *widget,
gint x,
gint y);
@@ -571,6 +579,8 @@ void gtk_widget_set_usize (GtkWidget *widget,
void gtk_widget_get_usize (GtkWidget *widget,
gint *width,
gint *height);
+#endif
+
void gtk_widget_set_events (GtkWidget *widget,
gint events);
void gtk_widget_add_events (GtkWidget *widget,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index e69a393b2..e44efd428 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -66,7 +66,6 @@ enum {
/* Style Props */
PROP_TITLE,
- PROP_AUTO_SHRINK,
PROP_ALLOW_SHRINK,
PROP_ALLOW_GROW,
PROP_RESIZABLE,
@@ -82,8 +81,7 @@ enum {
typedef struct {
GdkGeometry geometry; /* Last set of geometry hints we set */
GdkWindowHints flags;
- gint width;
- gint height;
+ GdkRectangle configure_request;
} GtkWindowLastGeometryInfo;
struct _GtkWindowGeometryInfo
@@ -93,10 +91,30 @@ struct _GtkWindowGeometryInfo
GdkGeometry geometry; /* Geometry hints */
GdkWindowHints mask;
GtkWidget *widget; /* subwidget to which hints apply */
- gint width; /* Default size */
- gint height;
- guint may_shrink : 1; /* one-shot auto_shrink behaviour after set_default_size */
+ /* from last gtk_window_resize () - if > 0, indicates that
+ * we should resize to this size.
+ */
+ gint resize_width;
+ gint resize_height;
+ /* From last gtk_window_move () prior to mapping -
+ * only used if initial_pos_set
+ */
+ gint initial_x;
+ gint initial_y;
+
+ /* Default size - used only the FIRST time we map a window,
+ * only if > 0.
+ */
+ gint default_width;
+ gint default_height;
+ /* whether to use initial_x, initial_y */
+ guint initial_pos_set : 1;
+ /* CENTER_ALWAYS or other position constraint changed since
+ * we sent the last configure request.
+ */
+ guint position_constraints_changed : 1;
+
GtkWindowLastGeometryInfo last;
};
@@ -153,31 +171,6 @@ static void gtk_window_real_activate_default (GtkWindow *window);
static void gtk_window_real_activate_focus (GtkWindow *window);
static void gtk_window_move_focus (GtkWindow *window,
GtkDirectionType dir);
-
-static void gtk_window_move_resize (GtkWindow *window);
-static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
- guint flags_a,
- GdkGeometry *geometry_b,
- guint flags_b);
-static void gtk_window_compute_default_size (GtkWindow *window,
- guint *width,
- guint *height);
-static void gtk_window_constrain_size (GtkWindow *window,
- GdkGeometry *geometry,
- guint flags,
- gint width,
- gint height,
- gint *new_width,
- gint *new_height);
-static void gtk_window_compute_hints (GtkWindow *window,
- GdkGeometry *new_geometry,
- guint *new_flags);
-static gint gtk_window_compute_reposition (GtkWindow *window,
- gint new_width,
- gint new_height,
- gint *x,
- gint *y);
-
static void gtk_window_read_rcfiles (GtkWidget *widget,
GdkEventClient *event);
static void gtk_window_paint (GtkWidget *widget,
@@ -190,8 +183,39 @@ static void gtk_window_transient_parent_realized (GtkWidget *parent,
static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
GtkWidget *window);
-static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
- gboolean create);
+static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
+ gboolean create);
+
+static void gtk_window_move_resize (GtkWindow *window);
+static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
+ guint flags_a,
+ GdkGeometry *geometry_b,
+ guint flags_b);
+static void gtk_window_constrain_size (GtkWindow *window,
+ GdkGeometry *geometry,
+ guint flags,
+ gint width,
+ gint height,
+ gint *new_width,
+ gint *new_height);
+static void gtk_window_constrain_position (GtkWindow *window,
+ gint new_width,
+ gint new_height,
+ gint *x,
+ gint *y);
+static void gtk_window_compute_hints (GtkWindow *window,
+ GdkGeometry *new_geometry,
+ guint *new_flags);
+static void gtk_window_compute_configure_request (GtkWindow *window,
+ GdkRectangle *request,
+ GdkGeometry *geometry,
+ guint *flags);
+
+static void gtk_window_set_default_size_internal (GtkWindow *window,
+ gboolean change_width,
+ gint width,
+ gboolean change_height,
+ gint height);
static GSList *toplevel_list = NULL;
@@ -335,18 +359,10 @@ gtk_window_class_init (GtkWindowClass *klass)
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
- PROP_AUTO_SHRINK,
- g_param_spec_boolean ("auto_shrink",
- _("Auto Shrink"),
- _("If TRUE, the window automatically shrinks to its size request anytime a resize occurs. Don't use this feature, it makes no sense."),
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
PROP_ALLOW_SHRINK,
g_param_spec_boolean ("allow_shrink",
_("Allow Shrink"),
- _("If TRUE, the window has no mimimum size. Don't use this feature, it makes no sense."),
+ _("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea."),
FALSE,
G_PARAM_READWRITE));
@@ -387,22 +403,22 @@ gtk_window_class_init (GtkWindowClass *klass)
PROP_DEFAULT_WIDTH,
g_param_spec_int ("default_width",
_("Default Width"),
- _("The default width of the window, or 0 to use the size request."),
- 0,
+ _("The default width of the window, used when initially showing the window."),
+ -1,
G_MAXINT,
- 0,
+ -1,
G_PARAM_READWRITE));
-
+
g_object_class_install_property (gobject_class,
PROP_DEFAULT_HEIGHT,
g_param_spec_int ("default_height",
_("Default Height"),
- _("The default height of the window, or 0 to use the size request."),
- 0,
+ _("The default height of the window, used when initially showing the window."),
+ -1,
G_MAXINT,
- 0,
+ -1,
G_PARAM_READWRITE));
-
+
g_object_class_install_property (gobject_class,
PROP_DESTROY_WITH_PARENT,
g_param_spec_boolean ("destroy_with_parent",
@@ -552,13 +568,13 @@ gtk_window_init (GtkWindow *window)
window->type = GTK_WINDOW_TOPLEVEL;
window->focus_widget = NULL;
window->default_widget = NULL;
- window->resize_count = 0;
+ window->configure_request_count = 0;
window->allow_shrink = FALSE;
window->allow_grow = TRUE;
- window->auto_shrink = FALSE;
- window->handling_resize = FALSE;
+ window->configure_notify_received = FALSE;
window->position = GTK_WIN_POS_NONE;
- window->use_uposition = TRUE;
+ window->need_default_size = TRUE;
+ window->need_default_position = TRUE;
window->modal = FALSE;
window->frame = NULL;
window->has_frame = FALSE;
@@ -591,7 +607,7 @@ gtk_window_set_property (GObject *object,
GParamSpec *pspec)
{
GtkWindow *window;
-
+
window = GTK_WINDOW (object);
switch (prop_id)
@@ -602,10 +618,6 @@ gtk_window_set_property (GObject *object,
case PROP_TITLE:
gtk_window_set_title (window, g_value_get_string (value));
break;
- case PROP_AUTO_SHRINK:
- window->auto_shrink = g_value_get_boolean (value);
- gtk_widget_queue_resize (GTK_WIDGET (window));
- break;
case PROP_ALLOW_SHRINK:
window->allow_shrink = g_value_get_boolean (value);
gtk_widget_queue_resize (GTK_WIDGET (window));
@@ -627,10 +639,14 @@ gtk_window_set_property (GObject *object,
gtk_window_set_position (window, g_value_get_enum (value));
break;
case PROP_DEFAULT_WIDTH:
- gtk_window_set_default_size (window, g_value_get_int (value), -1);
+ gtk_window_set_default_size_internal (window,
+ TRUE, g_value_get_int (value),
+ FALSE, -1);
break;
case PROP_DEFAULT_HEIGHT:
- gtk_window_set_default_size (window, -1, g_value_get_int (value));
+ gtk_window_set_default_size_internal (window,
+ FALSE, -1,
+ TRUE, g_value_get_int (value));
break;
case PROP_DESTROY_WITH_PARENT:
gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
@@ -659,9 +675,6 @@ gtk_window_get_property (GObject *object,
case PROP_TITLE:
g_value_set_string (value, window->title);
break;
- case PROP_AUTO_SHRINK:
- g_value_set_boolean (value, window->auto_shrink);
- break;
case PROP_ALLOW_SHRINK:
g_value_set_boolean (value, window->allow_shrink);
break;
@@ -680,16 +693,16 @@ gtk_window_get_property (GObject *object,
case PROP_DEFAULT_WIDTH:
info = gtk_window_get_geometry_info (window, FALSE);
if (!info)
- g_value_set_int (value, 0);
+ g_value_set_int (value, -1);
else
- g_value_set_int (value, info->width);
+ g_value_set_int (value, info->default_width);
break;
case PROP_DEFAULT_HEIGHT:
info = gtk_window_get_geometry_info (window, FALSE);
if (!info)
- g_value_set_int (value, 0);
+ g_value_set_int (value, -1);
else
- g_value_set_int (value, info->height);
+ g_value_set_int (value, info->default_height);
break;
case PROP_DESTROY_WITH_PARENT:
g_value_set_boolean (value, window->destroy_with_parent);
@@ -950,12 +963,10 @@ gtk_window_set_policy (GtkWindow *window,
window->allow_shrink = (allow_shrink != FALSE);
window->allow_grow = (allow_grow != FALSE);
- window->auto_shrink = (auto_shrink != FALSE);
g_object_notify (G_OBJECT (window), "allow_shrink");
g_object_notify (G_OBJECT (window), "allow_grow");
g_object_notify (G_OBJECT (window), "resizable");
- g_object_notify (G_OBJECT (window), "auto_shrink");
gtk_widget_queue_resize (GTK_WIDGET (window));
}
@@ -1125,8 +1136,24 @@ gtk_window_set_position (GtkWindow *window,
{
g_return_if_fail (GTK_IS_WINDOW (window));
- window->position = position;
+ if (position == GTK_WIN_POS_CENTER_ALWAYS ||
+ window->position == GTK_WIN_POS_CENTER_ALWAYS)
+ {
+ GtkWindowGeometryInfo *info;
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ /* this flag causes us to re-request the CENTER_ALWAYS
+ * constraint in gtk_window_move_resize(), see
+ * comment in that function.
+ */
+ info->position_constraints_changed = TRUE;
+
+ gtk_widget_queue_resize (GTK_WIDGET (window));
+ }
+
+ window->position = position;
+
g_object_notify (G_OBJECT (window), "window_position");
}
@@ -1293,25 +1320,7 @@ _gtk_window_reposition (GtkWindow *window,
g_return_if_fail (GTK_IS_WINDOW (window));
- /* keep this in sync with gtk_window_compute_reposition()
- */
- if (GTK_WIDGET_REALIZED (window))
- {
- info = gtk_window_get_geometry_info (window, TRUE);
-
- if (!(info->last.flags & GDK_HINT_POS))
- {
- info->last.flags |= GDK_HINT_POS;
- gdk_window_set_geometry_hints (GTK_WIDGET (window)->window,
- &info->last.geometry,
- info->last.flags);
- }
-
- if (window->frame)
- gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
- else
- gdk_window_move (GTK_WIDGET (window)->window, x, y);
- }
+ gtk_window_move (window, x, y);
}
static void
@@ -1573,13 +1582,20 @@ gtk_window_get_geometry_info (GtkWindow *window,
{
info = g_new0 (GtkWindowGeometryInfo, 1);
- info->width = 0;
- info->height = 0;
- info->last.width = -1;
- info->last.height = -1;
+ info->default_width = -1;
+ info->default_height = -1;
+ info->resize_width = -1;
+ info->resize_height = -1;
+ info->initial_x = 0;
+ info->initial_y = 0;
+ info->initial_pos_set = FALSE;
+ info->position_constraints_changed = FALSE;
+ info->last.configure_request.x = 0;
+ info->last.configure_request.y = 0;
+ info->last.configure_request.width = -1;
+ info->last.configure_request.height = -1;
info->widget = NULL;
info->mask = 0;
- info->may_shrink = FALSE;
window->geometry_info = info;
}
@@ -1625,8 +1641,14 @@ gtk_window_set_geometry_hints (GtkWindow *window,
if (geometry)
info->geometry = *geometry;
- info->mask = geom_mask;
+ /* We store gravity in window->gravity not in the hints. */
+ info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
+ if (geom_mask & GDK_HINT_WIN_GRAVITY)
+ {
+ gtk_window_set_gravity (window, geometry->win_gravity);
+ }
+
gtk_widget_queue_resize (GTK_WIDGET (window));
}
@@ -1683,21 +1705,73 @@ gtk_window_get_decorated (GtkWindow *window)
return window->decorated;
}
+static void
+gtk_window_set_default_size_internal (GtkWindow *window,
+ gboolean change_width,
+ gint width,
+ gboolean change_height,
+ gint height)
+{
+ GtkWindowGeometryInfo *info;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (change_width == FALSE || width >= -1);
+ g_return_if_fail (change_height == FALSE || height >= -1);
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ g_object_freeze_notify (G_OBJECT (window));
+
+ if (change_width)
+ {
+ if (width == 0)
+ width = 1;
+
+ if (width < 0)
+ width = -1;
+
+ info->default_width = width;
+
+ g_object_notify (G_OBJECT (window), "default_width");
+ }
+
+ if (change_height)
+ {
+ if (height == 0)
+ height = 1;
+
+ if (height < 0)
+ height = -1;
+
+ info->default_height = height;
+
+ g_object_notify (G_OBJECT (window), "default_height");
+ }
+
+ g_object_thaw_notify (G_OBJECT (window));
+
+ gtk_widget_queue_resize (GTK_WIDGET (window));
+}
+
/**
* gtk_window_set_default_size:
* @window: a #GtkWindow
- * @width: width in pixels, 0 to unset, or -1 to leave the width unchanged
- * @height: height in pixels, 0 to unset, or -1 to leave the height unchanged
+ * @width: width in pixels, or -1 to unset the default width
+ * @height: height in pixels, or -1 to unset the default height
*
* Sets the default size of a window. If the window's "natural" size
* (its size request) is larger than the default, the default will be
- * ignored. So the default size is a minimum initial size. Unlike
- * gtk_widget_set_usize(), which sets a size request for a widget and
- * thus would keep users from shrinking the window, this function only
- * sets the initial size, just as if the user had resized the window
- * themselves. Users can still shrink the window again as they
- * normally would. Setting a default size of 0 means to use the
- * "natural" default size (the size request of the window).
+ * ignored. More generally, if the default size does not obey the
+ * geometry hints for the window (gtk_window_set_geometry_hints() can
+ * be used to set these explicitly), the default size will be clamped
+ * to the nearest permitted size.
+ *
+ * Unlike gtk_widget_set_size_request(), which sets a size request for
+ * a widget and thus would keep users from shrinking the window, this
+ * function only sets the initial size, just as if the user had
+ * resized the window themselves. Users can still shrink the window
+ * again as they normally would. Setting a default size of -1 means to
+ * use the "natural" default size (the size request of the window).
*
* For more control over a window's initial size and how resizing works,
* investigate gtk_window_set_geometry_hints().
@@ -1706,35 +1780,29 @@ gtk_window_get_decorated (GtkWindow *window)
* gtk_window_set_geometry_hints(), the default size specified by
* gtk_window_set_default_size() will be the default size of that
* widget, not of the entire window.
- *
+ *
+ * For some uses, gtk_window_resize() is a more appropriate function.
+ * gtk_window_resize() changes the current size of the window, rather
+ * than the size to be used on initial display. gtk_window_resize() always
+ * affects the window itself, not the geometry widget.
+ *
+ * The default size of a window only affects the first time a window is
+ * shown; if a window is hidden and re-shown, it will remember the size
+ * it had prior to hiding, rather than using the default size.
+ *
+ * Windows can't actually be 0x0 in size, they must be at least 1x1, but
+ * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
**/
void
gtk_window_set_default_size (GtkWindow *window,
gint width,
gint height)
{
- GtkWindowGeometryInfo *info;
-
g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (width >= -1);
+ g_return_if_fail (height >= -1);
- info = gtk_window_get_geometry_info (window, TRUE);
-
- g_object_freeze_notify (G_OBJECT (window));
- if (width >= 0)
- {
- info->width = width;
- g_object_notify (G_OBJECT (window), "default_width");
- info->may_shrink = TRUE;
- }
- if (height >= 0)
- {
- info->height = height;
- g_object_notify (G_OBJECT (window), "default_height");
- info->may_shrink = TRUE;
- }
- g_object_thaw_notify (G_OBJECT (window));
-
- gtk_widget_queue_resize (GTK_WIDGET (window));
+ gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height);
}
/**
@@ -1743,10 +1811,11 @@ gtk_window_set_default_size (GtkWindow *window,
* @width: location to store the default width, or %NULL
* @height: location to store the default height, or %NULL
*
- * Gets the default size of the window. A value of 0 for the
- * width or height indicates that a default size has not
- * been explicitely set for that dimension, so the value
- * will be computed from the requisition of the window.
+ * Gets the default size of the window. A value of -1 for the width or
+ * height indicates that a default size has not been explicitly set
+ * for that dimension, so the "natural" size of the window will be
+ * used.
+ *
**/
void
gtk_window_get_default_size (GtkWindow *window,
@@ -1760,12 +1829,425 @@ gtk_window_get_default_size (GtkWindow *window,
info = gtk_window_get_geometry_info (window, FALSE);
if (width)
- *width = info ? info->width : 0;
+ *width = info->default_width;
+
+ if (height)
+ *height = info->default_height;
+}
+
+/**
+ * gtk_window_resize:
+ * @window: a #GtkWindow
+ * @width: width to resize the window to
+ * @height: height to resize the window to
+ *
+ * Resizes the window as if the user had done so, obeying geometry
+ * constraints. The default geometry constraint is that windows may
+ * not be smaller than their size request; to override this
+ * constraint, call gtk_widget_set_size_request() to set the window's
+ * request to a smaller value.
+ *
+ * If gtk_window_resize() is called before showing a window for the
+ * first time, it overrides any default size set with
+ * gtk_window_set_default_size().
+ *
+ * Windows may not be resized smaller than 1 by 1 pixels.
+ *
+ **/
+void
+gtk_window_resize (GtkWindow *window,
+ gint width,
+ gint height)
+{
+ GtkWindowGeometryInfo *info;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ info->resize_width = width;
+ info->resize_height = height;
+
+ gtk_widget_queue_resize (GTK_WIDGET (window));
+}
+
+/**
+ * gtk_window_get_size:
+ * @window: a #GtkWindow
+ * @width: return location for width, or %NULL
+ * @height: return location for height, or %NULL
+ *
+ * Obtains the current size of @window. If @window is not onscreen,
+ * returns the size GTK+ will suggest to the window manager for the
+ * initial window size (but this is not reliably the same as the size
+ * the window manager will actually select). The size obtained by
+ * gtk_window_get_size() is the last size received in a
+ * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
+ * rather than querying the X server for the size. As a result, if you
+ * call gtk_window_resize() then immediately call
+ * gtk_window_get_size(), the size won't have taken effect yet. After
+ * the window manager processes the resize request, GTK+ receives
+ * notification that the size has changed via a configure event, and
+ * the size of the window gets updated.
+ *
+ * Note #1: Nearly any use of this function creates a race condition,
+ * because the size of the window may change between the time that you
+ * get the size and the time that you perform some action assuming
+ * that size is the current size. To avoid race conditions, connect to
+ * "configure_event" on the window and adjust your size-dependent
+ * state to match the size delivered in the #GdkEventConfigure.
+ *
+ * Note #2: The returned size does NOT include the size of the window
+ * manager decorations (aka the window frame or border). Those
+ * are not drawn by GTK+ and GTK+ has no reliable method of
+ * determining their size.
+ *
+ * Note #3: If you are getting a window size in order to position
+ * the window onscreen, there may be a better way. The preferred
+ * way is to simply set the window's semantic type with
+ * gtk_window_set_type_hint(), which allows the window manager to
+ * e.g. center dialogs. Also, if you set the transient parent of
+ * dialogs with gtk_widget_set_transient_for() window managers
+ * will often center the dialog over its parent window. It's
+ * much preferred to let the window manager handle these
+ * things rather than doing it yourself, because all apps will
+ * behave consistently and according to user prefs if the window
+ * manager handles it. Also, the window manager can take the size
+ * of the window decorations/border into account, while your
+ * application cannot.
+ *
+ * In any case, if you insist on application-specified window
+ * positioning, there's STILL a better way than doing it yourself -
+ * gtk_window_set_position() will frequently handle the details
+ * for you.
+ *
+ **/
+void
+gtk_window_get_size (GtkWindow *window,
+ gint *width,
+ gint *height)
+{
+ gint w, h;
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ widget = GTK_WIDGET (window);
+
+ if (width == NULL && height == NULL)
+ return;
+
+ if (GTK_WIDGET_MAPPED (window))
+ {
+ gdk_drawable_get_size (GTK_WIDGET (window)->window,
+ &w, &h);
+ }
+ else
+ {
+ GdkRectangle configure_request;
+
+ gtk_window_compute_configure_request (window,
+ &configure_request,
+ NULL, NULL);
+
+ w = configure_request.width;
+ h = configure_request.height;
+ }
+
+ if (width)
+ *width = w;
if (height)
- *height = info ? info->height : 0;
+ *height = h;
+}
+
+/**
+ * gtk_window_move:
+ * @window: a #GtkWindow
+ * @x: X coordinate to move window to
+ * @y: Y coordinate to move window to
+ *
+ * Asks the window manager to move @window to the given position.
+ * Window managers are free to ignore this; most window managers
+ * ignore requests for initial window positions (instead using a
+ * user-defined placement algorithm) and honor requests after the
+ * window has already been shown.
+ *
+ * Note: the position is the position of the gravity-determined
+ * reference point for the window. The gravity determines two things:
+ * first, the location of the reference point in root window
+ * coordinates; and second, which point on the window is positioned at
+ * the reference point.
+ *
+ * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
+ * point is simply the @x, @y supplied to gtk_window_move(). The
+ * top-left corner of the window decorations (aka window frame or
+ * border) will be placed at @x, @y. Therefore, to position a window
+ * at the top left of the screen, you want to use the default gravity
+ * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
+ *
+ * To position a window at the bottom right corner of the screen, you
+ * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
+ * point is at @x + the window width and @y + the window height, and
+ * the bottom-right corner of the window border will be placed at that
+ * reference point. So, to place a window in the bottom right corner
+ * you would first set gravity to south east, then write:
+ * gtk_window_move (window, gdk_screen_width () - window_width,
+ * gdk_screen_height () - window_height).
+ *
+ * The extended window manager hints specification at
+ * http://www.freedesktop.org/standards/wm-spec.html has a nice table
+ * of gravities in the "implementation notes" section.
+ *
+ * The gtk_window_get_position() documentation may also be relevant.
+ *
+ **/
+void
+gtk_window_move (GtkWindow *window,
+ gint x,
+ gint y)
+{
+ GtkWindowGeometryInfo *info;
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ widget = GTK_WIDGET (window);
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ if (GTK_WIDGET_MAPPED (window))
+ {
+ /* we have now sent a request with this position
+ * with currently-active constraints, so toggle flag.
+ */
+ info->position_constraints_changed = FALSE;
+
+ /* we only constrain if mapped - if not mapped,
+ * then gtk_window_compute_configure_request()
+ * will apply the constraints later, and we
+ * don't want to lose information about
+ * what position the user set before then.
+ * i.e. if you do a move() then turn off POS_CENTER
+ * then show the window, your move() will work.
+ */
+ gtk_window_constrain_position (window,
+ widget->allocation.width,
+ widget->allocation.height,
+ &x, &y);
+
+ /* Note that this request doesn't go through our standard request
+ * framework, e.g. doesn't increment configure_request_count,
+ * doesn't set info->last, etc.; that's because
+ * we don't save the info needed to arrive at this same request
+ * again.
+ *
+ * To gtk_window_move_resize(), this will end up looking exactly
+ * the same as the position being changed by the window
+ * manager.
+ */
+
+ /* FIXME are we handling gravity properly for framed windows? */
+ if (window->frame)
+ gdk_window_move (window->frame,
+ x - window->frame_left,
+ y - window->frame_top);
+ else
+ gdk_window_move (GTK_WIDGET (window)->window,
+ x, y);
+ }
+ else
+ {
+ /* Save this position to apply on mapping */
+ info->initial_x = x;
+ info->initial_y = y;
+ info->initial_pos_set = TRUE;
+ }
}
+
+/**
+ * gtk_window_get_position:
+ * @window: a #GtkWindow
+ * @root_x: return location for X coordinate of gravity-determined reference p\oint
+ * @root_y: return location for Y coordinate of gravity-determined reference p\oint
+ *
+ * This function returns the position you need to pass to
+ * gtk_window_move() to keep @window in its current position. This
+ * means that the meaning of the returned value varies with window
+ * gravity. See gtk_window_move() for more details.
+ *
+ * If you haven't changed the window gravity, its gravity will be
+ * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
+ * returns the position of the top-left corner of the window
+ * manager frame for the window. gtk_window_move() sets the
+ * position of this same top-left corner.
+ *
+ * gtk_window_get_position() is not 100% reliable because the X Window System
+ * does not specify a way to obtain the geometry of the
+ * decorations placed on a window by the window manager.
+ * Thus GTK+ is using a "best guess" that works with most
+ * window managers.
+ *
+ * Moreover, nearly all window managers are broken with respect to
+ * their handling of window gravity. So moving a window to its current
+ * position as returned by gtk_window_get_position() tends to
+ * result in moving the window slightly.
+ *
+ * If a window has gravity #GDK_GRAVITY_STATIC the window manager
+ * frame is not relevant, and thus gtk_window_get_position() will
+ * always produce accurate results. However you can't use static
+ * gravity to do things like place a window in a corner of the screen,
+ * because static gravity ignores the window manager decorations.
+ *
+ * If you are saving and restoring your application's window
+ * positions, you should know that it's impossible for applications to
+ * do this without getting it somewhat wrong because applications do
+ * not have sufficient knowledge of window manager state. The Correct
+ * Mechanism is to support the session management protocol (see the
+ * "GnomeClient" object in the GNOME libraries for example) and allow
+ * the window manager to save your window sizes and positions.
+ *
+ **/
+
+void
+gtk_window_get_position (GtkWindow *window,
+ gint *root_x,
+ gint *root_y)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ widget = GTK_WIDGET (window);
+ if (window->gravity == GDK_GRAVITY_STATIC)
+ {
+ if (GTK_WIDGET_MAPPED (widget))
+ {
+ /* This does a server round-trip, which is sort of wrong;
+ * but a server round-trip is inevitable for
+ * gdk_window_get_frame_extents() in the usual
+ * NorthWestGravity case below, so not sure what else to
+ * do. We should likely be consistent about whether we get
+ * the client-side info or the server-side info.
+ */
+ gdk_window_get_origin (widget->window, root_x, root_y);
+ }
+ else
+ {
+ GdkRectangle configure_request;
+
+ gtk_window_compute_configure_request (window,
+ &configure_request,
+ NULL, NULL);
+
+ *root_x = configure_request.x;
+ *root_y = configure_request.y;
+ }
+ }
+ else
+ {
+ GdkRectangle frame_extents;
+
+ gint x, y;
+ gint w, h;
+
+ if (GTK_WIDGET_MAPPED (widget))
+ {
+ gdk_window_get_frame_extents (widget->window, &frame_extents);
+ x = frame_extents.x;
+ y = frame_extents.y;
+ gtk_window_get_size (window, &w, &h);
+ }
+ else
+ {
+ /* We just say the frame has 0 size on all sides.
+ * Not sure what else to do.
+ */
+ gtk_window_compute_configure_request (window,
+ &frame_extents,
+ NULL, NULL);
+ x = frame_extents.x;
+ y = frame_extents.y;
+ w = frame_extents.width;
+ h = frame_extents.height;
+ }
+
+ switch (window->gravity)
+ {
+ case GDK_GRAVITY_NORTH:
+ case GDK_GRAVITY_CENTER:
+ case GDK_GRAVITY_SOUTH:
+ /* Find center of frame. */
+ x += frame_extents.width / 2;
+ /* Center client window on that point. */
+ x -= w / 2;
+ break;
+
+ case GDK_GRAVITY_SOUTH_EAST:
+ case GDK_GRAVITY_EAST:
+ case GDK_GRAVITY_NORTH_EAST:
+ /* Find right edge of frame */
+ x += frame_extents.width;
+ /* Align left edge of client at that point. */
+ x -= w;
+ break;
+ default:
+ break;
+ }
+
+ switch (window->gravity)
+ {
+ case GDK_GRAVITY_WEST:
+ case GDK_GRAVITY_CENTER:
+ case GDK_GRAVITY_EAST:
+ /* Find center of frame. */
+ y += frame_extents.height / 2;
+ /* Center client window there. */
+ y -= h / 2;
+ break;
+ case GDK_GRAVITY_SOUTH_WEST:
+ case GDK_GRAVITY_SOUTH:
+ case GDK_GRAVITY_SOUTH_EAST:
+ /* Find south edge of frame */
+ y += frame_extents.height;
+ /* Place bottom edge of client there */
+ y -= h;
+ break;
+ default:
+ break;
+ }
+
+ if (root_x)
+ *root_x = x;
+ if (root_y)
+ *root_y = y;
+ }
+}
+
+/**
+ * gtk_window_reshow_with_initial_size:
+ * @window: a #GtkWindow
+ *
+ * Hides @window, then reshows it, resetting the
+ * default size and position of the window. Used
+ * by GUI builders only.
+ **/
+void
+gtk_window_reshow_with_initial_size (GtkWindow *window)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ widget = GTK_WIDGET (window);
+
+ gtk_widget_hide (widget);
+ gtk_widget_unrealize (widget);
+ gtk_widget_show (widget);
+}
+
static void
gtk_window_destroy (GtkObject *object)
{
@@ -1863,44 +2345,56 @@ gtk_window_show (GtkWidget *widget)
{
GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
GtkAllocation allocation = { 0, 0 };
+ GdkRectangle configure_request;
GdkGeometry new_geometry;
- guint width, height, new_flags;
+ guint new_flags;
gboolean was_realized;
-
- /* determine default size to initially show the window with */
- gtk_widget_size_request (widget, NULL);
- gtk_window_compute_default_size (window, &width, &height);
-
- /* save away the last default size for later comparisions */
- info->last.width = width;
- info->last.height = height;
- /* constrain size to geometry */
- gtk_window_compute_hints (window, &new_geometry, &new_flags);
- gtk_window_constrain_size (window,
- &new_geometry, new_flags,
- width, height,
- &width, &height);
+ /* We are going to go ahead and perform this configure request
+ * and then emulate a configure notify by going ahead and
+ * doing a size allocate. Sort of a synchronous
+ * mini-copy of gtk_window_move_resize() here.
+ */
+ gtk_window_compute_configure_request (window,
+ &configure_request,
+ &new_geometry,
+ &new_flags);
- /* and allocate the window */
- allocation.width = width;
- allocation.height = height;
- gtk_widget_size_allocate (widget, &allocation);
+ /* We update this because we are going to go ahead
+ * and gdk_window_resize() below, rather than
+ * queuing it.
+ */
+ info->last.configure_request.width = configure_request.width;
+ info->last.configure_request.height = configure_request.height;
+ /* and allocate the window - this is normally done
+ * in move_resize in response to configure notify
+ */
+ allocation.width = configure_request.width;
+ allocation.height = configure_request.height;
+ gtk_widget_size_allocate (widget, &allocation);
+
+ /* Then we guarantee we have a realize */
was_realized = FALSE;
if (!GTK_WIDGET_REALIZED (widget))
{
gtk_widget_realize (widget);
- was_realized = TRUE;;
+ was_realized = TRUE;
}
/* Must be done after the windows are realized,
* so that the decorations can be read
*/
gtk_decorated_window_calculate_frame_size (window);
-
+
+ /* We only send configure request if we didn't just finish
+ * creating the window; if we just created the window
+ * then we created it with widget->allocation anyhow.
+ */
if (!was_realized)
- gdk_window_resize (widget->window, width, height);
+ gdk_window_resize (widget->window,
+ configure_request.width,
+ configure_request.height);
}
gtk_container_check_resize (container);
@@ -1963,6 +2457,10 @@ gtk_window_map (GtkWidget *widget)
gdk_window_iconify (toplevel);
else
gdk_window_deiconify (toplevel);
+
+ /* No longer use the default settings */
+ window->need_default_size = FALSE;
+ window->need_default_position = FALSE;
gdk_window_show (widget->window);
@@ -1974,8 +2472,7 @@ static void
gtk_window_unmap (GtkWidget *widget)
{
GtkWindow *window;
-
- g_return_if_fail (GTK_IS_WINDOW (widget));
+ GtkWindowGeometryInfo *info;
window = GTK_WINDOW (widget);
@@ -1984,11 +2481,22 @@ gtk_window_unmap (GtkWidget *widget)
gdk_window_withdraw (window->frame);
else
gdk_window_withdraw (widget->window);
+
+ window->configure_request_count = 0;
+ window->configure_notify_received = FALSE;
- window->use_uposition = TRUE;
- window->resize_count = 0;
- window->handling_resize = FALSE;
+ /* on unmap, we reset the default positioning of the window,
+ * so it's placed again, but we don't reset the default
+ * size of the window, so it's remembered.
+ */
+ window->need_default_position = TRUE;
+ info = gtk_window_get_geometry_info (window, FALSE);
+ if (info)
+ {
+ info->initial_pos_set = FALSE;
+ info->position_constraints_changed = FALSE;
+ }
}
static void
@@ -2130,11 +2638,30 @@ static void
gtk_window_unrealize (GtkWidget *widget)
{
GtkWindow *window;
-
- g_return_if_fail (GTK_IS_WINDOW (widget));
+ GtkWindowGeometryInfo *info;
window = GTK_WINDOW (widget);
+ /* On unrealize, we reset the size of the window such
+ * that we will re-apply the default sizing stuff
+ * next time we show the window.
+ *
+ * Default positioning is reset on unmap, instead of unrealize.
+ */
+ window->need_default_size = TRUE;
+ info = gtk_window_get_geometry_info (window, FALSE);
+ if (info)
+ {
+ info->resize_width = -1;
+ info->resize_height = -1;
+ info->last.configure_request.x = 0;
+ info->last.configure_request.y = 0;
+ info->last.configure_request.width = -1;
+ info->last.configure_request.height = -1;
+ /* be sure we reset geom hints on re-realize */
+ info->last.flags = 0;
+ }
+
if (window->frame)
{
gdk_window_set_user_data (window->frame, NULL);
@@ -2280,42 +2807,51 @@ gtk_window_configure_event (GtkWidget *widget,
window = GTK_WINDOW (widget);
- /* we got a configure event specifying the new window size and position,
- * in principle we have to distinguish 4 cases here:
- * 1) the size didn't change and resize_count == 0
- * -> the window was merely moved (sometimes not even that)
- * 2) the size didn't change and resize_count > 0
- * -> we requested a new size, but didn't get it
- * 3) the size changed and resize_count > 0
- * -> we asked for a new size and we got one
- * 4) the size changed and resize_count == 0
- * -> we got resized from outside the toolkit, and have to
- * accept that size since we don't want to fight neither the
- * window manager nor the user
- * in the three latter cases we have to reallocate the widget tree,
- * which happens in gtk_window_move_resize(), so we set a flag for
- * that function and assign the new size. if resize_count > 1,
- * we simply do nothing and wait for more configure events.
+ /* window->configure_request_count incremented for each
+ * configure request, and decremented to a min of 0 for
+ * each configure notify.
+ *
+ * All it means is that we know we will get at least
+ * window->configure_request_count more configure notifies.
+ * We could get more configure notifies than that; some
+ * of the configure notifies we get may be unrelated to
+ * the configure requests. But we will get at least
+ * window->configure_request_count notifies.
*/
- if (window->resize_count > 0 ||
- widget->allocation.width != event->width ||
- widget->allocation.height != event->height)
- {
- if (window->resize_count > 0)
- window->resize_count -= 1;
-
- if (window->resize_count == 0)
- {
- window->handling_resize = TRUE;
-
- widget->allocation.width = event->width;
- widget->allocation.height = event->height;
-
- gtk_widget_queue_resize (widget);
- }
- }
+ if (window->configure_request_count > 0)
+ window->configure_request_count -= 1;
+
+ /* As an optimization, we avoid a resize when possible.
+ *
+ * The only times we can avoid a resize are:
+ * - we know only the position changed, not the size
+ * - we know we have made more requests and so will get more
+ * notifies and can wait to resize when we get them
+ */
+
+ if (window->configure_request_count > 0 ||
+ (widget->allocation.width == event->width &&
+ widget->allocation.height == event->height))
+ return TRUE;
+ /*
+ * If we do need to resize, we do that by:
+ * - filling in widget->allocation with the new size
+ * - setting configure_notify_received to TRUE
+ * for use in gtk_window_move_resize()
+ * - queueing a resize, leading to invocation of
+ * gtk_window_move_resize() in an idle handler
+ *
+ */
+
+ window->configure_notify_received = TRUE;
+
+ widget->allocation.width = event->width;
+ widget->allocation.height = event->height;
+
+ gtk_widget_queue_resize (widget);
+
return TRUE;
}
@@ -2644,248 +3180,609 @@ gtk_window_real_set_focus (GtkWindow *window,
gtk_widget_queue_draw (window->default_widget);
}
-
-
/*********************************
* Functions related to resizing *
*********************************/
+/* This function doesn't constrain to geometry hints */
+static void
+gtk_window_compute_configure_request_size (GtkWindow *window,
+ guint *width,
+ guint *height)
+{
+ GtkRequisition requisition;
+ GtkWindowGeometryInfo *info;
+ GtkWidget *widget;
+
+ /* Preconditions:
+ * - we've done a size request
+ */
+
+ widget = GTK_WIDGET (window);
+
+ info = gtk_window_get_geometry_info (window, FALSE);
+
+ if (window->need_default_size)
+ {
+ gtk_widget_get_child_requisition (widget, &requisition);
+
+ /* Default to requisition */
+ *width = requisition.width;
+ *height = requisition.height;
+
+ /* If window is empty so requests 0, default to random nonzero size */
+ if (*width == 0 && *height == 0)
+ {
+ *width = 200;
+ *height = 200;
+ }
+
+ /* Override requisition with default size */
+
+ if (info)
+ {
+ if (info->default_width > 0)
+ *width = info->default_width;
+
+ if (info->default_height > 0)
+ *height = info->default_height;
+ }
+ }
+ else
+ {
+ /* Default to keeping current size */
+ *width = widget->allocation.width;
+ *height = widget->allocation.height;
+ }
+
+ /* Override any size with gtk_window_resize() values */
+ if (info)
+ {
+ if (info->resize_width > 0)
+ *width = info->resize_width;
+
+ if (info->resize_height > 0)
+ *height = info->resize_height;
+ }
+}
+
+static void
+gtk_window_compute_configure_request (GtkWindow *window,
+ GdkRectangle *request,
+ GdkGeometry *geometry,
+ guint *flags)
+{
+ GdkGeometry new_geometry;
+ guint new_flags;
+ int w, h;
+ GtkWidget *widget;
+ GtkWindowPosition pos;
+ GtkWidget *parent_widget;
+ GtkWindowGeometryInfo *info;
+ int x, y;
+
+ widget = GTK_WIDGET (window);
+
+ gtk_widget_size_request (widget, NULL);
+ gtk_window_compute_configure_request_size (window, &w, &h);
+
+ gtk_window_compute_hints (window, &new_geometry, &new_flags);
+ gtk_window_constrain_size (window,
+ &new_geometry, new_flags,
+ w, h,
+ &w, &h);
+
+ parent_widget = (GtkWidget*) window->transient_parent;
+
+ pos = window->position;
+ if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
+ (parent_widget == NULL ||
+ !GTK_WIDGET_MAPPED (parent_widget)))
+ pos = GTK_WIN_POS_NONE;
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ /* by default, don't change position requested */
+ x = info->last.configure_request.x;
+ y = info->last.configure_request.y;
+
+ if (window->need_default_position)
+ {
+
+ /* FIXME this all interrelates with window gravity.
+ * For most of them I think we want to set GRAVITY_CENTER.
+ *
+ * Not sure how to go about that.
+ */
+
+ switch (pos)
+ {
+ /* here we are only handling CENTER_ALWAYS
+ * as it relates to default positioning,
+ * where it's equivalent to simply CENTER
+ */
+ case GTK_WIN_POS_CENTER_ALWAYS:
+ case GTK_WIN_POS_CENTER:
+ {
+ gint screen_width = gdk_screen_width ();
+ gint screen_height = gdk_screen_height ();
+
+ x = (screen_width - w) / 2;
+ y = (screen_height - h) / 2;
+ }
+ break;
+
+ case GTK_WIN_POS_CENTER_ON_PARENT:
+ {
+ gint ox, oy;
+
+ g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
+
+ gdk_window_get_origin (parent_widget->window,
+ &ox, &oy);
+
+ x = ox + (parent_widget->allocation.width - w) / 2;
+ y = oy + (parent_widget->allocation.height - h) / 2;
+ }
+ break;
+
+ case GTK_WIN_POS_MOUSE:
+ {
+ gint screen_width = gdk_screen_width ();
+ gint screen_height = gdk_screen_height ();
+ int px, py;
+
+ gdk_window_get_pointer (NULL, &px, &py, NULL);
+ x = px - w / 2;
+ y = py - h / 2;
+ x = CLAMP (x, 0, screen_width - w);
+ y = CLAMP (y, 0, screen_height - h);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } /* if (window->need_default_position) */
+
+ if (window->need_default_position &&
+ info->initial_pos_set)
+ {
+ x = info->initial_x;
+ y = info->initial_y;
+ gtk_window_constrain_position (window, w, h, &x, &y);
+ }
+
+ request->x = x;
+ request->y = y;
+ request->width = w;
+ request->height = h;
+
+ if (geometry)
+ *geometry = new_geometry;
+ if (flags)
+ *flags = new_flags;
+}
+
+static void
+gtk_window_constrain_position (GtkWindow *window,
+ gint new_width,
+ gint new_height,
+ gint *x,
+ gint *y)
+{
+ /* See long comments in gtk_window_move_resize()
+ * on when it's safe to call this function.
+ */
+ if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
+ {
+ gint center_x, center_y;
+ gint screen_width = gdk_screen_width ();
+ gint screen_height = gdk_screen_height ();
+
+ center_x = (screen_width - new_width) / 2;
+ center_y = (screen_height - new_height) / 2;
+
+ *x = center_x;
+ *y = center_y;
+ }
+}
+
static void
gtk_window_move_resize (GtkWindow *window)
{
+ /* Overview:
+ *
+ * First we determine whether any information has changed that would
+ * cause us to revise our last configure request. If we would send
+ * a different configure request from last time, then
+ * configure_request_size_changed = TRUE or
+ * configure_request_pos_changed = TRUE. configure_request_size_changed
+ * may be true due to new hints, a gtk_window_resize(), or whatever.
+ * configure_request_pos_changed may be true due to gtk_window_set_position()
+ * or gtk_window_move().
+ *
+ * If the configure request has changed, we send off a new one. To
+ * ensure GTK invariants are maintained (resize queue does what it
+ * should), we go ahead and size_allocate the requested size in this
+ * function.
+ *
+ * If the configure request has not changed, we don't ever resend
+ * it, because it could mean fighting the user or window manager.
+ *
+ *
+ * To prepare the configure request, we come up with a base size/pos:
+ * - the one from gtk_window_move()/gtk_window_resize()
+ * - else default_width, default_height if we haven't ever
+ * been mapped
+ * - else the size request if we haven't ever been mapped,
+ * as a substitute default size
+ * - else the current size of the window, as received from
+ * configure notifies (i.e. the current allocation)
+ *
+ * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
+ * the position request to be centered.
+ */
GtkWidget *widget;
GtkContainer *container;
GtkWindowGeometryInfo *info;
- GtkWindowLastGeometryInfo saved_last_info;
GdkGeometry new_geometry;
guint new_flags;
- gint x, y;
- gint width, height;
- gint new_width, new_height;
- gboolean need_reposition;
- gboolean default_size_changed = FALSE;
- gboolean hints_changed = FALSE;
- gboolean may_shrink = window->auto_shrink;
-
- g_return_if_fail (GTK_WIDGET_REALIZED (window));
-
+ GdkRectangle new_request;
+ gboolean configure_request_size_changed;
+ gboolean configure_request_pos_changed;
+ gboolean hints_changed; /* do we need to send these again */
+ GtkWindowLastGeometryInfo saved_last_info;
+
widget = GTK_WIDGET (window);
container = GTK_CONTAINER (widget);
info = gtk_window_get_geometry_info (window, TRUE);
- saved_last_info = info->last;
-
- gtk_widget_size_request (widget, NULL);
- gtk_window_compute_default_size (window, &new_width, &new_height);
- if (info->last.width < 0 ||
- info->last.width != new_width ||
- info->last.height != new_height)
- {
- default_size_changed = TRUE;
- may_shrink |= info->may_shrink;
- info->last.width = new_width;
- info->last.height = new_height;
+ configure_request_size_changed = FALSE;
+ configure_request_pos_changed = FALSE;
+
+ gtk_window_compute_configure_request (window, &new_request,
+ &new_geometry, &new_flags);
+
+ /* This check implies the invariant that we never set info->last
+ * without setting the hints and sending off a configure request.
+ *
+ * If we change info->last without sending the request, we may
+ * miss a request.
+ */
+ if (info->last.configure_request.x != new_request.x ||
+ info->last.configure_request.y != new_request.y)
+ configure_request_pos_changed = TRUE;
+
+ /* To change, we must be different from BOTH the last request, and
+ * also our current size as received from the most recent configure
+ * notify.
+ *
+ * If different from last request, it means some sizing
+ * parameters have changed; but one possible such sizing
+ * parameter could be the current size.
+ *
+ * We never want to re-request our current size, because that could
+ * lead to some strange infinite loops if a window manager did
+ * something insane but ICCCM-compliant such as add 2 to all
+ * requested sizes. (i.e. if the WM always assigned a size that
+ * was a function of the requested size, rather than a constraint
+ * applied to requested size - so that requesting current size
+ * did not result in getting that size back)
+ *
+ * So here we detect and prevent any attempt to set size
+ * to current size.
+ *
+ * (FIXME I think some race may be possible here, but
+ * perhaps avoided by configure_request_count?)
+ */
+ if ((info->last.configure_request.width != new_request.width ||
+ info->last.configure_request.height != new_request.height) &&
+ (widget->allocation.width != new_request.width ||
+ widget->allocation.height != new_request.height))
+ configure_request_size_changed = TRUE;
- /* We need to force a reposition in this case
+ /*
+ * Position Constraints
+ * ====================
+ *
+ * POS_CENTER_ALWAYS is conceptually a constraint rather than
+ * a default. The other POS_ values are used only when the
+ * window is shown, not after that.
+ *
+ * However, we can't implement a position constraint as
+ * "anytime the window size changes, center the window"
+ * because this may well end up fighting the WM or user. In
+ * fact it gets in an infinite loop with at least one WM.
+ *
+ * Basically, applications are in no way in a position to
+ * constrain the position of a window, with one exception:
+ * override redirect windows. (Really the intended purpose
+ * of CENTER_ALWAYS anyhow, I would think.)
+ *
+ * So the way we implement this "constraint" is to say that when WE
+ * cause a move or resize, i.e. we make a configure request changing
+ * window size, we recompute the CENTER_ALWAYS position to reflect
+ * the new window size, and include it in our request. Also, if we
+ * just turned on CENTER_ALWAYS we snap to center with a new
+ * request. Otherwise, if we are just NOTIFIED of a move or resize
+ * done by someone else e.g. the window manager, we do NOT send a
+ * new configure request.
+ *
+ * For override redirect windows, this works fine; all window
+ * sizes are from our configure requests. For managed windows,
+ * it is at least semi-sane, though who knows what the
+ * app author is thinking.
+ */
+
+ if (configure_request_pos_changed ||
+ configure_request_size_changed ||
+ info->position_constraints_changed)
+ {
+ /* We request the constrained position if:
+ * - we were changing position, and need to clamp
+ * the change to the constraint
+ * - we're changing the size anyway
+ * - set_position() was called to toggle CENTER_ALWAYS on
*/
- if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
- window->use_uposition = TRUE;
+
+ gtk_window_constrain_position (window,
+ new_request.width,
+ new_request.height,
+ &new_request.x,
+ &new_request.y);
+
+ /* Update whether we need to request a move */
+ if (info->last.configure_request.x != new_request.x ||
+ info->last.configure_request.y != new_request.y)
+ configure_request_pos_changed = TRUE;
+ else
+ configure_request_pos_changed = FALSE;
}
- info->may_shrink = FALSE;
- /* Compute new set of hints for the window
- */
- gtk_window_compute_hints (window, &new_geometry, &new_flags);
+ hints_changed = FALSE;
+
if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
&new_geometry, new_flags))
{
hints_changed = TRUE;
- info->last.geometry = new_geometry;
- info->last.flags = new_flags;
}
- /* From the default size and the allocation, figure out the size
- * the window should be.
+#if 0
+ g_print ("--- %s ---\n"
+ "last : %d,%d\t%d x %d\n"
+ "this : %d,%d\t%d x %d\n"
+ "alloc: %d,%d\t%d x %d\n"
+ "req : \t%d x %d\n"
+ "size_changed: %d pos_changed: %d hints_changed: %d\n"
+ "configure_notify_received: %d\n"
+ "configure_request_count: %d\n"
+ "position_constraints_changed: %d\n",
+ window->title ? window->title : "(no title)",
+ info->last.configure_request.x,
+ info->last.configure_request.y,
+ info->last.configure_request.width,
+ info->last.configure_request.height,
+ new_request.x,
+ new_request.y,
+ new_request.width,
+ new_request.height,
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width,
+ widget->allocation.height,
+ widget->requisition.width,
+ widget->requisition.height,
+ configure_request_pos_changed,
+ configure_request_size_changed,
+ hints_changed,
+ window->configure_notify_received,
+ window->configure_request_count,
+ info->position_constraints_changed);
+#endif
+
+ saved_last_info = info->last;
+ info->last.geometry = new_geometry;
+ info->last.flags = new_flags;
+ info->last.configure_request = new_request;
+
+ /* need to set PPosition so the WM will look at our position,
+ * but we don't want to count PPosition coming and going as a hints
+ * change for future iterations. So we saved info->last prior to
+ * this.
+ */
+
+ /* Also, if the initial position was explicitly set, then we always
+ * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
+ * work.
*/
- if (!default_size_changed ||
- (!may_shrink &&
- new_width <= widget->allocation.width &&
- new_height <= widget->allocation.height))
- {
- new_width = widget->allocation.width;
- new_height = widget->allocation.height;
- }
-
- /* constrain the window size to the specified geometry */
- gtk_window_constrain_size (window,
- &new_geometry, new_flags,
- new_width, new_height,
- &new_width, &new_height);
- /* compute new window position if a move is required
+ /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
+ * this is an initial map
*/
- need_reposition = gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
- if (need_reposition && !(new_flags & GDK_HINT_POS))
+
+ if ((configure_request_pos_changed ||
+ info->initial_pos_set ||
+ (window->need_default_position &&
+ window->position != GTK_WIN_POS_NONE)) &&
+ (new_flags & GDK_HINT_POS) == 0)
{
new_flags |= GDK_HINT_POS;
hints_changed = TRUE;
}
-
-
- /* handle actual resizing:
- * - handle reallocations due to configure events
- * - figure whether we need to request a new window size
- * - handle simple resizes within our widget tree
- * - reposition window if neccessary
+
+ /* Set hints if necessary
*/
- width = widget->allocation.width;
- height = widget->allocation.height;
-
- if (window->handling_resize)
+ if (hints_changed)
+ gdk_window_set_geometry_hints (widget->window,
+ &new_geometry,
+ new_flags);
+
+ if (window->configure_notify_received)
{
GtkAllocation allocation;
-
- /* if we are just responding to a configure event, which
- * might be due to a resize by the window manager, the
- * user, or a response to a resizing request we made
- * earlier, we go ahead, allocate the new size and we're done
+
+ /* If we have received a configure event since
+ * the last time in this function, we need to
+ * accept our new size and size_allocate child widgets.
* (see gtk_window_configure_event() for more details).
+ *
+ * 1 or more configure notifies may have been received.
+ * Also, configure_notify_received will only be TRUE
+ * if all expected configure notifies have been received
+ * (one per configure request), as an optimization.
+ *
*/
- window->handling_resize = FALSE;
-
+ window->configure_notify_received = FALSE;
+
+ /* gtk_window_configure_event() filled in widget->allocation */
allocation = widget->allocation;
gtk_widget_size_allocate (widget, &allocation);
gtk_widget_queue_draw (widget);
- if ((default_size_changed || hints_changed) && (width != new_width || height != new_height))
- {
- /* We could be here for two reasons
- * 1) We coincidentally got a resize while handling
- * another resize.
- * 2) Our computation of default_size_changed was completely
- * screwed up, probably because one of our children
- * is changed requisition during size allocation).
- *
- * For 1), we could just go ahead and ask for the
- * new size right now, but doing that for 2)
- * might well be fighting the user (and can even
- * trigger a loop). Since we really don't want to
- * do that, we requeue a resize in hopes that
- * by the time it gets handled, the child has seen
- * the light and is willing to go along with the
- * new size. (this happens for the zvt widget, since
- * the size_allocate() above will have stored the
- * requisition corresponding to the new size in the
- * zvt widget)
- *
- * This doesn't buy us anything for 1), but it shouldn't
- * hurt us too badly, since it is what would have
- * happened if we had gotten the configure event before
- * the new size had been set.
- */
-
- if (need_reposition)
- {
- if (window->frame)
- gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
- else
- gdk_window_move (GTK_WIDGET (window)->window, x, y);
- }
+ /* If the configure request changed, it means that
+ * we either:
+ * 1) coincidentally changed hints or widget properties
+ * impacting the configure request before getting
+ * a configure notify
+ * or
+ * 2) some broken widget is changing its size request
+ * during size allocation, resulting in
+ * a false appearance of changed configure request.
+ *
+ * For 1), we could just go ahead and ask for the
+ * new size right now, but doing that for 2)
+ * might well be fighting the user (and can even
+ * trigger a loop). Since we really don't want to
+ * do that, we requeue a resize in hopes that
+ * by the time it gets handled, the child has seen
+ * the light and is willing to go along with the
+ * new size. (this happens for the zvt widget, since
+ * the size_allocate() above will have stored the
+ * requisition corresponding to the new size in the
+ * zvt widget)
+ *
+ * This doesn't buy us anything for 1), but it shouldn't
+ * hurt us too badly, since it is what would have
+ * happened if we had gotten the configure event before
+ * the new size had been set.
+ *
+ */
- /* we have to preserve the values and flags that are used
- * for computation of default_size_changed and hints_changed
- */
+ if (configure_request_size_changed ||
+ configure_request_pos_changed)
+ {
+ /* Don't change the recorded last info after all, because we
+ * haven't actually updated to the new info yet - we decided
+ * to postpone our configure request until later.
+ */
+
info->last = saved_last_info;
-
+
gtk_widget_queue_resize (widget);
-
- return;
}
}
-
- /* Now set hints if necessary
- */
- if (hints_changed)
- gdk_window_set_geometry_hints (widget->window,
- &new_geometry,
- new_flags);
-
- if ((default_size_changed || hints_changed) &&
- (width != new_width || height != new_height))
+ else if (configure_request_pos_changed ||
+ configure_request_size_changed ||
+ hints_changed)
{
- /* given that (width != new_width || height != new_height), we are in one
- * of the following situations:
+ /* We are in one of the following situations with
+ * respect to the window size:
*
- * default_size_changed
+ * A. configure_request_size_changed
* our requisition has changed and we need a different window size,
* so we request it from the window manager.
*
- * !default_size_changed
+ * B. !configure_request_size_changed
* the window manager wouldn't assign us the size we requested, in this
* case we don't try to request a new size with every resize.
*
- * !default_size_changed && hints_changed
+ * C. !configure_request_size_changed && hints_changed
* the window manager rejects our size, but we have just changed the
* window manager hints, so there's a certain chance our request will
* be honoured this time, so we try again.
*/
+
+ /* Compress case C into case A */
+ if (hints_changed)
+ configure_request_size_changed = TRUE;
+
+ g_assert (configure_request_size_changed ||
+ configure_request_pos_changed);
- /* request a new window size */
- if (need_reposition)
+ /* Now send the configure request */
+
+ if (configure_request_pos_changed)
{
if (window->frame)
{
gdk_window_move_resize (window->frame,
- x - window->frame_left, y - window->frame_top,
- new_width + window->frame_left + window->frame_right,
- new_height + window->frame_top + window->frame_bottom);
- gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
+ new_request.x - window->frame_left,
+ new_request.y - window->frame_top,
+ new_request.width + window->frame_left + window->frame_right,
+ new_request.height + window->frame_top + window->frame_bottom);
+ gdk_window_resize (GTK_WIDGET (window)->window,
+ new_request.width, new_request.height);
}
else
- gdk_window_move_resize (GTK_WIDGET (window)->window, x, y, new_width, new_height);
+ gdk_window_move_resize (widget->window,
+ new_request.x, new_request.y,
+ new_request.width, new_request.height);
}
else
{
+ /* only size changed */
+
if (window->frame)
gdk_window_resize (window->frame,
- new_width + window->frame_left + window->frame_right,
- new_height + window->frame_top + window->frame_bottom);
- gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
+ new_request.width + window->frame_left + window->frame_right,
+ new_request.height + window->frame_top + window->frame_bottom);
+
+ gdk_window_resize (widget->window,
+ new_request.width, new_request.height);
}
- window->resize_count += 1;
- /* we are now awaiting the new configure event in response to our
+ /* Increment the number of have-not-yet-received-notify requests */
+ window->configure_request_count += 1;
+
+ /* We have now sent a request since the last position constraint
+ * change
+ */
+ info->position_constraints_changed = FALSE;
+
+ /* we are now awaiting the new configure notify event in response to our
* resizing request. the configure event will cause a new resize
- * with ->handling_resize=TRUE.
+ * with ->configure_notify_received=TRUE.
* until then, we want to
* - discard expose events
* - coalesce resizes for our children
* - defer any window resizes until the configure event arrived
- * to achive this, we queue a resize for the window, but remove its
+ * to achieve this, we queue a resize for the window, but remove its
* resizing handler, so resizing will not be handled from the next
* idle handler but when the configure event arrives.
*
* FIXME: we should also dequeue the pending redraws here, since
- * we handle those ourselves in ->handling_resize==TRUE.
+ * we handle those ourselves in ->configure_notify_received==TRUE.
+ *
+ * FIXME: not sure the above FIXME is correct, because we only
+ * queue draw in size allocate if the size actually changes,
+ * so if the update area for the window contains stuff
+ * unrelated to sizing (should be rare actually) then we
+ * might lose that info.
*/
- gtk_widget_queue_resize (GTK_WIDGET (container));
+ gtk_widget_queue_resize (widget);
if (container->resize_mode == GTK_RESIZE_QUEUE)
_gtk_container_dequeue_resize_handler (container);
}
else
{
- if (need_reposition)
- {
- if (window->frame)
- gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
- else
- gdk_window_move (widget->window, x, y);
- }
-
+ /* Not requesting anything new from WM, just had a queue resize
+ * for some reason, so handle the resize queue
+ */
if (container->resize_widgets)
- gtk_container_resize_children (GTK_CONTAINER (window));
+ gtk_container_resize_children (container);
}
}
@@ -2932,40 +3829,6 @@ gtk_window_compare_hints (GdkGeometry *geometry_a,
return TRUE;
}
-/* Compute the default_size for a window. The result will
- * be stored in *width and *height. The default size is
- * the size the window should have when initially mapped.
- * This routine does not attempt to constrain the size
- * to obey the geometry hints - that must be done elsewhere.
- */
-static void
-gtk_window_compute_default_size (GtkWindow *window,
- guint *width,
- guint *height)
-{
- GtkRequisition requisition;
- GtkWindowGeometryInfo *info;
-
- gtk_widget_get_child_requisition (GTK_WIDGET (window), &requisition);
- *width = requisition.width;
- *height = requisition.height;
-
- info = gtk_window_get_geometry_info (window, FALSE);
-
- if (*width == 0 && *height == 0)
- {
- /* empty window */
- *width = 200;
- *height = 200;
- }
-
- if (info)
- {
- *width = info->width > 0 ? info->width : *width;
- *height = info->height > 0 ? info->height : *height;
- }
-}
-
void
_gtk_window_constrain_size (GtkWindow *window,
gint width,
@@ -3017,8 +3880,6 @@ gtk_window_compute_hints (GtkWindow *window,
guint *new_flags)
{
GtkWidget *widget;
- GtkWidgetAuxInfo *aux_info;
- gint ux, uy;
gint extra_width = 0;
gint extra_height = 0;
GtkWindowGeometryInfo *geometry_info;
@@ -3031,27 +3892,26 @@ gtk_window_compute_hints (GtkWindow *window,
gtk_widget_get_child_requisition (widget, &requisition);
geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
- g_return_if_fail (geometry_info != NULL);
-
- *new_flags = geometry_info->mask;
- *new_geometry = geometry_info->geometry;
-
- if (geometry_info->widget)
+ if (geometry_info)
{
- extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
- extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
+ *new_flags = geometry_info->mask;
+ *new_geometry = geometry_info->geometry;
+ }
+ else
+ {
+ *new_flags = 0;
}
- ux = 0;
- uy = 0;
-
- aux_info = _gtk_widget_get_aux_info (widget, FALSE);
- if (aux_info && aux_info->x_set && aux_info->y_set)
+ if (geometry_info && geometry_info->widget)
{
- ux = aux_info->x;
- uy = aux_info->y;
- *new_flags |= GDK_HINT_POS;
+ extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
+ extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
}
+
+ /* We don't want to set GDK_HINT_POS in here, we just set it
+ * in gtk_window_move_resize() when we want the position
+ * honored.
+ */
if (*new_flags & GDK_HINT_BASE_SIZE)
{
@@ -3073,10 +3933,10 @@ gtk_window_compute_hints (GtkWindow *window,
if (new_geometry->min_width < 0)
new_geometry->min_width = requisition.width;
else
- new_geometry->min_width += extra_width;
+ new_geometry->min_width += extra_width;
if (new_geometry->min_height < 0)
- new_geometry->min_width = requisition.height;
+ new_geometry->min_height = requisition.height;
else
new_geometry->min_height += extra_height;
}
@@ -3112,106 +3972,6 @@ gtk_window_compute_hints (GtkWindow *window,
new_geometry->win_gravity = window->gravity;
}
-/* Compute a new position for the window based on a new
- * size. *x and *y will be set to the new coordinates. Returns
- * TRUE if the window needs to be moved (and thus x and y got
- * assigned)
- */
-static gint
-gtk_window_compute_reposition (GtkWindow *window,
- gint new_width,
- gint new_height,
- gint *x,
- gint *y)
-{
- GtkWidget *widget = GTK_WIDGET (window);
- GtkWindowPosition pos;
- GtkWidget *parent_widget;
- gboolean needs_move = FALSE;
-
- parent_widget = (GtkWidget*) window->transient_parent;
-
- pos = window->position;
- if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
- (parent_widget == NULL ||
- !GTK_WIDGET_MAPPED (parent_widget)))
- pos = GTK_WIN_POS_NONE;
-
- switch (pos)
- {
- case GTK_WIN_POS_CENTER:
- case GTK_WIN_POS_CENTER_ALWAYS:
- if (window->use_uposition)
- {
- gint screen_width = gdk_screen_width ();
- gint screen_height = gdk_screen_height ();
-
- *x = (screen_width - new_width) / 2;
- *y = (screen_height - new_height) / 2;
- needs_move = TRUE;
- }
- break;
-
- case GTK_WIN_POS_CENTER_ON_PARENT:
- if (window->use_uposition)
- {
- gint ox, oy;
- gdk_window_get_origin (parent_widget->window,
- &ox, &oy);
-
- *x = ox + (parent_widget->allocation.width - new_width) / 2;
- *y = oy + (parent_widget->allocation.height - new_height) / 2;
- needs_move = TRUE;
- }
- break;
-
- case GTK_WIN_POS_MOUSE:
- if (window->use_uposition)
- {
- gint screen_width = gdk_screen_width ();
- gint screen_height = gdk_screen_height ();
-
- gdk_window_get_pointer (NULL, x, y, NULL);
- *x -= new_width / 2;
- *y -= new_height / 2;
- *x = CLAMP (*x, 0, screen_width - new_width);
- *y = CLAMP (*y, 0, screen_height - new_height);
- needs_move = TRUE;
- }
- break;
- default:
- if (window->use_uposition)
- {
- GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
-
- if (aux_info && aux_info->x_set && aux_info->y_set)
- {
- *x = aux_info->x;
- *y = aux_info->y;
- needs_move = TRUE;
- }
- }
- break;
- }
-
- if (needs_move)
- {
- GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
-
- /* we handle necessary window positioning by hand here,
- * so we can coalesce the window movement with possible
- * resizes to get only one configure event.
- */
- aux_info->x_set = TRUE;
- aux_info->y_set = TRUE;
- aux_info->x = *x;
- aux_info->y = *y;
- window->use_uposition = FALSE;
- }
-
- return needs_move;
-}
-
/***********************
* Redrawing functions *
***********************/
@@ -3639,23 +4399,12 @@ gtk_window_get_resizable (GtkWindow *window)
* @window: a #GtkWindow
* @gravity: window gravity
*
- * Window gravity defines the "reference point" to be used when
- * positioning or resizing a window. Calls to
- * gtk_widget_set_uposition() will position a different point on the
- * window depending on the window gravity. When the window changes size
- * the reference point determined by the window's gravity will stay in
- * a fixed location.
- *
- * See #GdkGravity for full details. To briefly summarize,
- * #GDK_GRAVITY_NORTH_WEST means that the reference point is the
- * northwest (top left) corner of the window
- * frame. #GDK_GRAVITY_SOUTH_EAST would be the bottom right corner of
- * the frame, and so on. If you want to position the window contents,
- * rather than the window manager's frame, #GDK_GRAVITY_STATIC moves
- * the reference point to the northwest corner of the #GtkWindow
- * itself.
+ * Window gravity defines the meaning of coordinates passed to
+ * gtk_window_move(). See gtk_window_move() and #GdkGravity for
+ * more details.
*
- * The default window gravity is #GDK_GRAVITY_NORTH_WEST.
+ * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
+ * typically "do what you mean."
*
**/
void
@@ -3945,3 +4694,286 @@ _gtk_window_get_group (GtkWindow *window)
return default_group;
}
}
+
+
+/*
+ Derived from XParseGeometry() in XFree86
+
+ Copyright 1985, 1986, 1987,1998 The Open Group
+
+ All Rights Reserved.
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of The Open Group shall
+ not be used in advertising or otherwise to promote the sale, use or
+ other dealings in this Software without prior written authorization
+ from The Open Group.
+*/
+
+
+/*
+ * XParseGeometry parses strings of the form
+ * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ * width, height, xoffset, and yoffset are unsigned integers.
+ * Example: "=80x24+300-49"
+ * The equal sign is optional.
+ * It returns a bitmask that indicates which of the four values
+ * were actually found in the string. For each value found,
+ * the corresponding argument is updated; for each value
+ * not found, the corresponding argument is left unchanged.
+ */
+
+/* The following code is from Xlib, and is minimally modified, so we
+ * can track any upstream changes if required. Don't change this
+ * code. Or if you do, put in a huge comment marking which thing
+ * changed.
+ */
+
+static int
+read_int (gchar *string,
+ gchar **next)
+{
+ int result = 0;
+ int sign = 1;
+
+ if (*string == '+')
+ string++;
+ else if (*string == '-')
+ {
+ string++;
+ sign = -1;
+ }
+
+ for (; (*string >= '0') && (*string <= '9'); string++)
+ {
+ result = (result * 10) + (*string - '0');
+ }
+
+ *next = string;
+
+ if (sign >= 0)
+ return (result);
+ else
+ return (-result);
+}
+
+/*
+ * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
+ * value (x, y, width, height) was found in the parsed string.
+ */
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+
+/* Try not to reformat/modify, so we can compare/sync with X sources */
+static int
+gtk_XParseGeometry (const char *string,
+ int *x,
+ int *y,
+ unsigned int *width,
+ unsigned int *height)
+{
+ int mask = NoValue;
+ char *strind;
+ unsigned int tempWidth, tempHeight;
+ int tempX, tempY;
+ char *nextCharacter;
+
+ if ( (string == NULL) || (*string == '\0')) return(mask);
+ if (*string == '=')
+ string++; /* ignore possible '=' at beg of geometry spec */
+
+ strind = (char *)string;
+ if (*strind != '+' && *strind != '-' && *strind != 'x') {
+ tempWidth = read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= WidthValue;
+ }
+
+ if (*strind == 'x' || *strind == 'X') {
+ strind++;
+ tempHeight = read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= HeightValue;
+ }
+
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempX = -read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= XNegative;
+
+ }
+ else
+ { strind++;
+ tempX = read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= XValue;
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempY = -read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ mask |= YNegative;
+
+ }
+ else
+ {
+ strind++;
+ tempY = read_int(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= YValue;
+ }
+ }
+
+ /* If strind isn't at the end of the string the it's an invalid
+ geometry specification. */
+
+ if (*strind != '\0') return (0);
+
+ if (mask & XValue)
+ *x = tempX;
+ if (mask & YValue)
+ *y = tempY;
+ if (mask & WidthValue)
+ *width = tempWidth;
+ if (mask & HeightValue)
+ *height = tempHeight;
+ return (mask);
+}
+
+/**
+ * gtk_window_parse_geometry:
+ * @window: a #GtkWindow
+ * @geometry: geometry string
+ *
+ * Parses a standard X Window System geometry string - see the
+ * manual page for X (type 'man X') for details on this.
+ * gtk_window_parse_geometry() does work on all GTK+ ports
+ * including Win32 but is primarily intended for an X environment.
+ *
+ * If either a size or a position can be extracted from the
+ * geometry string, gtk_window_parse_geometry() returns %TRUE
+ * and calls gtk_window_set_default_size() and/or gtk_window_move()
+ * to resize/move the window.
+ *
+ * If gtk_window_parse_geometry() returns %TRUE, it will also
+ * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
+ * indicating to the window manager that the size/position of
+ * the window was user-specified. This causes most window
+ * managers to honor the geometry.
+ *
+ * Return value: %TRUE if string was parsed successfully
+ **/
+gboolean
+gtk_window_parse_geometry (GtkWindow *window,
+ const gchar *geometry)
+{
+ gint result, x, y;
+ guint w, h;
+ GdkGravity grav;
+ gboolean size_set, pos_set;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (geometry != NULL, FALSE);
+
+ result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
+
+ if ((result & WidthValue) == 0 ||
+ w < 0)
+ w = -1;
+ if ((result & HeightValue) == 0 ||
+ h < 0)
+ h = -1;
+
+ size_set = FALSE;
+ if ((result & WidthValue) || (result & HeightValue))
+ {
+ gtk_window_set_default_size (window, w, h);
+ size_set = TRUE;
+ }
+
+ gtk_window_get_size (window, &w, &h);
+
+ grav = GDK_GRAVITY_NORTH_WEST;
+
+ if ((result & XNegative) && (result & YNegative))
+ grav = GDK_GRAVITY_SOUTH_EAST;
+ else if (result & XNegative)
+ grav = GDK_GRAVITY_NORTH_EAST;
+ else if (result & YNegative)
+ grav = GDK_GRAVITY_SOUTH_WEST;
+
+ if ((result & XValue) == 0)
+ x = 0;
+
+ if ((result & YValue) == 0)
+ y = 0;
+
+ if (grav == GDK_GRAVITY_SOUTH_WEST ||
+ grav == GDK_GRAVITY_SOUTH_EAST)
+ y = gdk_screen_height () - h;
+
+ if (grav == GDK_GRAVITY_SOUTH_EAST ||
+ grav == GDK_GRAVITY_NORTH_EAST)
+ x = gdk_screen_width () - w;
+
+ if (y < 0)
+ y = 0;
+
+ if (x < 0)
+ x = 0;
+
+ pos_set = FALSE;
+ if ((result & XValue) || (result & YValue))
+ {
+ gtk_window_set_gravity (window, grav);
+ gtk_window_move (window, x, y);
+ pos_set = TRUE;
+ }
+
+ if (size_set || pos_set)
+ {
+ /* Set USSize, USPosition hints */
+ GtkWindowGeometryInfo *info;
+
+ info = gtk_window_get_geometry_info (window, TRUE);
+
+ if (pos_set)
+ info->mask |= GDK_HINT_USER_POS;
+ if (size_set)
+ info->mask |= GDK_HINT_USER_SIZE;
+ }
+
+ return result != 0;
+}
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index 282909cff..7753d02dd 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -69,24 +69,23 @@ struct _GtkWindow
GdkWindow *frame;
GtkWindowGroup *group;
- guint16 resize_count;
-
- GtkWindowType type : 4;
- guint has_user_ref_count : 1;
- guint has_focus : 1;
+ guint16 configure_request_count;
guint allow_shrink : 1;
guint allow_grow : 1;
- guint auto_shrink : 1;
- guint handling_resize : 1;
- guint position : 2;
-
- /* The following flag is initially TRUE when a window is mapped.
- * and will be set to FALSE after it is first positioned.
- * It is also temporarily reset when the window's size changes.
- *
- * When TRUE, we move the window to the position the app set.
+ guint configure_notify_received : 1;
+ /* The following flags are initially TRUE (before a window is mapped).
+ * They cause us to compute a configure request that involves
+ * default-only parameters. Once mapped, we set them to FALSE.
+ * Then we set them to TRUE again on unmap (for position)
+ * and on unrealize (for size).
*/
- guint use_uposition : 1;
+ guint need_default_position : 1;
+ guint need_default_size : 1;
+ guint position : 3;
+ GtkWindowType type : 4;
+ guint has_user_ref_count : 1;
+ guint has_focus : 1;
+
guint modal : 1;
guint destroy_with_parent : 1;
@@ -252,16 +251,33 @@ void gtk_window_set_policy (GtkWindow *window,
gint allow_grow,
gint auto_shrink);
#endif
-/* The following differs from gtk_widget_set_usize, in that
- * gtk_widget_set_usize() overrides the requisition, so sets a minimum
- * size, while this only sets the size requested from the WM.
+
+/* Set initial default size of the window (does not constrain user
+ * resize operations)
*/
-void gtk_window_set_default_size (GtkWindow *window,
- gint width,
- gint height);
-void gtk_window_get_default_size (GtkWindow *window,
- gint *width,
- gint *height);
+void gtk_window_set_default_size (GtkWindow *window,
+ gint width,
+ gint height);
+void gtk_window_get_default_size (GtkWindow *window,
+ gint *width,
+ gint *height);
+void gtk_window_resize (GtkWindow *window,
+ gint width,
+ gint height);
+void gtk_window_get_size (GtkWindow *window,
+ gint *width,
+ gint *height);
+void gtk_window_move (GtkWindow *window,
+ gint x,
+ gint y);
+void gtk_window_get_position (GtkWindow *window,
+ gint *x,
+ gint *y);
+gboolean gtk_window_parse_geometry (GtkWindow *window,
+ const gchar *geometry);
+
+/* Ignore this unless you are writing a GUI builder */
+void gtk_window_reshow_with_initial_size (GtkWindow *window);
/* Window groups
*/
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 2cbf63dfa..37f470300 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -8109,16 +8109,10 @@ configure_event_callback (GtkWidget *widget,
gchar *msg;
gint x, y;
-#if 0
- /* FIXME */
- gtk_window_get_location (GTK_WINDOW (widget), &x, &y);
-#else
- x = 0;
- y = 0;
-#endif
+ gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
msg = g_strdup_printf ("event: %d,%d %d x %d\n"
- "location: %d, %d",
+ "position: %d, %d",
event->x, event->y, event->width, event->height,
x, y);
@@ -8152,9 +8146,17 @@ set_size_callback (GtkWidget *widget,
get_ints (data, &w, &h);
- gtk_window_set_default_size (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
+ gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
}
-
+
+static void
+unset_default_size_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gtk_window_set_default_size (g_object_get_data (data, "target"),
+ -1, -1);
+}
+
static void
set_default_size_callback (GtkWidget *widget,
gpointer data)
@@ -8168,6 +8170,14 @@ set_default_size_callback (GtkWidget *widget,
}
static void
+unset_usize_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gtk_widget_set_size_request (g_object_get_data (data, "target"),
+ -1, -1);
+}
+
+static void
set_usize_callback (GtkWidget *widget,
gpointer data)
{
@@ -8175,8 +8185,8 @@ set_usize_callback (GtkWidget *widget,
get_ints (data, &w, &h);
- gtk_widget_set_usize (g_object_get_data (data, "target"),
- w, h);
+ gtk_widget_set_size_request (g_object_get_data (data, "target"),
+ w, h);
}
static void
@@ -8187,7 +8197,21 @@ set_location_callback (GtkWidget *widget,
get_ints (data, &x, &y);
- gtk_widget_set_uposition (g_object_get_data (data, "target"), x, y);
+ gtk_window_move (g_object_get_data (data, "target"), x, y);
+}
+
+static void
+move_to_position_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gint x, y;
+ GtkWindow *window;
+
+ window = g_object_get_data (data, "target");
+
+ gtk_window_get_position (window, &x, &y);
+
+ gtk_window_move (window, x, y);
}
static void
@@ -8201,12 +8225,9 @@ set_geometry_callback (GtkWidget *entry,
text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
-#if 0
- /* FIXME */
if (!gtk_window_parse_geometry (target, text))
g_print ("Bad geometry string '%s'\n", text);
-#endif
-
+
g_free (text);
}
@@ -8242,12 +8263,232 @@ auto_shrink_callback (GtkWidget *widget,
static void
gravity_selected (GtkWidget *widget,
- gpointer data)
+ gpointer data)
{
gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
}
+static void
+pos_selected (GtkWidget *widget,
+ gpointer data)
+{
+ gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
+ gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
+}
+
+static void
+move_gravity_window_to_current_position (GtkWidget *widget,
+ gpointer data)
+{
+ gint x, y;
+ GtkWindow *window;
+
+ window = GTK_WINDOW (data);
+
+ gtk_window_get_position (window, &x, &y);
+
+ gtk_window_move (window, x, y);
+}
+
+static void
+get_screen_corner (GtkWindow *window,
+ gint *x,
+ gint *y)
+{
+ int w, h;
+
+ gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+
+ switch (gtk_window_get_gravity (window))
+ {
+ case GDK_GRAVITY_SOUTH_EAST:
+ *x = gdk_screen_width () - w;
+ *y = gdk_screen_height () - h;
+ break;
+
+ case GDK_GRAVITY_NORTH_EAST:
+ *x = gdk_screen_width () - w;
+ *y = 0;
+ break;
+
+ case GDK_GRAVITY_SOUTH_WEST:
+ *x = 0;
+ *y = gdk_screen_height () - h;
+ break;
+
+ case GDK_GRAVITY_NORTH_WEST:
+ *x = 0;
+ *y = 0;
+ break;
+
+ case GDK_GRAVITY_SOUTH:
+ *x = (gdk_screen_width () - w) / 2;
+ *y = gdk_screen_height () - h;
+ break;
+
+ case GDK_GRAVITY_NORTH:
+ *x = (gdk_screen_width () - w) / 2;
+ *y = 0;
+ break;
+
+ case GDK_GRAVITY_WEST:
+ *x = 0;
+ *y = (gdk_screen_height () - h) / 2;
+ break;
+
+ case GDK_GRAVITY_EAST:
+ *x = gdk_screen_width () - w;
+ *y = (gdk_screen_height () - h) / 2;
+ break;
+
+ case GDK_GRAVITY_CENTER:
+ *x = (gdk_screen_width () - w) / 2;
+ *y = (gdk_screen_height () - h) / 2;
+ break;
+
+ case GDK_GRAVITY_STATIC:
+ /* pick some random numbers */
+ *x = 350;
+ *y = 350;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static void
+move_gravity_window_to_starting_position (GtkWidget *widget,
+ gpointer data)
+{
+ gint x, y;
+ GtkWindow *window;
+
+ window = GTK_WINDOW (data);
+
+ get_screen_corner (window,
+ &x, &y);
+
+ gtk_window_move (window, x, y);
+}
+
+static GtkWidget*
+make_gravity_window (GtkWidget *destroy_with,
+ GdkGravity gravity,
+ const gchar *title)
+{
+ GtkWidget *window;
+ GtkWidget *button;
+ GtkWidget *vbox;
+ int x, y;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+ gtk_window_set_title (GTK_WINDOW (window), title);
+ gtk_window_set_gravity (GTK_WINDOW (window), gravity);
+
+ gtk_signal_connect_object (GTK_OBJECT (destroy_with),
+ "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (window));
+
+
+ button = gtk_button_new_with_mnemonic ("_Move to current position");
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (move_gravity_window_to_current_position),
+ window);
+
+ gtk_container_add (GTK_CONTAINER (vbox), button);
+ gtk_widget_show (button);
+
+ button = gtk_button_new_with_mnemonic ("Move to _starting position");
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (move_gravity_window_to_starting_position),
+ window);
+
+ gtk_container_add (GTK_CONTAINER (vbox), button);
+ gtk_widget_show (button);
+
+ /* Pretend this is the result of --geometry.
+ * DO NOT COPY THIS CODE unless you are setting --geometry results,
+ * and in that case you probably should just use gtk_window_parse_geometry().
+ * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
+ * you are parsing --geometry or equivalent.
+ */
+ gtk_window_set_geometry_hints (GTK_WINDOW (window),
+ NULL, NULL,
+ GDK_HINT_USER_POS);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ 200, 200);
+
+ get_screen_corner (GTK_WINDOW (window), &x, &y);
+
+ gtk_window_move (GTK_WINDOW (window),
+ x, y);
+
+ return window;
+}
+
+static void
+do_gravity_test (GtkWidget *widget,
+ gpointer data)
+{
+ GtkWidget *destroy_with = data;
+ GtkWidget *window;
+
+ /* We put a window at each gravity point on the screen. */
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
+ "NorthWest");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
+ "SouthEast");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
+ "NorthEast");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
+ "SouthWest");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
+ "South");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
+ "North");
+ gtk_widget_show (window);
+
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
+ "West");
+ gtk_widget_show (window);
+
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
+ "East");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
+ "Center");
+ gtk_widget_show (window);
+
+ window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
+ "Static");
+ gtk_widget_show (window);
+}
+
static GtkWidget*
window_controls (GtkWidget *window)
{
@@ -8287,7 +8528,7 @@ window_controls (GtkWidget *window)
GTK_SIGNAL_FUNC (configure_event_callback),
label);
- adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+ adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
5.0, 0.0);
spin = gtk_spin_button_new (adj, 0, 0);
@@ -8295,7 +8536,7 @@ window_controls (GtkWidget *window)
g_object_set_data (G_OBJECT (control_window), "spin1", spin);
- adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+ adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
5.0, 0.0);
spin = gtk_spin_button_new (adj, 0, 0);
@@ -8309,15 +8550,29 @@ window_controls (GtkWidget *window)
gtk_signal_connect (GTK_OBJECT (entry), "changed",
GTK_SIGNAL_FUNC (set_geometry_callback),
control_window);
+
+ button = gtk_button_new_with_label ("Show gravity test windows");
+ gtk_signal_connect_object (GTK_OBJECT (button),
+ "clicked",
+ GTK_SIGNAL_FUNC (do_gravity_test),
+ control_window);
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ button = gtk_button_new_with_label ("Reshow with initial size");
+ gtk_signal_connect_object (GTK_OBJECT (button),
+ "clicked",
+ GTK_SIGNAL_FUNC (gtk_window_reshow_with_initial_size),
+ GTK_OBJECT (window));
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Queue resize");
gtk_signal_connect_object (GTK_OBJECT (button),
"clicked",
GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
- GTK_OBJECT (control_window));
+ GTK_OBJECT (window));
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_with_label ("Set size");
+ button = gtk_button_new_with_label ("Resize");
gtk_signal_connect (GTK_OBJECT (button),
"clicked",
GTK_SIGNAL_FUNC (set_size_callback),
@@ -8331,20 +8586,41 @@ window_controls (GtkWidget *window)
GTK_OBJECT (control_window));
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_with_label ("Set usize");
+ button = gtk_button_new_with_label ("Unset default size");
+ gtk_signal_connect (GTK_OBJECT (button),
+ "clicked",
+ GTK_SIGNAL_FUNC (unset_default_size_callback),
+ GTK_OBJECT (control_window));
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ button = gtk_button_new_with_label ("Set size request");
gtk_signal_connect (GTK_OBJECT (button),
"clicked",
GTK_SIGNAL_FUNC (set_usize_callback),
GTK_OBJECT (control_window));
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_with_label ("Set location");
+ button = gtk_button_new_with_label ("Unset size request");
+ gtk_signal_connect (GTK_OBJECT (button),
+ "clicked",
+ GTK_SIGNAL_FUNC (unset_usize_callback),
+ GTK_OBJECT (control_window));
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ button = gtk_button_new_with_label ("Move");
gtk_signal_connect (GTK_OBJECT (button),
"clicked",
GTK_SIGNAL_FUNC (set_location_callback),
GTK_OBJECT (control_window));
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+ button = gtk_button_new_with_label ("Move to current position");
+ gtk_signal_connect (GTK_OBJECT (button),
+ "clicked",
+ GTK_SIGNAL_FUNC (move_to_position_callback),
+ GTK_OBJECT (control_window));
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
button = gtk_check_button_new_with_label ("Allow shrink");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
gtk_signal_connect (GTK_OBJECT (button),
@@ -8424,6 +8700,44 @@ window_controls (GtkWidget *window)
control_window);
gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
+
+
+ menu = gtk_menu_new ();
+
+ i = 0;
+ while (i < 5)
+ {
+ GtkWidget *mi;
+ static gchar *names[] = {
+ "GTK_WIN_POS_NONE",
+ "GTK_WIN_POS_CENTER",
+ "GTK_WIN_POS_MOUSE",
+ "GTK_WIN_POS_CENTER_ALWAYS",
+ "GTK_WIN_POS_CENTER_ON_PARENT",
+ NULL
+ };
+
+ g_assert (names[i]);
+
+ mi = gtk_menu_item_new_with_label (names[i]);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ ++i;
+ }
+
+ gtk_widget_show_all (menu);
+
+ om = gtk_option_menu_new ();
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+
+
+ gtk_signal_connect (GTK_OBJECT (om),
+ "changed",
+ GTK_SIGNAL_FUNC (pos_selected),
+ control_window);
+
+ gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
gtk_widget_show_all (vbox);
@@ -8434,27 +8748,36 @@ void
create_window_sizing (void)
{
static GtkWidget *window = NULL;
+ static GtkWidget *target_window = NULL;
- if (!window)
+ if (!target_window)
{
GtkWidget *label;
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
- gtk_container_add (GTK_CONTAINER (window), label);
+ gtk_container_add (GTK_CONTAINER (target_window), label);
gtk_widget_show (label);
+ gtk_signal_connect (GTK_OBJECT (target_window), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+ &target_window);
+
+ window = window_controls (target_window);
+
gtk_signal_connect (GTK_OBJECT (window), "destroy",
- GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+ GTK_SIGNAL_FUNC (gtk_widget_destroyed),
&window);
-
- gtk_window_set_title (GTK_WINDOW (window), "Window to size");
-
- gtk_widget_show (window_controls (window));
+
+ gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
}
+ /* don't show target window by default, we want to allow testing
+ * of behavior on first show.
+ */
+
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show (window);
else