1
/* GTK - The GIMP Toolkit
2
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
21
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22
* file for a list of people on the GTK+ Team. See the ChangeLog
23
* files for a list of changes. These files are distributed with
24
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33
#include "gdk/gdkkeysyms.h"
37
#include "gtkprivate.h"
39
#include "gtkwindow.h"
40
#include "gtkwindow-decorate.h"
41
#include "gtkbindings.h"
42
#include "gtkkeyhash.h"
44
#include "gtkmnemonichash.h"
45
#include "gtkmenubar.h"
46
#include "gtkiconfactory.h"
47
#include "gtkicontheme.h"
48
#include "gtkmarshalers.h"
50
#include "gtkbuildable.h"
53
#ifdef GDK_WINDOWING_X11
82
PROP_DESTROY_WITH_PARENT,
87
PROP_SKIP_TASKBAR_HINT,
99
/* Readonly properties */
101
PROP_HAS_TOPLEVEL_FOCUS,
103
/* Writeonly properties */
106
PROP_MNEMONICS_VISIBLE,
114
GdkPixmap *icon_pixmap;
115
GdkPixmap *icon_mask;
118
guint using_default_icon : 1;
119
guint using_parent_icon : 1;
120
guint using_themed_icon : 1;
124
GdkGeometry geometry; /* Last set of geometry hints we set */
125
GdkWindowHints flags;
126
GdkRectangle configure_request;
127
} GtkWindowLastGeometryInfo;
129
struct _GtkWindowGeometryInfo
131
/* Properties that the app has set on the window
133
GdkGeometry geometry; /* Geometry hints */
135
GtkWidget *widget; /* subwidget to which hints apply */
136
/* from last gtk_window_resize () - if > 0, indicates that
137
* we should resize to this size.
142
/* From last gtk_window_move () prior to mapping -
143
* only used if initial_pos_set
148
/* Default size - used only the FIRST time we map a window,
153
/* whether to use initial_x, initial_y */
154
guint initial_pos_set : 1;
155
/* CENTER_ALWAYS or other position constraint changed since
156
* we sent the last configure request.
158
guint position_constraints_changed : 1;
160
/* if true, default_width, height come from gtk_window_parse_geometry,
161
* and thus should be multiplied by the increments and affect the
162
* geometry widget only
164
guint default_is_geometry : 1;
166
GtkWindowLastGeometryInfo last;
169
#define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
171
typedef struct _GtkWindowPrivate GtkWindowPrivate;
173
struct _GtkWindowPrivate
175
GtkMnemonicHash *mnemonic_hash;
177
guint above_initially : 1;
178
guint below_initially : 1;
179
guint fullscreen_initially : 1;
180
guint skips_taskbar : 1;
181
guint skips_pager : 1;
183
guint accept_focus : 1;
184
guint focus_on_map : 1;
186
guint transient_parent_group : 1;
188
guint reset_type_hint : 1;
189
guint opacity_set : 1;
190
guint builder_visible : 1;
192
guint mnemonics_visible : 1;
193
guint mnemonics_visible_set : 1;
195
GdkWindowTypeHint type_hint;
204
static void gtk_window_dispose (GObject *object);
205
static void gtk_window_destroy (GtkObject *object);
206
static void gtk_window_finalize (GObject *object);
207
static void gtk_window_show (GtkWidget *widget);
208
static void gtk_window_hide (GtkWidget *widget);
209
static void gtk_window_map (GtkWidget *widget);
210
static void gtk_window_unmap (GtkWidget *widget);
211
static void gtk_window_realize (GtkWidget *widget);
212
static void gtk_window_unrealize (GtkWidget *widget);
213
static void gtk_window_size_request (GtkWidget *widget,
214
GtkRequisition *requisition);
215
static void gtk_window_size_allocate (GtkWidget *widget,
216
GtkAllocation *allocation);
217
static gint gtk_window_event (GtkWidget *widget,
219
static gboolean gtk_window_map_event (GtkWidget *widget,
221
static gboolean gtk_window_frame_event (GtkWindow *window,
223
static gint gtk_window_configure_event (GtkWidget *widget,
224
GdkEventConfigure *event);
225
static gint gtk_window_key_press_event (GtkWidget *widget,
227
static gint gtk_window_key_release_event (GtkWidget *widget,
229
static gint gtk_window_enter_notify_event (GtkWidget *widget,
230
GdkEventCrossing *event);
231
static gint gtk_window_leave_notify_event (GtkWidget *widget,
232
GdkEventCrossing *event);
233
static gint gtk_window_focus_in_event (GtkWidget *widget,
234
GdkEventFocus *event);
235
static gint gtk_window_focus_out_event (GtkWidget *widget,
236
GdkEventFocus *event);
237
static gint gtk_window_client_event (GtkWidget *widget,
238
GdkEventClient *event);
239
static void gtk_window_check_resize (GtkContainer *container);
240
static gint gtk_window_focus (GtkWidget *widget,
241
GtkDirectionType direction);
242
static void gtk_window_real_set_focus (GtkWindow *window,
245
static void gtk_window_real_activate_default (GtkWindow *window);
246
static void gtk_window_real_activate_focus (GtkWindow *window);
247
static void gtk_window_move_focus (GtkWindow *window,
248
GtkDirectionType dir);
249
static void gtk_window_keys_changed (GtkWindow *window);
250
static void gtk_window_paint (GtkWidget *widget,
252
static gint gtk_window_expose (GtkWidget *widget,
253
GdkEventExpose *event);
254
static void gtk_window_unset_transient_for (GtkWindow *window);
255
static void gtk_window_transient_parent_realized (GtkWidget *parent,
257
static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
260
static GdkScreen *gtk_window_check_screen (GtkWindow *window);
262
static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
265
static void gtk_window_move_resize (GtkWindow *window);
266
static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
268
GdkGeometry *geometry_b,
270
static void gtk_window_constrain_size (GtkWindow *window,
271
GdkGeometry *geometry,
277
static void gtk_window_constrain_position (GtkWindow *window,
282
static void gtk_window_compute_hints (GtkWindow *window,
283
GdkGeometry *new_geometry,
285
static void gtk_window_compute_configure_request (GtkWindow *window,
286
GdkRectangle *request,
287
GdkGeometry *geometry,
290
static void gtk_window_set_default_size_internal (GtkWindow *window,
291
gboolean change_width,
293
gboolean change_height,
295
gboolean is_geometry);
297
static void update_themed_icon (GtkIconTheme *theme,
299
static GList *icon_list_from_theme (GtkWidget *widget,
301
static void gtk_window_realize_icon (GtkWindow *window);
302
static void gtk_window_unrealize_icon (GtkWindow *window);
304
static void gtk_window_notify_keys_changed (GtkWindow *window);
305
static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
306
static void gtk_window_free_key_hash (GtkWindow *window);
307
static void gtk_window_on_composited_changed (GdkScreen *screen,
310
static GSList *toplevel_list = NULL;
311
static guint window_signals[LAST_SIGNAL] = { 0 };
312
static GList *default_icon_list = NULL;
313
static gchar *default_icon_name = NULL;
314
static guint default_icon_serial = 0;
315
static gboolean disable_startup_notification = FALSE;
316
static gboolean sent_startup_notification = FALSE;
318
static GQuark quark_gtk_embedded = 0;
319
static GQuark quark_gtk_window_key_hash = 0;
320
static GQuark quark_gtk_window_default_icon_pixmap = 0;
321
static GQuark quark_gtk_window_icon_info = 0;
322
static GQuark quark_gtk_buildable_accels = 0;
324
static GtkBuildableIface *parent_buildable_iface;
326
static void gtk_window_set_property (GObject *object,
330
static void gtk_window_get_property (GObject *object,
336
static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
337
static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
340
const GValue *value);
341
static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
342
GtkBuilder *builder);
343
static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
346
const gchar *tagname,
347
GMarkupParser *parser,
349
static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
352
const gchar *tagname,
356
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
357
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
358
gtk_window_buildable_interface_init))
361
add_tab_bindings (GtkBindingSet *binding_set,
362
GdkModifierType modifiers,
363
GtkDirectionType direction)
365
gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
367
GTK_TYPE_DIRECTION_TYPE, direction);
368
gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
370
GTK_TYPE_DIRECTION_TYPE, direction);
374
add_arrow_bindings (GtkBindingSet *binding_set,
376
GtkDirectionType direction)
378
guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
380
gtk_binding_entry_add_signal (binding_set, keysym, 0,
382
GTK_TYPE_DIRECTION_TYPE, direction);
383
gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
385
GTK_TYPE_DIRECTION_TYPE, direction);
386
gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
388
GTK_TYPE_DIRECTION_TYPE, direction);
389
gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
391
GTK_TYPE_DIRECTION_TYPE, direction);
395
extract_time_from_startup_id (const gchar* startup_id)
397
gchar *timestr = g_strrstr (startup_id, "_TIME");
398
guint32 retval = GDK_CURRENT_TIME;
405
/* Skip past the "_TIME" part */
409
timestamp = strtoul (timestr, &end, 0);
410
if (end != timestr && errno == 0)
418
startup_id_is_fake (const gchar* startup_id)
420
return strncmp (startup_id, "_TIME", 5) == 0;
424
gtk_window_class_init (GtkWindowClass *klass)
426
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
427
GtkObjectClass *object_class;
428
GtkWidgetClass *widget_class;
429
GtkContainerClass *container_class;
430
GtkBindingSet *binding_set;
432
object_class = (GtkObjectClass*) klass;
433
widget_class = (GtkWidgetClass*) klass;
434
container_class = (GtkContainerClass*) klass;
436
quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
437
quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
438
quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
439
quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
440
quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
442
gobject_class->dispose = gtk_window_dispose;
443
gobject_class->finalize = gtk_window_finalize;
445
gobject_class->set_property = gtk_window_set_property;
446
gobject_class->get_property = gtk_window_get_property;
448
object_class->destroy = gtk_window_destroy;
450
widget_class->show = gtk_window_show;
451
widget_class->hide = gtk_window_hide;
452
widget_class->map = gtk_window_map;
453
widget_class->map_event = gtk_window_map_event;
454
widget_class->unmap = gtk_window_unmap;
455
widget_class->realize = gtk_window_realize;
456
widget_class->unrealize = gtk_window_unrealize;
457
widget_class->size_request = gtk_window_size_request;
458
widget_class->size_allocate = gtk_window_size_allocate;
459
widget_class->configure_event = gtk_window_configure_event;
460
widget_class->key_press_event = gtk_window_key_press_event;
461
widget_class->key_release_event = gtk_window_key_release_event;
462
widget_class->enter_notify_event = gtk_window_enter_notify_event;
463
widget_class->leave_notify_event = gtk_window_leave_notify_event;
464
widget_class->focus_in_event = gtk_window_focus_in_event;
465
widget_class->focus_out_event = gtk_window_focus_out_event;
466
widget_class->client_event = gtk_window_client_event;
467
widget_class->focus = gtk_window_focus;
468
widget_class->expose_event = gtk_window_expose;
470
container_class->check_resize = gtk_window_check_resize;
472
klass->set_focus = gtk_window_real_set_focus;
473
klass->frame_event = gtk_window_frame_event;
475
klass->activate_default = gtk_window_real_activate_default;
476
klass->activate_focus = gtk_window_real_activate_focus;
477
klass->move_focus = gtk_window_move_focus;
478
klass->keys_changed = gtk_window_keys_changed;
480
g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
483
g_object_class_install_property (gobject_class,
485
g_param_spec_enum ("type",
487
P_("The type of the window"),
488
GTK_TYPE_WINDOW_TYPE,
490
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
492
g_object_class_install_property (gobject_class,
494
g_param_spec_string ("title",
496
P_("The title of the window"),
498
GTK_PARAM_READWRITE));
500
g_object_class_install_property (gobject_class,
502
g_param_spec_string ("role",
504
P_("Unique identifier for the window to be used when restoring a session"),
506
GTK_PARAM_READWRITE));
508
g_object_class_install_property (object_class,
510
g_param_spec_boolean ("ubuntu-no-proxy",
511
P_("Disable menu proxies for this window"),
512
P_("Disable menu proxies for this window"),
514
GTK_PARAM_READWRITE));
517
* GtkWindow:startup-id:
519
* The :startup-id is a write-only property for setting window's
520
* startup notification identifier. See gtk_window_set_startup_id()
525
g_object_class_install_property (gobject_class,
527
g_param_spec_string ("startup-id",
529
P_("Unique startup identifier for the window used by startup-notification"),
531
GTK_PARAM_WRITABLE));
534
* GtkWindow:allow-shrink:
536
* If %TRUE, the window has no mimimum size. Setting this to %TRUE is
537
* 99% of the time a bad idea.
539
* Deprecated: 2.22: Use GtkWindow:resizable property instead.
541
g_object_class_install_property (gobject_class,
543
g_param_spec_boolean ("allow-shrink",
545
/* xgettext:no-c-format */
546
P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
548
GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
551
* GtkWindow:allow-grow:
553
* If %TRUE, users can expand the window beyond its minimum size.
555
* Deprecated: 2.22: Use GtkWindow:resizable property instead.
557
g_object_class_install_property (gobject_class,
559
g_param_spec_boolean ("allow-grow",
561
P_("If TRUE, users can expand the window beyond its minimum size"),
563
GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
565
g_object_class_install_property (gobject_class,
567
g_param_spec_boolean ("resizable",
569
P_("If TRUE, users can resize the window"),
571
GTK_PARAM_READWRITE));
573
g_object_class_install_property (gobject_class,
575
g_param_spec_boolean ("modal",
577
P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
579
GTK_PARAM_READWRITE));
581
g_object_class_install_property (gobject_class,
583
g_param_spec_enum ("window-position",
584
P_("Window Position"),
585
P_("The initial position of the window"),
586
GTK_TYPE_WINDOW_POSITION,
588
GTK_PARAM_READWRITE));
590
g_object_class_install_property (gobject_class,
592
g_param_spec_int ("default-width",
594
P_("The default width of the window, used when initially showing the window"),
598
GTK_PARAM_READWRITE));
600
g_object_class_install_property (gobject_class,
602
g_param_spec_int ("default-height",
603
P_("Default Height"),
604
P_("The default height of the window, used when initially showing the window"),
608
GTK_PARAM_READWRITE));
610
g_object_class_install_property (gobject_class,
611
PROP_DESTROY_WITH_PARENT,
612
g_param_spec_boolean ("destroy-with-parent",
613
P_("Destroy with Parent"),
614
P_("If this window should be destroyed when the parent is destroyed"),
616
GTK_PARAM_READWRITE));
618
g_object_class_install_property (gobject_class,
620
g_param_spec_object ("icon",
622
P_("Icon for this window"),
624
GTK_PARAM_READWRITE));
625
g_object_class_install_property (gobject_class,
626
PROP_MNEMONICS_VISIBLE,
627
g_param_spec_boolean ("mnemonics-visible",
628
P_("Mnemonics Visible"),
629
P_("Whether mnemonics are currently visible in this window"),
631
GTK_PARAM_READWRITE));
634
* GtkWindow:icon-name:
636
* The :icon-name property specifies the name of the themed icon to
637
* use as the window icon. See #GtkIconTheme for more details.
641
g_object_class_install_property (gobject_class,
643
g_param_spec_string ("icon-name",
645
P_("Name of the themed icon for this window"),
647
GTK_PARAM_READWRITE));
649
g_object_class_install_property (gobject_class,
651
g_param_spec_object ("screen",
653
P_("The screen where this window will be displayed"),
655
GTK_PARAM_READWRITE));
657
g_object_class_install_property (gobject_class,
659
g_param_spec_boolean ("is-active",
661
P_("Whether the toplevel is the current active window"),
663
GTK_PARAM_READABLE));
665
g_object_class_install_property (gobject_class,
666
PROP_HAS_TOPLEVEL_FOCUS,
667
g_param_spec_boolean ("has-toplevel-focus",
668
P_("Focus in Toplevel"),
669
P_("Whether the input focus is within this GtkWindow"),
671
GTK_PARAM_READABLE));
673
g_object_class_install_property (gobject_class,
675
g_param_spec_enum ("type-hint",
677
P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
678
GDK_TYPE_WINDOW_TYPE_HINT,
679
GDK_WINDOW_TYPE_HINT_NORMAL,
680
GTK_PARAM_READWRITE));
682
g_object_class_install_property (gobject_class,
683
PROP_SKIP_TASKBAR_HINT,
684
g_param_spec_boolean ("skip-taskbar-hint",
686
P_("TRUE if the window should not be in the task bar."),
688
GTK_PARAM_READWRITE));
690
g_object_class_install_property (gobject_class,
691
PROP_SKIP_PAGER_HINT,
692
g_param_spec_boolean ("skip-pager-hint",
694
P_("TRUE if the window should not be in the pager."),
696
GTK_PARAM_READWRITE));
698
g_object_class_install_property (gobject_class,
700
g_param_spec_boolean ("urgency-hint",
702
P_("TRUE if the window should be brought to the user's attention."),
704
GTK_PARAM_READWRITE));
707
* GtkWindow:accept-focus:
709
* Whether the window should receive the input focus.
713
g_object_class_install_property (gobject_class,
715
g_param_spec_boolean ("accept-focus",
717
P_("TRUE if the window should receive the input focus."),
719
GTK_PARAM_READWRITE));
722
* GtkWindow:focus-on-map:
724
* Whether the window should receive the input focus when mapped.
728
g_object_class_install_property (gobject_class,
730
g_param_spec_boolean ("focus-on-map",
732
P_("TRUE if the window should receive the input focus when mapped."),
734
GTK_PARAM_READWRITE));
737
* GtkWindow:decorated:
739
* Whether the window should be decorated by the window manager.
743
g_object_class_install_property (gobject_class,
745
g_param_spec_boolean ("decorated",
747
P_("Whether the window should be decorated by the window manager"),
749
GTK_PARAM_READWRITE));
752
* GtkWindow:deletable:
754
* Whether the window frame should have a close button.
758
g_object_class_install_property (gobject_class,
760
g_param_spec_boolean ("deletable",
762
P_("Whether the window frame should have a close button"),
764
GTK_PARAM_READWRITE));
770
* The window gravity of the window. See gtk_window_move() and #GdkGravity for
771
* more details about window gravity.
775
g_object_class_install_property (gobject_class,
777
g_param_spec_enum ("gravity",
779
P_("The window gravity of the window"),
781
GDK_GRAVITY_NORTH_WEST,
782
GTK_PARAM_READWRITE));
786
* GtkWindow:transient-for:
788
* The transient parent of the window. See gtk_window_set_transient_for() for
789
* more details about transient windows.
793
g_object_class_install_property (gobject_class,
795
g_param_spec_object ("transient-for",
796
P_("Transient for Window"),
797
P_("The transient parent of the dialog"),
799
GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
804
* The requested opacity of the window. See gtk_window_set_opacity() for
805
* more details about window opacity.
809
g_object_class_install_property (gobject_class,
811
g_param_spec_double ("opacity",
812
P_("Opacity for Window"),
813
P_("The opacity of the window, from 0 to 1"),
817
GTK_PARAM_READWRITE));
819
window_signals[SET_FOCUS] =
820
g_signal_new (I_("set-focus"),
821
G_TYPE_FROM_CLASS (gobject_class),
823
G_STRUCT_OFFSET (GtkWindowClass, set_focus),
825
_gtk_marshal_VOID__OBJECT,
829
window_signals[FRAME_EVENT] =
830
g_signal_new (I_("frame-event"),
831
G_TYPE_FROM_CLASS (gobject_class),
833
G_STRUCT_OFFSET(GtkWindowClass, frame_event),
834
_gtk_boolean_handled_accumulator, NULL,
835
_gtk_marshal_BOOLEAN__BOXED,
840
* GtkWindow::activate-focus:
841
* @window: the window which received the signal
843
* The ::activate-focus signal is a
844
* <link linkend="keybinding-signals">keybinding signal</link>
845
* which gets emitted when the user activates the currently
846
* focused widget of @window.
848
window_signals[ACTIVATE_FOCUS] =
849
g_signal_new (I_("activate-focus"),
850
G_TYPE_FROM_CLASS (gobject_class),
851
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
852
G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
854
_gtk_marshal_VOID__VOID,
859
* GtkWindow::activate-default:
860
* @window: the window which received the signal
862
* The ::activate-default signal is a
863
* <link linkend="keybinding-signals">keybinding signal</link>
864
* which gets emitted when the user activates the default widget
867
window_signals[ACTIVATE_DEFAULT] =
868
g_signal_new (I_("activate-default"),
869
G_TYPE_FROM_CLASS (gobject_class),
870
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
871
G_STRUCT_OFFSET (GtkWindowClass, activate_default),
873
_gtk_marshal_VOID__VOID,
878
* GtkWindow::keys-changed:
879
* @window: the window which received the signal
881
* The ::keys-changed signal gets emitted when the set of accelerators
882
* or mnemonics that are associated with @window changes.
884
window_signals[KEYS_CHANGED] =
885
g_signal_new (I_("keys-changed"),
886
G_TYPE_FROM_CLASS (gobject_class),
888
G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
890
_gtk_marshal_VOID__VOID,
898
binding_set = gtk_binding_set_by_class (klass);
900
gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
901
"activate-focus", 0);
902
gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
903
"activate-focus", 0);
905
gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
906
"activate-default", 0);
907
gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
908
"activate-default", 0);
909
gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
910
"activate-default", 0);
912
add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
913
add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
914
add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
915
add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
917
add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
918
add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
919
add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
920
add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
924
gtk_window_init (GtkWindow *window)
926
GdkColormap *colormap;
927
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
929
gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
930
_gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
932
GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
934
gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
936
window->title = NULL;
937
window->wmclass_name = g_strdup (g_get_prgname ());
938
window->wmclass_class = g_strdup (gdk_get_program_class ());
939
window->wm_role = NULL;
940
window->geometry_info = NULL;
941
window->type = GTK_WINDOW_TOPLEVEL;
942
window->focus_widget = NULL;
943
window->default_widget = NULL;
944
window->configure_request_count = 0;
945
window->allow_shrink = FALSE;
946
window->allow_grow = TRUE;
947
window->configure_notify_received = FALSE;
948
window->position = GTK_WIN_POS_NONE;
949
window->need_default_size = TRUE;
950
window->need_default_position = TRUE;
951
window->modal = FALSE;
952
window->frame = NULL;
953
window->has_frame = FALSE;
954
window->frame_left = 0;
955
window->frame_right = 0;
956
window->frame_top = 0;
957
window->frame_bottom = 0;
958
window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
959
window->gravity = GDK_GRAVITY_NORTH_WEST;
960
window->decorated = TRUE;
961
window->mnemonic_modifier = GDK_MOD1_MASK;
962
window->screen = gdk_screen_get_default ();
964
priv->accept_focus = TRUE;
965
priv->focus_on_map = TRUE;
966
priv->deletable = TRUE;
967
priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
969
priv->startup_id = NULL;
970
priv->mnemonics_visible = TRUE;
972
colormap = _gtk_widget_peek_colormap ();
974
gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
976
g_object_ref_sink (window);
977
window->has_user_ref_count = TRUE;
978
toplevel_list = g_slist_prepend (toplevel_list, window);
980
gtk_decorated_window_init (window);
982
g_signal_connect (window->screen, "composited-changed",
983
G_CALLBACK (gtk_window_on_composited_changed), window);
987
gtk_window_set_property (GObject *object,
993
GtkWindowPrivate *priv;
995
window = GTK_WINDOW (object);
997
priv = GTK_WINDOW_GET_PRIVATE (window);
1002
window->type = g_value_get_enum (value);
1005
gtk_window_set_title (window, g_value_get_string (value));
1008
gtk_window_set_role (window, g_value_get_string (value));
1010
case PROP_STARTUP_ID:
1011
gtk_window_set_startup_id (window, g_value_get_string (value));
1013
case PROP_ALLOW_SHRINK:
1014
window->allow_shrink = g_value_get_boolean (value);
1015
gtk_widget_queue_resize (GTK_WIDGET (window));
1017
case PROP_ALLOW_GROW:
1018
window->allow_grow = g_value_get_boolean (value);
1019
gtk_widget_queue_resize (GTK_WIDGET (window));
1020
g_object_notify (G_OBJECT (window), "resizable");
1022
case PROP_RESIZABLE:
1023
window->allow_grow = g_value_get_boolean (value);
1024
gtk_widget_queue_resize (GTK_WIDGET (window));
1025
g_object_notify (G_OBJECT (window), "allow-grow");
1028
gtk_window_set_modal (window, g_value_get_boolean (value));
1031
gtk_window_set_position (window, g_value_get_enum (value));
1033
case PROP_DEFAULT_WIDTH:
1034
gtk_window_set_default_size_internal (window,
1035
TRUE, g_value_get_int (value),
1038
case PROP_DEFAULT_HEIGHT:
1039
gtk_window_set_default_size_internal (window,
1041
TRUE, g_value_get_int (value), FALSE);
1043
case PROP_DESTROY_WITH_PARENT:
1044
gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1047
gtk_window_set_icon (window,
1048
g_value_get_object (value));
1050
case PROP_ICON_NAME:
1051
gtk_window_set_icon_name (window, g_value_get_string (value));
1054
gtk_window_set_screen (window, g_value_get_object (value));
1056
case PROP_TYPE_HINT:
1057
gtk_window_set_type_hint (window,
1058
g_value_get_enum (value));
1060
case PROP_SKIP_TASKBAR_HINT:
1061
gtk_window_set_skip_taskbar_hint (window,
1062
g_value_get_boolean (value));
1064
case PROP_SKIP_PAGER_HINT:
1065
gtk_window_set_skip_pager_hint (window,
1066
g_value_get_boolean (value));
1068
case PROP_URGENCY_HINT:
1069
gtk_window_set_urgency_hint (window,
1070
g_value_get_boolean (value));
1072
case PROP_ACCEPT_FOCUS:
1073
gtk_window_set_accept_focus (window,
1074
g_value_get_boolean (value));
1076
case PROP_FOCUS_ON_MAP:
1077
gtk_window_set_focus_on_map (window,
1078
g_value_get_boolean (value));
1080
case PROP_DECORATED:
1081
gtk_window_set_decorated (window, g_value_get_boolean (value));
1083
case PROP_DELETABLE:
1084
gtk_window_set_deletable (window, g_value_get_boolean (value));
1087
gtk_window_set_gravity (window, g_value_get_enum (value));
1089
case PROP_TRANSIENT_FOR:
1090
gtk_window_set_transient_for (window, g_value_get_object (value));
1093
gtk_window_set_opacity (window, g_value_get_double (value));
1095
case PROP_MNEMONICS_VISIBLE:
1096
gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1099
priv->no_proxy = g_value_get_boolean (value);
1102
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1108
gtk_window_get_property (GObject *object,
1114
GtkWindowPrivate *priv;
1116
window = GTK_WINDOW (object);
1117
priv = GTK_WINDOW_GET_PRIVATE (window);
1121
GtkWindowGeometryInfo *info;
1123
g_value_set_enum (value, window->type);
1126
g_value_set_string (value, window->wm_role);
1129
g_value_set_string (value, window->title);
1131
case PROP_ALLOW_SHRINK:
1132
g_value_set_boolean (value, window->allow_shrink);
1134
case PROP_ALLOW_GROW:
1135
g_value_set_boolean (value, window->allow_grow);
1137
case PROP_RESIZABLE:
1138
g_value_set_boolean (value, window->allow_grow);
1141
g_value_set_boolean (value, window->modal);
1144
g_value_set_enum (value, window->position);
1146
case PROP_DEFAULT_WIDTH:
1147
info = gtk_window_get_geometry_info (window, FALSE);
1149
g_value_set_int (value, -1);
1151
g_value_set_int (value, info->default_width);
1153
case PROP_DEFAULT_HEIGHT:
1154
info = gtk_window_get_geometry_info (window, FALSE);
1156
g_value_set_int (value, -1);
1158
g_value_set_int (value, info->default_height);
1160
case PROP_DESTROY_WITH_PARENT:
1161
g_value_set_boolean (value, window->destroy_with_parent);
1164
g_value_set_object (value, gtk_window_get_icon (window));
1166
case PROP_ICON_NAME:
1167
g_value_set_string (value, gtk_window_get_icon_name (window));
1170
g_value_set_object (value, window->screen);
1172
case PROP_IS_ACTIVE:
1173
g_value_set_boolean (value, window->is_active);
1175
case PROP_HAS_TOPLEVEL_FOCUS:
1176
g_value_set_boolean (value, window->has_toplevel_focus);
1178
case PROP_TYPE_HINT:
1179
g_value_set_enum (value, priv->type_hint);
1181
case PROP_SKIP_TASKBAR_HINT:
1182
g_value_set_boolean (value,
1183
gtk_window_get_skip_taskbar_hint (window));
1185
case PROP_SKIP_PAGER_HINT:
1186
g_value_set_boolean (value,
1187
gtk_window_get_skip_pager_hint (window));
1189
case PROP_URGENCY_HINT:
1190
g_value_set_boolean (value,
1191
gtk_window_get_urgency_hint (window));
1193
case PROP_ACCEPT_FOCUS:
1194
g_value_set_boolean (value,
1195
gtk_window_get_accept_focus (window));
1197
case PROP_FOCUS_ON_MAP:
1198
g_value_set_boolean (value,
1199
gtk_window_get_focus_on_map (window));
1201
case PROP_DECORATED:
1202
g_value_set_boolean (value, gtk_window_get_decorated (window));
1204
case PROP_DELETABLE:
1205
g_value_set_boolean (value, gtk_window_get_deletable (window));
1208
g_value_set_enum (value, gtk_window_get_gravity (window));
1210
case PROP_TRANSIENT_FOR:
1211
g_value_set_object (value, gtk_window_get_transient_for (window));
1214
g_value_set_double (value, gtk_window_get_opacity (window));
1216
case PROP_MNEMONICS_VISIBLE:
1217
g_value_set_boolean (value, priv->mnemonics_visible);
1220
g_value_set_boolean (value, priv->no_proxy);
1223
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1229
gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1231
parent_buildable_iface = g_type_interface_peek_parent (iface);
1232
iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1233
iface->parser_finished = gtk_window_buildable_parser_finished;
1234
iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1235
iface->custom_finished = gtk_window_buildable_custom_finished;
1239
gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1240
GtkBuilder *builder,
1242
const GValue *value)
1244
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1246
if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1247
priv->builder_visible = TRUE;
1249
parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1253
gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1254
GtkBuilder *builder)
1256
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1260
if (priv->builder_visible)
1261
gtk_widget_show (GTK_WIDGET (buildable));
1263
accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1264
for (l = accels; l; l = l->next)
1266
object = gtk_builder_get_object (builder, l->data);
1269
g_warning ("Unknown accel group %s specified in window %s",
1270
(const gchar*)l->data, gtk_buildable_get_name (buildable));
1273
gtk_window_add_accel_group (GTK_WINDOW (buildable),
1274
GTK_ACCEL_GROUP (object));
1278
g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1280
parent_buildable_iface->parser_finished (buildable, builder);
1286
} GSListSubParserData;
1289
window_start_element (GMarkupParseContext *context,
1290
const gchar *element_name,
1291
const gchar **names,
1292
const gchar **values,
1297
GSListSubParserData *data = (GSListSubParserData*)user_data;
1299
if (strcmp (element_name, "group") == 0)
1301
for (i = 0; names[i]; i++)
1303
if (strcmp (names[i], "name") == 0)
1304
data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1307
else if (strcmp (element_name, "accel-groups") == 0)
1310
g_warning ("Unsupported tag type for GtkWindow: %s\n",
1315
static const GMarkupParser window_parser =
1317
window_start_element
1321
gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1322
GtkBuilder *builder,
1324
const gchar *tagname,
1325
GMarkupParser *parser,
1328
GSListSubParserData *parser_data;
1330
if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1331
tagname, parser, data))
1334
if (strcmp (tagname, "accel-groups") == 0)
1336
parser_data = g_slice_new0 (GSListSubParserData);
1337
parser_data->items = NULL;
1338
parser_data->object = G_OBJECT (buildable);
1340
*parser = window_parser;
1341
*data = parser_data;
1349
gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1350
GtkBuilder *builder,
1352
const gchar *tagname,
1355
GSListSubParserData *data;
1357
parent_buildable_iface->custom_finished (buildable, builder, child,
1358
tagname, user_data);
1360
if (strcmp (tagname, "accel-groups") != 0)
1363
data = (GSListSubParserData*)user_data;
1365
g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1366
data->items, (GDestroyNotify) g_slist_free);
1368
g_slice_free (GSListSubParserData, data);
1373
* @type: type of window
1375
* Creates a new #GtkWindow, which is a toplevel window that can
1376
* contain other widgets. Nearly always, the type of the window should
1377
* be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1378
* popup menu from scratch (which is a bad idea, just use #GtkMenu),
1379
* you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1380
* dialogs, though in some other toolkits dialogs are called "popups".
1381
* In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1382
* On X11, popup windows are not controlled by the <link
1383
* linkend="gtk-X11-arch">window manager</link>.
1385
* If you simply want an undecorated window (no window borders), use
1386
* gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1388
* Return value: a new #GtkWindow.
1391
gtk_window_new (GtkWindowType type)
1395
g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1397
window = g_object_new (GTK_TYPE_WINDOW, NULL);
1399
window->type = type;
1401
return GTK_WIDGET (window);
1405
* gtk_window_set_title:
1406
* @window: a #GtkWindow
1407
* @title: title of the window
1409
* Sets the title of the #GtkWindow. The title of a window will be
1410
* displayed in its title bar; on the X Window System, the title bar
1411
* is rendered by the <link linkend="gtk-X11-arch">window
1412
* manager</link>, so exactly how the title appears to users may vary
1413
* according to a user's exact configuration. The title should help a
1414
* user distinguish this window from other windows they may have
1415
* open. A good title might include the application name and current
1416
* document filename, for example.
1420
gtk_window_set_title (GtkWindow *window,
1425
g_return_if_fail (GTK_IS_WINDOW (window));
1427
new_title = g_strdup (title);
1428
g_free (window->title);
1429
window->title = new_title;
1431
if (gtk_widget_get_realized (GTK_WIDGET (window)))
1433
gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1435
gtk_decorated_window_set_title (window, title);
1438
g_object_notify (G_OBJECT (window), "title");
1442
* gtk_window_get_title:
1443
* @window: a #GtkWindow
1445
* Retrieves the title of the window. See gtk_window_set_title().
1447
* Return value: the title of the window, or %NULL if none has
1448
* been set explicitely. The returned string is owned by the widget
1449
* and must not be modified or freed.
1452
gtk_window_get_title (GtkWindow *window)
1454
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1456
return window->title;
1460
* gtk_window_set_wmclass:
1461
* @window: a #GtkWindow
1462
* @wmclass_name: window name hint
1463
* @wmclass_class: window class hint
1465
* Don't use this function. It sets the X Window System "class" and
1466
* "name" hints for a window. According to the ICCCM, you should
1467
* always set these to the same value for all windows in an
1468
* application, and GTK+ sets them to that value by default, so calling
1469
* this function is sort of pointless. However, you may want to call
1470
* gtk_window_set_role() on each window in your application, for the
1471
* benefit of the session manager. Setting the role allows the window
1472
* manager to restore window positions when loading a saved session.
1476
gtk_window_set_wmclass (GtkWindow *window,
1477
const gchar *wmclass_name,
1478
const gchar *wmclass_class)
1480
g_return_if_fail (GTK_IS_WINDOW (window));
1482
g_free (window->wmclass_name);
1483
window->wmclass_name = g_strdup (wmclass_name);
1485
g_free (window->wmclass_class);
1486
window->wmclass_class = g_strdup (wmclass_class);
1488
if (gtk_widget_get_realized (GTK_WIDGET (window)))
1489
g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1493
* gtk_window_set_role:
1494
* @window: a #GtkWindow
1495
* @role: unique identifier for the window to be used when restoring a session
1497
* This function is only useful on X11, not with other GTK+ targets.
1499
* In combination with the window title, the window role allows a
1500
* <link linkend="gtk-X11-arch">window manager</link> to identify "the
1501
* same" window when an application is restarted. So for example you
1502
* might set the "toolbox" role on your app's toolbox window, so that
1503
* when the user restarts their session, the window manager can put
1504
* the toolbox back in the same place.
1506
* If a window already has a unique title, you don't need to set the
1507
* role, since the WM can use the title to identify the window when
1508
* restoring the session.
1512
gtk_window_set_role (GtkWindow *window,
1517
g_return_if_fail (GTK_IS_WINDOW (window));
1519
new_role = g_strdup (role);
1520
g_free (window->wm_role);
1521
window->wm_role = new_role;
1523
if (gtk_widget_get_realized (GTK_WIDGET (window)))
1524
gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1526
g_object_notify (G_OBJECT (window), "role");
1530
* gtk_window_set_startup_id:
1531
* @window: a #GtkWindow
1532
* @startup_id: a string with startup-notification identifier
1534
* Startup notification identifiers are used by desktop environment to
1535
* track application startup, to provide user feedback and other
1536
* features. This function changes the corresponding property on the
1537
* underlying GdkWindow. Normally, startup identifier is managed
1538
* automatically and you should only use this function in special cases
1539
* like transferring focus from other processes. You should use this
1540
* function before calling gtk_window_present() or any equivalent
1541
* function generating a window map event.
1543
* This function is only useful on X11, not with other GTK+ targets.
1548
gtk_window_set_startup_id (GtkWindow *window,
1549
const gchar *startup_id)
1551
GtkWindowPrivate *priv;
1553
g_return_if_fail (GTK_IS_WINDOW (window));
1555
priv = GTK_WINDOW_GET_PRIVATE (window);
1557
g_free (priv->startup_id);
1558
priv->startup_id = g_strdup (startup_id);
1560
if (gtk_widget_get_realized (GTK_WIDGET (window)))
1562
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1564
#ifdef GDK_WINDOWING_X11
1565
if (timestamp != GDK_CURRENT_TIME)
1566
gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1569
/* Here we differentiate real and "fake" startup notification IDs,
1570
* constructed on purpose just to pass interaction timestamp
1572
if (startup_id_is_fake (priv->startup_id))
1573
gtk_window_present_with_time (window, timestamp);
1576
gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1579
/* If window is mapped, terminate the startup-notification too */
1580
if (gtk_widget_get_mapped (GTK_WIDGET (window)) &&
1581
!disable_startup_notification)
1582
gdk_notify_startup_complete_with_id (priv->startup_id);
1586
g_object_notify (G_OBJECT (window), "startup-id");
1590
* gtk_window_get_role:
1591
* @window: a #GtkWindow
1593
* Returns the role of the window. See gtk_window_set_role() for
1594
* further explanation.
1596
* Return value: the role of the window if set, or %NULL. The
1597
* returned is owned by the widget and must not be modified
1601
gtk_window_get_role (GtkWindow *window)
1603
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1605
return window->wm_role;
1609
* gtk_window_set_focus:
1610
* @window: a #GtkWindow
1611
* @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1612
* any focus widget for the toplevel window.
1614
* If @focus is not the current focus widget, and is focusable, sets
1615
* it as the focus widget for the window. If @focus is %NULL, unsets
1616
* the focus widget for this window. To set the focus to a particular
1617
* widget in the toplevel, it is usually more convenient to use
1618
* gtk_widget_grab_focus() instead of this function.
1621
gtk_window_set_focus (GtkWindow *window,
1624
g_return_if_fail (GTK_IS_WINDOW (window));
1627
g_return_if_fail (GTK_IS_WIDGET (focus));
1628
g_return_if_fail (gtk_widget_get_can_focus (focus));
1632
gtk_widget_grab_focus (focus);
1635
/* Clear the existing focus chain, so that when we focus into
1636
* the window again, we start at the beginnning.
1638
GtkWidget *widget = window->focus_widget;
1641
while (widget->parent)
1643
widget = widget->parent;
1644
gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1648
_gtk_window_internal_set_focus (window, NULL);
1653
_gtk_window_internal_set_focus (GtkWindow *window,
1656
g_return_if_fail (GTK_IS_WINDOW (window));
1658
if ((window->focus_widget != focus) ||
1659
(focus && !gtk_widget_has_focus (focus)))
1660
g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1664
* gtk_window_set_default:
1665
* @window: a #GtkWindow
1666
* @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1667
* default widget for the toplevel.
1669
* The default widget is the widget that's activated when the user
1670
* presses Enter in a dialog (for example). This function sets or
1671
* unsets the default widget for a #GtkWindow about. When setting
1672
* (rather than unsetting) the default widget it's generally easier to
1673
* call gtk_widget_grab_focus() on the widget. Before making a widget
1674
* the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1675
* widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1678
gtk_window_set_default (GtkWindow *window,
1679
GtkWidget *default_widget)
1681
g_return_if_fail (GTK_IS_WINDOW (window));
1684
g_return_if_fail (gtk_widget_get_can_default (default_widget));
1686
if (window->default_widget != default_widget)
1688
GtkWidget *old_default_widget = NULL;
1691
g_object_ref (default_widget);
1693
if (window->default_widget)
1695
old_default_widget = window->default_widget;
1697
if (window->focus_widget != window->default_widget ||
1698
!gtk_widget_get_receives_default (window->default_widget))
1699
_gtk_widget_set_has_default (window->default_widget, FALSE);
1700
gtk_widget_queue_draw (window->default_widget);
1703
window->default_widget = default_widget;
1705
if (window->default_widget)
1707
if (window->focus_widget == NULL ||
1708
!gtk_widget_get_receives_default (window->focus_widget))
1709
_gtk_widget_set_has_default (window->default_widget, TRUE);
1710
gtk_widget_queue_draw (window->default_widget);
1713
if (old_default_widget)
1714
g_object_notify (G_OBJECT (old_default_widget), "has-default");
1718
g_object_notify (G_OBJECT (default_widget), "has-default");
1719
g_object_unref (default_widget);
1725
* gtk_window_get_default_widget:
1726
* @window: a #GtkWindow
1728
* Returns the default widget for @window. See gtk_window_set_default()
1731
* Returns: (transfer none): the default widget, or %NULL if there is none.
1736
gtk_window_get_default_widget (GtkWindow *window)
1738
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1740
return window->default_widget;
1744
gtk_window_set_policy_internal (GtkWindow *window,
1745
gboolean allow_shrink,
1746
gboolean allow_grow,
1747
gboolean auto_shrink)
1749
window->allow_shrink = (allow_shrink != FALSE);
1750
window->allow_grow = (allow_grow != FALSE);
1752
g_object_freeze_notify (G_OBJECT (window));
1753
g_object_notify (G_OBJECT (window), "allow-shrink");
1754
g_object_notify (G_OBJECT (window), "allow-grow");
1755
g_object_notify (G_OBJECT (window), "resizable");
1756
g_object_thaw_notify (G_OBJECT (window));
1758
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1762
gtk_window_set_policy (GtkWindow *window,
1763
gboolean allow_shrink,
1764
gboolean allow_grow,
1765
gboolean auto_shrink)
1767
g_return_if_fail (GTK_IS_WINDOW (window));
1769
gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1773
handle_keys_changed (gpointer data)
1777
window = GTK_WINDOW (data);
1779
if (window->keys_changed_handler)
1781
g_source_remove (window->keys_changed_handler);
1782
window->keys_changed_handler = 0;
1785
g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1791
gtk_window_notify_keys_changed (GtkWindow *window)
1793
if (!window->keys_changed_handler)
1794
window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1798
* gtk_window_add_accel_group:
1799
* @window: window to attach accelerator group to
1800
* @accel_group: a #GtkAccelGroup
1802
* Associate @accel_group with @window, such that calling
1803
* gtk_accel_groups_activate() on @window will activate accelerators
1807
gtk_window_add_accel_group (GtkWindow *window,
1808
GtkAccelGroup *accel_group)
1810
g_return_if_fail (GTK_IS_WINDOW (window));
1811
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1813
_gtk_accel_group_attach (accel_group, G_OBJECT (window));
1814
g_signal_connect_object (accel_group, "accel-changed",
1815
G_CALLBACK (gtk_window_notify_keys_changed),
1816
window, G_CONNECT_SWAPPED);
1817
gtk_window_notify_keys_changed (window);
1821
* gtk_window_remove_accel_group:
1822
* @window: a #GtkWindow
1823
* @accel_group: a #GtkAccelGroup
1825
* Reverses the effects of gtk_window_add_accel_group().
1828
gtk_window_remove_accel_group (GtkWindow *window,
1829
GtkAccelGroup *accel_group)
1831
g_return_if_fail (GTK_IS_WINDOW (window));
1832
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1834
g_signal_handlers_disconnect_by_func (accel_group,
1835
gtk_window_notify_keys_changed,
1837
_gtk_accel_group_detach (accel_group, G_OBJECT (window));
1838
gtk_window_notify_keys_changed (window);
1841
static GtkMnemonicHash *
1842
gtk_window_get_mnemonic_hash (GtkWindow *window,
1845
GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1846
if (!private->mnemonic_hash && create)
1847
private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1849
return private->mnemonic_hash;
1853
* gtk_window_add_mnemonic:
1854
* @window: a #GtkWindow
1855
* @keyval: the mnemonic
1856
* @target: the widget that gets activated by the mnemonic
1858
* Adds a mnemonic to this window.
1861
gtk_window_add_mnemonic (GtkWindow *window,
1865
g_return_if_fail (GTK_IS_WINDOW (window));
1866
g_return_if_fail (GTK_IS_WIDGET (target));
1868
_gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1870
gtk_window_notify_keys_changed (window);
1874
* gtk_window_remove_mnemonic:
1875
* @window: a #GtkWindow
1876
* @keyval: the mnemonic
1877
* @target: the widget that gets activated by the mnemonic
1879
* Removes a mnemonic from this window.
1882
gtk_window_remove_mnemonic (GtkWindow *window,
1886
g_return_if_fail (GTK_IS_WINDOW (window));
1887
g_return_if_fail (GTK_IS_WIDGET (target));
1889
_gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1891
gtk_window_notify_keys_changed (window);
1895
* gtk_window_mnemonic_activate:
1896
* @window: a #GtkWindow
1897
* @keyval: the mnemonic
1898
* @modifier: the modifiers
1899
* @returns: %TRUE if the activation is done.
1901
* Activates the targets associated with the mnemonic.
1904
gtk_window_mnemonic_activate (GtkWindow *window,
1906
GdkModifierType modifier)
1908
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1910
if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1912
GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1914
return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1921
* gtk_window_set_mnemonic_modifier:
1922
* @window: a #GtkWindow
1923
* @modifier: the modifier mask used to activate
1924
* mnemonics on this window.
1926
* Sets the mnemonic modifier for this window.
1929
gtk_window_set_mnemonic_modifier (GtkWindow *window,
1930
GdkModifierType modifier)
1932
g_return_if_fail (GTK_IS_WINDOW (window));
1933
g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1935
window->mnemonic_modifier = modifier;
1936
gtk_window_notify_keys_changed (window);
1940
* gtk_window_get_mnemonic_modifier:
1941
* @window: a #GtkWindow
1943
* Returns the mnemonic modifier for this window. See
1944
* gtk_window_set_mnemonic_modifier().
1946
* Return value: the modifier mask used to activate
1947
* mnemonics on this window.
1950
gtk_window_get_mnemonic_modifier (GtkWindow *window)
1952
g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1954
return window->mnemonic_modifier;
1958
* gtk_window_set_position:
1959
* @window: a #GtkWindow.
1960
* @position: a position constraint.
1962
* Sets a position constraint for this window. If the old or new
1963
* constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1964
* the window to be repositioned to satisfy the new constraint.
1967
gtk_window_set_position (GtkWindow *window,
1968
GtkWindowPosition position)
1970
g_return_if_fail (GTK_IS_WINDOW (window));
1972
if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1973
window->position == GTK_WIN_POS_CENTER_ALWAYS)
1975
GtkWindowGeometryInfo *info;
1977
info = gtk_window_get_geometry_info (window, TRUE);
1979
/* this flag causes us to re-request the CENTER_ALWAYS
1980
* constraint in gtk_window_move_resize(), see
1981
* comment in that function.
1983
info->position_constraints_changed = TRUE;
1985
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1988
window->position = position;
1990
g_object_notify (G_OBJECT (window), "window-position");
1994
* gtk_window_activate_focus:
1995
* @window: a #GtkWindow
1997
* Activates the current focused widget within the window.
1999
* Return value: %TRUE if a widget got activated.
2002
gtk_window_activate_focus (GtkWindow *window)
2004
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2006
if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2007
return gtk_widget_activate (window->focus_widget);
2013
* gtk_window_get_focus:
2014
* @window: a #GtkWindow
2016
* Retrieves the current focused widget within the window.
2017
* Note that this is the widget that would have the focus
2018
* if the toplevel window focused; if the toplevel window
2019
* is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2020
* not be %TRUE for the widget.
2022
* Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2025
gtk_window_get_focus (GtkWindow *window)
2027
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2029
return window->focus_widget;
2033
* gtk_window_activate_default:
2034
* @window: a #GtkWindow
2036
* Activates the default widget for the window, unless the current
2037
* focused widget has been configured to receive the default action
2038
* (see gtk_widget_set_receives_default()), in which case the
2039
* focused widget is activated.
2041
* Return value: %TRUE if a widget got activated.
2044
gtk_window_activate_default (GtkWindow *window)
2046
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2048
if (window->default_widget && gtk_widget_is_sensitive (window->default_widget) &&
2049
(!window->focus_widget || !gtk_widget_get_receives_default (window->focus_widget)))
2050
return gtk_widget_activate (window->default_widget);
2051
else if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2052
return gtk_widget_activate (window->focus_widget);
2058
* gtk_window_set_modal:
2059
* @window: a #GtkWindow
2060
* @modal: whether the window is modal
2062
* Sets a window modal or non-modal. Modal windows prevent interaction
2063
* with other windows in the same application. To keep modal dialogs
2064
* on top of main application windows, use
2065
* gtk_window_set_transient_for() to make the dialog transient for the
2066
* parent; most <link linkend="gtk-X11-arch">window managers</link>
2067
* will then disallow lowering the dialog below the parent.
2072
gtk_window_set_modal (GtkWindow *window,
2077
g_return_if_fail (GTK_IS_WINDOW (window));
2079
modal = modal != FALSE;
2080
if (window->modal == modal)
2083
window->modal = modal;
2084
widget = GTK_WIDGET (window);
2086
/* adjust desired modality state */
2087
if (gtk_widget_get_realized (widget))
2090
gdk_window_set_modal_hint (widget->window, TRUE);
2092
gdk_window_set_modal_hint (widget->window, FALSE);
2095
if (gtk_widget_get_visible (widget))
2098
gtk_grab_add (widget);
2100
gtk_grab_remove (widget);
2103
g_object_notify (G_OBJECT (window), "modal");
2107
* gtk_window_get_modal:
2108
* @window: a #GtkWindow
2110
* Returns whether the window is modal. See gtk_window_set_modal().
2112
* Return value: %TRUE if the window is set to be modal and
2113
* establishes a grab when shown
2116
gtk_window_get_modal (GtkWindow *window)
2118
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2120
return window->modal;
2124
* gtk_window_list_toplevels:
2126
* Returns a list of all existing toplevel windows. The widgets
2127
* in the list are not individually referenced. If you want
2128
* to iterate through the list and perform actions involving
2129
* callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2130
* <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2131
* then unref all the widgets afterwards.
2133
* Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2136
gtk_window_list_toplevels (void)
2141
for (slist = toplevel_list; slist; slist = slist->next)
2142
list = g_list_prepend (list, slist->data);
2148
gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2150
GList *embedded_windows;
2152
g_return_if_fail (GTK_IS_WINDOW (window));
2154
embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2155
if (embedded_windows)
2156
g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2157
embedded_windows = g_list_prepend (embedded_windows,
2158
GUINT_TO_POINTER (xid));
2160
g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2163
(GDestroyNotify) g_list_free : NULL);
2167
gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2169
GList *embedded_windows;
2172
g_return_if_fail (GTK_IS_WINDOW (window));
2174
embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2175
if (embedded_windows)
2176
g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2178
node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2181
embedded_windows = g_list_remove_link (embedded_windows, node);
2182
g_list_free_1 (node);
2185
g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2188
(GDestroyNotify) g_list_free : NULL);
2192
_gtk_window_reposition (GtkWindow *window,
2196
g_return_if_fail (GTK_IS_WINDOW (window));
2198
gtk_window_move (window, x, y);
2202
gtk_window_dispose (GObject *object)
2204
GtkWindow *window = GTK_WINDOW (object);
2206
gtk_window_set_focus (window, NULL);
2207
gtk_window_set_default (window, NULL);
2209
G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2213
parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2215
gtk_widget_destroy (GTK_WIDGET (child));
2219
connect_parent_destroyed (GtkWindow *window)
2221
if (window->transient_parent)
2223
g_signal_connect (window->transient_parent,
2225
G_CALLBACK (parent_destroyed_callback),
2231
disconnect_parent_destroyed (GtkWindow *window)
2233
if (window->transient_parent)
2235
g_signal_handlers_disconnect_by_func (window->transient_parent,
2236
parent_destroyed_callback,
2242
gtk_window_transient_parent_realized (GtkWidget *parent,
2245
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2246
gdk_window_set_transient_for (window->window, parent->window);
2250
gtk_window_transient_parent_unrealized (GtkWidget *parent,
2253
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2254
gdk_property_delete (window->window,
2255
gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2259
gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2263
gtk_window_set_screen (window, parent->screen);
2267
gtk_window_unset_transient_for (GtkWindow *window)
2269
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2271
if (window->transient_parent)
2273
g_signal_handlers_disconnect_by_func (window->transient_parent,
2274
gtk_window_transient_parent_realized,
2276
g_signal_handlers_disconnect_by_func (window->transient_parent,
2277
gtk_window_transient_parent_unrealized,
2279
g_signal_handlers_disconnect_by_func (window->transient_parent,
2280
gtk_window_transient_parent_screen_changed,
2282
g_signal_handlers_disconnect_by_func (window->transient_parent,
2283
gtk_widget_destroyed,
2284
&window->transient_parent);
2286
if (window->destroy_with_parent)
2287
disconnect_parent_destroyed (window);
2289
window->transient_parent = NULL;
2291
if (priv->transient_parent_group)
2293
priv->transient_parent_group = FALSE;
2294
gtk_window_group_remove_window (window->group,
2301
* gtk_window_set_transient_for:
2302
* @window: a #GtkWindow
2303
* @parent: (allow-none): parent window, or %NULL
2305
* Dialog windows should be set transient for the main application
2306
* window they were spawned from. This allows <link
2307
* linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2308
* dialog on top of the main window, or center the dialog over the
2309
* main window. gtk_dialog_new_with_buttons() and other convenience
2310
* functions in GTK+ will sometimes call
2311
* gtk_window_set_transient_for() on your behalf.
2313
* Passing %NULL for @parent unsets the current transient window.
2315
* On Windows, this function puts the child window on top of the parent,
2316
* much as the window manager would have done on X.
2319
gtk_window_set_transient_for (GtkWindow *window,
2322
GtkWindowPrivate *priv;
2324
g_return_if_fail (GTK_IS_WINDOW (window));
2325
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2326
g_return_if_fail (window != parent);
2328
priv = GTK_WINDOW_GET_PRIVATE (window);
2330
if (window->transient_parent)
2332
if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2333
gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)) &&
2334
(!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2335
gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2336
GTK_WIDGET (window));
2338
gtk_window_unset_transient_for (window);
2341
window->transient_parent = parent;
2345
g_signal_connect (parent, "destroy",
2346
G_CALLBACK (gtk_widget_destroyed),
2347
&window->transient_parent);
2348
g_signal_connect (parent, "realize",
2349
G_CALLBACK (gtk_window_transient_parent_realized),
2351
g_signal_connect (parent, "unrealize",
2352
G_CALLBACK (gtk_window_transient_parent_unrealized),
2354
g_signal_connect (parent, "notify::screen",
2355
G_CALLBACK (gtk_window_transient_parent_screen_changed),
2358
gtk_window_set_screen (window, parent->screen);
2360
if (window->destroy_with_parent)
2361
connect_parent_destroyed (window);
2363
if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2364
gtk_widget_get_realized (GTK_WIDGET (parent)))
2365
gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2366
GTK_WIDGET (window));
2370
gtk_window_group_add_window (parent->group, window);
2371
priv->transient_parent_group = TRUE;
2377
* gtk_window_get_transient_for:
2378
* @window: a #GtkWindow
2380
* Fetches the transient parent for this window. See
2381
* gtk_window_set_transient_for().
2383
* Return value: (transfer none): the transient parent for this window, or %NULL
2384
* if no transient parent has been set.
2387
gtk_window_get_transient_for (GtkWindow *window)
2389
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2391
return window->transient_parent;
2395
* gtk_window_set_opacity:
2396
* @window: a #GtkWindow
2397
* @opacity: desired opacity, between 0 and 1
2399
* Request the windowing system to make @window partially transparent,
2400
* with opacity 0 being fully transparent and 1 fully opaque. (Values
2401
* of the opacity parameter are clamped to the [0,1] range.) On X11
2402
* this has any effect only on X screens with a compositing manager
2403
* running. See gtk_widget_is_composited(). On Windows it should work
2406
* Note that setting a window's opacity after the window has been
2407
* shown causes it to flicker once on Windows.
2412
gtk_window_set_opacity (GtkWindow *window,
2415
GtkWindowPrivate *priv;
2417
g_return_if_fail (GTK_IS_WINDOW (window));
2419
priv = GTK_WINDOW_GET_PRIVATE (window);
2423
else if (opacity > 1.0)
2426
priv->opacity_set = TRUE;
2427
priv->opacity = opacity;
2429
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2430
gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2434
* gtk_window_get_opacity:
2435
* @window: a #GtkWindow
2437
* Fetches the requested opacity for this window. See
2438
* gtk_window_set_opacity().
2440
* Return value: the requested opacity for this window.
2445
gtk_window_get_opacity (GtkWindow *window)
2447
GtkWindowPrivate *priv;
2449
g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2451
priv = GTK_WINDOW_GET_PRIVATE (window);
2453
return priv->opacity;
2457
* gtk_window_set_type_hint:
2458
* @window: a #GtkWindow
2459
* @hint: the window type
2461
* By setting the type hint for the window, you allow the window
2462
* manager to decorate and handle the window in a way which is
2463
* suitable to the function of the window in your application.
2465
* This function should be called before the window becomes visible.
2467
* gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2468
* will sometimes call gtk_window_set_type_hint() on your behalf.
2472
gtk_window_set_type_hint (GtkWindow *window,
2473
GdkWindowTypeHint hint)
2475
GtkWindowPrivate *priv;
2477
g_return_if_fail (GTK_IS_WINDOW (window));
2478
g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2480
priv = GTK_WINDOW_GET_PRIVATE (window);
2482
if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2483
window->type_hint = hint;
2485
window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2487
priv->reset_type_hint = TRUE;
2488
priv->type_hint = hint;
2492
* gtk_window_get_type_hint:
2493
* @window: a #GtkWindow
2495
* Gets the type hint for this window. See gtk_window_set_type_hint().
2497
* Return value: the type hint for @window.
2500
gtk_window_get_type_hint (GtkWindow *window)
2502
GtkWindowPrivate *priv;
2504
g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2506
priv = GTK_WINDOW_GET_PRIVATE (window);
2508
return priv->type_hint;
2512
* gtk_window_set_skip_taskbar_hint:
2513
* @window: a #GtkWindow
2514
* @setting: %TRUE to keep this window from appearing in the task bar
2516
* Windows may set a hint asking the desktop environment not to display
2517
* the window in the task bar. This function sets this hint.
2522
gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2525
GtkWindowPrivate *priv;
2527
g_return_if_fail (GTK_IS_WINDOW (window));
2529
priv = GTK_WINDOW_GET_PRIVATE (window);
2531
setting = setting != FALSE;
2533
if (priv->skips_taskbar != setting)
2535
priv->skips_taskbar = setting;
2536
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2537
gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2538
priv->skips_taskbar);
2539
g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2544
* gtk_window_get_skip_taskbar_hint:
2545
* @window: a #GtkWindow
2547
* Gets the value set by gtk_window_set_skip_taskbar_hint()
2549
* Return value: %TRUE if window shouldn't be in taskbar
2554
gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2556
GtkWindowPrivate *priv;
2558
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2560
priv = GTK_WINDOW_GET_PRIVATE (window);
2562
return priv->skips_taskbar;
2566
* gtk_window_set_skip_pager_hint:
2567
* @window: a #GtkWindow
2568
* @setting: %TRUE to keep this window from appearing in the pager
2570
* Windows may set a hint asking the desktop environment not to display
2571
* the window in the pager. This function sets this hint.
2572
* (A "pager" is any desktop navigation tool such as a workspace
2573
* switcher that displays a thumbnail representation of the windows
2579
gtk_window_set_skip_pager_hint (GtkWindow *window,
2582
GtkWindowPrivate *priv;
2584
g_return_if_fail (GTK_IS_WINDOW (window));
2586
priv = GTK_WINDOW_GET_PRIVATE (window);
2588
setting = setting != FALSE;
2590
if (priv->skips_pager != setting)
2592
priv->skips_pager = setting;
2593
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2594
gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2596
g_object_notify (G_OBJECT (window), "skip-pager-hint");
2601
* gtk_window_get_skip_pager_hint:
2602
* @window: a #GtkWindow
2604
* Gets the value set by gtk_window_set_skip_pager_hint().
2606
* Return value: %TRUE if window shouldn't be in pager
2611
gtk_window_get_skip_pager_hint (GtkWindow *window)
2613
GtkWindowPrivate *priv;
2615
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2617
priv = GTK_WINDOW_GET_PRIVATE (window);
2619
return priv->skips_pager;
2623
* gtk_window_set_urgency_hint:
2624
* @window: a #GtkWindow
2625
* @setting: %TRUE to mark this window as urgent
2627
* Windows may set a hint asking the desktop environment to draw
2628
* the users attention to the window. This function sets this hint.
2633
gtk_window_set_urgency_hint (GtkWindow *window,
2636
GtkWindowPrivate *priv;
2638
g_return_if_fail (GTK_IS_WINDOW (window));
2640
priv = GTK_WINDOW_GET_PRIVATE (window);
2642
setting = setting != FALSE;
2644
if (priv->urgent != setting)
2646
priv->urgent = setting;
2647
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2648
gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2650
g_object_notify (G_OBJECT (window), "urgency-hint");
2655
* gtk_window_get_urgency_hint:
2656
* @window: a #GtkWindow
2658
* Gets the value set by gtk_window_set_urgency_hint()
2660
* Return value: %TRUE if window is urgent
2665
gtk_window_get_urgency_hint (GtkWindow *window)
2667
GtkWindowPrivate *priv;
2669
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2671
priv = GTK_WINDOW_GET_PRIVATE (window);
2673
return priv->urgent;
2677
* gtk_window_set_accept_focus:
2678
* @window: a #GtkWindow
2679
* @setting: %TRUE to let this window receive input focus
2681
* Windows may set a hint asking the desktop environment not to receive
2682
* the input focus. This function sets this hint.
2687
gtk_window_set_accept_focus (GtkWindow *window,
2690
GtkWindowPrivate *priv;
2692
g_return_if_fail (GTK_IS_WINDOW (window));
2694
priv = GTK_WINDOW_GET_PRIVATE (window);
2696
setting = setting != FALSE;
2698
if (priv->accept_focus != setting)
2700
priv->accept_focus = setting;
2701
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2702
gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2703
priv->accept_focus);
2704
g_object_notify (G_OBJECT (window), "accept-focus");
2709
* gtk_window_get_accept_focus:
2710
* @window: a #GtkWindow
2712
* Gets the value set by gtk_window_set_accept_focus().
2714
* Return value: %TRUE if window should receive the input focus
2719
gtk_window_get_accept_focus (GtkWindow *window)
2721
GtkWindowPrivate *priv;
2723
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2725
priv = GTK_WINDOW_GET_PRIVATE (window);
2727
return priv->accept_focus;
2731
* gtk_window_set_focus_on_map:
2732
* @window: a #GtkWindow
2733
* @setting: %TRUE to let this window receive input focus on map
2735
* Windows may set a hint asking the desktop environment not to receive
2736
* the input focus when the window is mapped. This function sets this
2742
gtk_window_set_focus_on_map (GtkWindow *window,
2745
GtkWindowPrivate *priv;
2747
g_return_if_fail (GTK_IS_WINDOW (window));
2749
priv = GTK_WINDOW_GET_PRIVATE (window);
2751
setting = setting != FALSE;
2753
if (priv->focus_on_map != setting)
2755
priv->focus_on_map = setting;
2756
if (gtk_widget_get_realized (GTK_WIDGET (window)))
2757
gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2758
priv->focus_on_map);
2759
g_object_notify (G_OBJECT (window), "focus-on-map");
2764
* gtk_window_get_focus_on_map:
2765
* @window: a #GtkWindow
2767
* Gets the value set by gtk_window_set_focus_on_map().
2769
* Return value: %TRUE if window should receive the input focus when
2775
gtk_window_get_focus_on_map (GtkWindow *window)
2777
GtkWindowPrivate *priv;
2779
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2781
priv = GTK_WINDOW_GET_PRIVATE (window);
2783
return priv->focus_on_map;
2787
* gtk_window_set_destroy_with_parent:
2788
* @window: a #GtkWindow
2789
* @setting: whether to destroy @window with its transient parent
2791
* If @setting is %TRUE, then destroying the transient parent of @window
2792
* will also destroy @window itself. This is useful for dialogs that
2793
* shouldn't persist beyond the lifetime of the main window they're
2794
* associated with, for example.
2797
gtk_window_set_destroy_with_parent (GtkWindow *window,
2800
g_return_if_fail (GTK_IS_WINDOW (window));
2802
if (window->destroy_with_parent == (setting != FALSE))
2805
if (window->destroy_with_parent)
2807
disconnect_parent_destroyed (window);
2811
connect_parent_destroyed (window);
2814
window->destroy_with_parent = setting;
2816
g_object_notify (G_OBJECT (window), "destroy-with-parent");
2820
* gtk_window_get_destroy_with_parent:
2821
* @window: a #GtkWindow
2823
* Returns whether the window will be destroyed with its transient parent. See
2824
* gtk_window_set_destroy_with_parent ().
2826
* Return value: %TRUE if the window will be destroyed with its transient parent.
2829
gtk_window_get_destroy_with_parent (GtkWindow *window)
2831
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2833
return window->destroy_with_parent;
2836
static GtkWindowGeometryInfo*
2837
gtk_window_get_geometry_info (GtkWindow *window,
2840
GtkWindowGeometryInfo *info;
2842
info = window->geometry_info;
2843
if (!info && create)
2845
info = g_new0 (GtkWindowGeometryInfo, 1);
2847
info->default_width = -1;
2848
info->default_height = -1;
2849
info->resize_width = -1;
2850
info->resize_height = -1;
2851
info->initial_x = 0;
2852
info->initial_y = 0;
2853
info->initial_pos_set = FALSE;
2854
info->default_is_geometry = FALSE;
2855
info->position_constraints_changed = FALSE;
2856
info->last.configure_request.x = 0;
2857
info->last.configure_request.y = 0;
2858
info->last.configure_request.width = -1;
2859
info->last.configure_request.height = -1;
2860
info->widget = NULL;
2862
window->geometry_info = info;
2869
* gtk_window_set_geometry_hints:
2870
* @window: a #GtkWindow
2871
* @geometry_widget: widget the geometry hints will be applied to
2872
* @geometry: struct containing geometry information
2873
* @geom_mask: mask indicating which struct fields should be paid attention to
2875
* This function sets up hints about how a window can be resized by
2876
* the user. You can set a minimum and maximum size; allowed resize
2877
* increments (e.g. for xterm, you can only resize by the size of a
2878
* character); aspect ratios; and more. See the #GdkGeometry struct.
2882
gtk_window_set_geometry_hints (GtkWindow *window,
2883
GtkWidget *geometry_widget,
2884
GdkGeometry *geometry,
2885
GdkWindowHints geom_mask)
2887
GtkWindowGeometryInfo *info;
2889
g_return_if_fail (GTK_IS_WINDOW (window));
2890
g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2892
info = gtk_window_get_geometry_info (window, TRUE);
2895
g_signal_handlers_disconnect_by_func (info->widget,
2896
gtk_widget_destroyed,
2899
info->widget = geometry_widget;
2901
g_signal_connect (geometry_widget, "destroy",
2902
G_CALLBACK (gtk_widget_destroyed),
2906
info->geometry = *geometry;
2908
/* We store gravity in window->gravity not in the hints. */
2909
info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2911
if (geom_mask & GDK_HINT_WIN_GRAVITY)
2913
gtk_window_set_gravity (window, geometry->win_gravity);
2916
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2920
* gtk_window_set_decorated:
2921
* @window: a #GtkWindow
2922
* @setting: %TRUE to decorate the window
2924
* By default, windows are decorated with a title bar, resize
2925
* controls, etc. Some <link linkend="gtk-X11-arch">window
2926
* managers</link> allow GTK+ to disable these decorations, creating a
2927
* borderless window. If you set the decorated property to %FALSE
2928
* using this function, GTK+ will do its best to convince the window
2929
* manager not to decorate the window. Depending on the system, this
2930
* function may not have any effect when called on a window that is
2931
* already visible, so you should call it before calling gtk_window_show().
2933
* On Windows, this function always works, since there's no window manager
2938
gtk_window_set_decorated (GtkWindow *window,
2941
g_return_if_fail (GTK_IS_WINDOW (window));
2943
setting = setting != FALSE;
2945
if (setting == window->decorated)
2948
window->decorated = setting;
2950
if (GTK_WIDGET (window)->window)
2952
if (window->decorated)
2953
gdk_window_set_decorations (GTK_WIDGET (window)->window,
2956
gdk_window_set_decorations (GTK_WIDGET (window)->window,
2960
g_object_notify (G_OBJECT (window), "decorated");
2964
* gtk_window_get_decorated:
2965
* @window: a #GtkWindow
2967
* Returns whether the window has been set to have decorations
2968
* such as a title bar via gtk_window_set_decorated().
2970
* Return value: %TRUE if the window has been set to have decorations
2973
gtk_window_get_decorated (GtkWindow *window)
2975
g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2977
return window->decorated;
2981
* gtk_window_set_deletable:
2982
* @window: a #GtkWindow
2983
* @setting: %TRUE to decorate the window as deletable
2985
* By default, windows have a close button in the window frame. Some
2986
* <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2987
* disable this button. If you set the deletable property to %FALSE
2988
* using this function, GTK+ will do its best to convince the window
2989
* manager not to show a close button. Depending on the system, this
2990
* function may not have any effect when called on a window that is
2991
* already visible, so you should call it before calling gtk_window_show().
2993
* On Windows, this function always works, since there's no window manager
2999
gtk_window_set_deletable (GtkWindow *window,
3002
GtkWindowPrivate *priv;
3004
g_return_if_fail (GTK_IS_WINDOW (window));
3006
priv = GTK_WINDOW_GET_PRIVATE (window);
3008
setting = setting != FALSE;
3010
if (setting == priv->deletable)
3013
priv->deletable = setting;
3015
if (GTK_WIDGET (window)->window)
3017
if (priv->deletable)
3018
gdk_window_set_functions (GTK_WIDGET (window)->window,
3021
gdk_window_set_functions (GTK_WIDGET (window)->window,
3022
GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3025
g_object_notify (G_OBJECT (window), "deletable");
3029
* gtk_window_get_deletable:
3030
* @window: a #GtkWindow
3032
* Returns whether the window has been set to have a close button
3033
* via gtk_window_set_deletable().
3035
* Return value: %TRUE if the window has been set to have a close button
3040
gtk_window_get_deletable (GtkWindow *window)
3042
GtkWindowPrivate *priv;
3044
g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3046
priv = GTK_WINDOW_GET_PRIVATE (window);
3048
return priv->deletable;
3051
static GtkWindowIconInfo*
3052
get_icon_info (GtkWindow *window)
3054
return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3058
free_icon_info (GtkWindowIconInfo *info)
3060
g_free (info->icon_name);
3061
g_slice_free (GtkWindowIconInfo, info);
3065
static GtkWindowIconInfo*
3066
ensure_icon_info (GtkWindow *window)
3068
GtkWindowIconInfo *info;
3070
info = get_icon_info (window);
3074
info = g_slice_new0 (GtkWindowIconInfo);
3075
g_object_set_qdata_full (G_OBJECT (window),
3076
quark_gtk_window_icon_info,
3078
(GDestroyNotify)free_icon_info);
3090
static ScreenIconInfo *
3091
get_screen_icon_info (GdkScreen *screen)
3093
ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3094
quark_gtk_window_default_icon_pixmap);
3097
info = g_slice_new0 (ScreenIconInfo);
3098
g_object_set_qdata (G_OBJECT (screen),
3099
quark_gtk_window_default_icon_pixmap, info);
3102
if (info->serial != default_icon_serial)
3106
g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3107
info->pixmap = NULL;
3112
g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3116
info->serial = default_icon_serial;
3123
get_pixmap_and_mask (GdkWindow *window,
3124
GtkWindowIconInfo *parent_info,
3125
gboolean is_default_list,
3127
GdkPixmap **pmap_return,
3128
GdkBitmap **mask_return)
3130
GdkScreen *screen = gdk_window_get_screen (window);
3131
ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3132
GdkPixbuf *best_icon;
3136
*pmap_return = NULL;
3137
*mask_return = NULL;
3139
if (is_default_list &&
3140
default_icon_info->pixmap != NULL)
3142
/* Use shared icon pixmap for all windows on this screen.
3144
if (default_icon_info->pixmap)
3145
g_object_ref (default_icon_info->pixmap);
3146
if (default_icon_info->mask)
3147
g_object_ref (default_icon_info->mask);
3149
*pmap_return = default_icon_info->pixmap;
3150
*mask_return = default_icon_info->mask;
3152
else if (parent_info && parent_info->icon_pixmap)
3154
if (parent_info->icon_pixmap)
3155
g_object_ref (parent_info->icon_pixmap);
3156
if (parent_info->icon_mask)
3157
g_object_ref (parent_info->icon_mask);
3159
*pmap_return = parent_info->icon_pixmap;
3160
*mask_return = parent_info->icon_mask;
3164
#define IDEAL_SIZE 48
3166
best_size = G_MAXINT;
3168
tmp_list = icon_list;
3169
while (tmp_list != NULL)
3171
GdkPixbuf *pixbuf = tmp_list->data;
3174
/* average width and height - if someone passes in a rectangular
3175
* icon they deserve what they get.
3177
this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3180
if (best_icon == NULL)
3187
/* icon is better if it's 32 pixels or larger, and closer to
3188
* the ideal size than the current best.
3191
(ABS (best_size - IDEAL_SIZE) <
3192
ABS (this - IDEAL_SIZE)))
3199
tmp_list = tmp_list->next;
3203
gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3204
gdk_screen_get_system_colormap (screen),
3209
/* Save pmap/mask for others to use if appropriate */
3212
parent_info->icon_pixmap = *pmap_return;
3213
parent_info->icon_mask = *mask_return;
3215
if (parent_info->icon_pixmap)
3216
g_object_ref (parent_info->icon_pixmap);
3217
if (parent_info->icon_mask)
3218
g_object_ref (parent_info->icon_mask);
3220
else if (is_default_list)
3222
default_icon_info->pixmap = *pmap_return;
3223
default_icon_info->mask = *mask_return;
3225
if (default_icon_info->pixmap)
3226
g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3227
(gpointer*)&default_icon_info->pixmap);
3228
if (default_icon_info->mask)
3229
g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3230
(gpointer*)&default_icon_info->mask);
3236
icon_list_from_theme (GtkWidget *widget,
3241
GtkIconTheme *icon_theme;
3246
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3248
sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3251
for (i = 0; sizes[i]; i++)
3254
* We need an EWMH extension to handle scalable icons
3255
* by passing their name to the WM. For now just use a
3259
icon = gtk_icon_theme_load_icon (icon_theme, name,
3262
icon = gtk_icon_theme_load_icon (icon_theme, name,
3265
list = g_list_append (list, icon);
3275
gtk_window_realize_icon (GtkWindow *window)
3278
GtkWindowIconInfo *info;
3281
widget = GTK_WIDGET (window);
3283
g_return_if_fail (widget->window != NULL);
3285
/* no point setting an icon on override-redirect */
3286
if (window->type == GTK_WINDOW_POPUP)
3291
info = ensure_icon_info (window);
3296
g_return_if_fail (info->icon_pixmap == NULL);
3297
g_return_if_fail (info->icon_mask == NULL);
3299
info->using_default_icon = FALSE;
3300
info->using_parent_icon = FALSE;
3301
info->using_themed_icon = FALSE;
3303
icon_list = info->icon_list;
3305
/* Look up themed icon */
3306
if (icon_list == NULL && info->icon_name)
3308
icon_list = icon_list_from_theme (widget, info->icon_name);
3310
info->using_themed_icon = TRUE;
3313
/* Inherit from transient parent */
3314
if (icon_list == NULL && window->transient_parent)
3316
icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3318
info->using_parent_icon = TRUE;
3321
/* Inherit from default */
3322
if (icon_list == NULL)
3324
icon_list = default_icon_list;
3326
info->using_default_icon = TRUE;
3329
/* Look up themed icon */
3330
if (icon_list == NULL && default_icon_name)
3332
icon_list = icon_list_from_theme (widget, default_icon_name);
3333
info->using_default_icon = TRUE;
3334
info->using_themed_icon = TRUE;
3337
gdk_window_set_icon_list (widget->window, icon_list);
3339
get_pixmap_and_mask (widget->window,
3340
info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3341
info->using_default_icon,
3346
/* This is a slight ICCCM violation since it's a color pixmap not
3347
* a bitmap, but everyone does it.
3349
gdk_window_set_icon (widget->window,
3354
info->realized = TRUE;
3356
if (info->using_themed_icon)
3358
GtkIconTheme *icon_theme;
3360
g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3361
g_list_free (icon_list);
3363
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3364
g_signal_connect (icon_theme, "changed",
3365
G_CALLBACK (update_themed_icon), window);
3370
gtk_window_unrealize_icon (GtkWindow *window)
3372
GtkWindowIconInfo *info;
3374
info = get_icon_info (window);
3379
if (info->icon_pixmap)
3380
g_object_unref (info->icon_pixmap);
3382
if (info->icon_mask)
3383
g_object_unref (info->icon_mask);
3385
info->icon_pixmap = NULL;
3386
info->icon_mask = NULL;
3388
if (info->using_themed_icon)
3390
GtkIconTheme *icon_theme;
3392
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3394
g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3397
/* We don't clear the properties on the window, just figure the
3398
* window is going away.
3401
info->realized = FALSE;
3406
* gtk_window_set_icon_list:
3407
* @window: a #GtkWindow
3408
* @list: list of #GdkPixbuf
3410
* Sets up the icon representing a #GtkWindow. The icon is used when
3411
* the window is minimized (also known as iconified). Some window
3412
* managers or desktop environments may also place it in the window
3413
* frame, or display it in other contexts.
3415
* gtk_window_set_icon_list() allows you to pass in the same icon in
3416
* several hand-drawn sizes. The list should contain the natural sizes
3417
* your icon is available in; that is, don't scale the image before
3418
* passing it to GTK+. Scaling is postponed until the last minute,
3419
* when the desired final size is known, to allow best quality.
3421
* By passing several sizes, you may improve the final image quality
3422
* of the icon, by reducing or eliminating automatic image scaling.
3424
* Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3425
* larger images (64x64, 128x128) if you have them.
3427
* See also gtk_window_set_default_icon_list() to set the icon
3428
* for all windows in your application in one go.
3430
* Note that transient windows (those who have been set transient for another
3431
* window using gtk_window_set_transient_for()) will inherit their
3432
* icon from their transient parent. So there's no need to explicitly
3433
* set the icon on transient windows.
3436
gtk_window_set_icon_list (GtkWindow *window,
3439
GtkWindowIconInfo *info;
3441
g_return_if_fail (GTK_IS_WINDOW (window));
3443
info = ensure_icon_info (window);
3445
if (info->icon_list == list) /* check for NULL mostly */
3448
g_list_foreach (list,
3449
(GFunc) g_object_ref, NULL);
3451
g_list_foreach (info->icon_list,
3452
(GFunc) g_object_unref, NULL);
3454
g_list_free (info->icon_list);
3456
info->icon_list = g_list_copy (list);
3458
g_object_notify (G_OBJECT (window), "icon");
3460
gtk_window_unrealize_icon (window);
3462
if (gtk_widget_get_realized (GTK_WIDGET (window)))
3463
gtk_window_realize_icon (window);
3465
/* We could try to update our transient children, but I don't think
3466
* it's really worth it. If we did it, the best way would probably
3467
* be to have children connect to notify::icon-list
3472
* gtk_window_get_icon_list:
3473
* @window: a #GtkWindow
3475
* Retrieves the list of icons set by gtk_window_set_icon_list().
3476
* The list is copied, but the reference count on each
3477
* member won't be incremented.
3479
* Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3482
gtk_window_get_icon_list (GtkWindow *window)
3484
GtkWindowIconInfo *info;
3486
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3488
info = get_icon_info (window);
3491
return g_list_copy (info->icon_list);
3497
* gtk_window_set_icon:
3498
* @window: a #GtkWindow
3499
* @icon: (allow-none): icon image, or %NULL
3501
* Sets up the icon representing a #GtkWindow. This icon is used when
3502
* the window is minimized (also known as iconified). Some window
3503
* managers or desktop environments may also place it in the window
3504
* frame, or display it in other contexts.
3506
* The icon should be provided in whatever size it was naturally
3507
* drawn; that is, don't scale the image before passing it to
3508
* GTK+. Scaling is postponed until the last minute, when the desired
3509
* final size is known, to allow best quality.
3511
* If you have your icon hand-drawn in multiple sizes, use
3512
* gtk_window_set_icon_list(). Then the best size will be used.
3514
* This function is equivalent to calling gtk_window_set_icon_list()
3515
* with a 1-element list.
3517
* See also gtk_window_set_default_icon_list() to set the icon
3518
* for all windows in your application in one go.
3521
gtk_window_set_icon (GtkWindow *window,
3526
g_return_if_fail (GTK_IS_WINDOW (window));
3527
g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3532
list = g_list_append (list, icon);
3534
gtk_window_set_icon_list (window, list);
3540
update_themed_icon (GtkIconTheme *icon_theme,
3543
g_object_notify (G_OBJECT (window), "icon");
3545
gtk_window_unrealize_icon (window);
3547
if (gtk_widget_get_realized (GTK_WIDGET (window)))
3548
gtk_window_realize_icon (window);
3552
* gtk_window_set_icon_name:
3553
* @window: a #GtkWindow
3554
* @name: (allow-none): the name of the themed icon
3556
* Sets the icon for the window from a named themed icon. See
3557
* the docs for #GtkIconTheme for more details.
3559
* Note that this has nothing to do with the WM_ICON_NAME
3560
* property which is mentioned in the ICCCM.
3565
gtk_window_set_icon_name (GtkWindow *window,
3568
GtkWindowIconInfo *info;
3571
g_return_if_fail (GTK_IS_WINDOW (window));
3573
info = ensure_icon_info (window);
3575
if (g_strcmp0 (info->icon_name, name) == 0)
3578
tmp = info->icon_name;
3579
info->icon_name = g_strdup (name);
3582
g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3583
g_list_free (info->icon_list);
3584
info->icon_list = NULL;
3586
update_themed_icon (NULL, window);
3588
g_object_notify (G_OBJECT (window), "icon-name");
3592
* gtk_window_get_icon_name:
3593
* @window: a #GtkWindow
3595
* Returns the name of the themed icon for the window,
3596
* see gtk_window_set_icon_name().
3598
* Returns: the icon name or %NULL if the window has
3604
gtk_window_get_icon_name (GtkWindow *window)
3606
GtkWindowIconInfo *info;
3608
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3610
info = ensure_icon_info (window);
3612
return info->icon_name;
3616
* gtk_window_get_icon:
3617
* @window: a #GtkWindow
3619
* Gets the value set by gtk_window_set_icon() (or if you've
3620
* called gtk_window_set_icon_list(), gets the first icon in
3623
* Return value: (transfer none): icon for window
3626
gtk_window_get_icon (GtkWindow *window)
3628
GtkWindowIconInfo *info;
3630
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3632
info = get_icon_info (window);
3633
if (info && info->icon_list)
3634
return GDK_PIXBUF (info->icon_list->data);
3639
/* Load pixbuf, printing warning on failure if error == NULL
3642
load_pixbuf_verbosely (const char *filename,
3645
GError *local_err = NULL;
3648
pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3656
g_warning ("Error loading icon from file '%s':\n\t%s",
3657
filename, local_err->message);
3658
g_error_free (local_err);
3666
* gtk_window_set_icon_from_file:
3667
* @window: a #GtkWindow
3668
* @filename: location of icon file
3669
* @err: (allow-none): location to store error, or %NULL.
3671
* Sets the icon for @window.
3672
* Warns on failure if @err is %NULL.
3674
* This function is equivalent to calling gtk_window_set_icon()
3675
* with a pixbuf created by loading the image from @filename.
3677
* Returns: %TRUE if setting the icon succeeded.
3682
gtk_window_set_icon_from_file (GtkWindow *window,
3683
const gchar *filename,
3686
GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3690
gtk_window_set_icon (window, pixbuf);
3691
g_object_unref (pixbuf);
3700
* gtk_window_set_default_icon_list:
3701
* @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3703
* Sets an icon list to be used as fallback for windows that haven't
3704
* had gtk_window_set_icon_list() called on them to set up a
3705
* window-specific icon list. This function allows you to set up the
3706
* icon for all windows in your app at once.
3708
* See gtk_window_set_icon_list() for more details.
3712
gtk_window_set_default_icon_list (GList *list)
3716
if (list == default_icon_list)
3719
/* Update serial so we don't used cached pixmaps/masks
3721
default_icon_serial++;
3723
g_list_foreach (list,
3724
(GFunc) g_object_ref, NULL);
3726
g_list_foreach (default_icon_list,
3727
(GFunc) g_object_unref, NULL);
3729
g_list_free (default_icon_list);
3731
default_icon_list = g_list_copy (list);
3733
/* Update all toplevels */
3734
toplevels = gtk_window_list_toplevels ();
3735
tmp_list = toplevels;
3736
while (tmp_list != NULL)
3738
GtkWindowIconInfo *info;
3739
GtkWindow *w = tmp_list->data;
3741
info = get_icon_info (w);
3742
if (info && info->using_default_icon)
3744
gtk_window_unrealize_icon (w);
3745
if (gtk_widget_get_realized (GTK_WIDGET (w)))
3746
gtk_window_realize_icon (w);
3749
tmp_list = tmp_list->next;
3751
g_list_free (toplevels);
3755
* gtk_window_set_default_icon:
3758
* Sets an icon to be used as fallback for windows that haven't
3759
* had gtk_window_set_icon() called on them from a pixbuf.
3764
gtk_window_set_default_icon (GdkPixbuf *icon)
3768
g_return_if_fail (GDK_IS_PIXBUF (icon));
3770
list = g_list_prepend (NULL, icon);
3771
gtk_window_set_default_icon_list (list);
3776
* gtk_window_set_default_icon_name:
3777
* @name: the name of the themed icon
3779
* Sets an icon to be used as fallback for windows that haven't
3780
* had gtk_window_set_icon_list() called on them from a named
3781
* themed icon, see gtk_window_set_icon_name().
3786
gtk_window_set_default_icon_name (const gchar *name)
3791
/* Update serial so we don't used cached pixmaps/masks
3793
default_icon_serial++;
3795
g_free (default_icon_name);
3796
default_icon_name = g_strdup (name);
3798
g_list_foreach (default_icon_list,
3799
(GFunc) g_object_unref, NULL);
3801
g_list_free (default_icon_list);
3802
default_icon_list = NULL;
3804
/* Update all toplevels */
3805
toplevels = gtk_window_list_toplevels ();
3806
tmp_list = toplevels;
3807
while (tmp_list != NULL)
3809
GtkWindowIconInfo *info;
3810
GtkWindow *w = tmp_list->data;
3812
info = get_icon_info (w);
3813
if (info && info->using_default_icon && info->using_themed_icon)
3815
gtk_window_unrealize_icon (w);
3816
if (gtk_widget_get_realized (GTK_WIDGET (w)))
3817
gtk_window_realize_icon (w);
3820
tmp_list = tmp_list->next;
3822
g_list_free (toplevels);
3826
* gtk_window_get_default_icon_name:
3828
* Returns the fallback icon name for windows that has been set
3829
* with gtk_window_set_default_icon_name(). The returned
3830
* string is owned by GTK+ and should not be modified. It
3831
* is only valid until the next call to
3832
* gtk_window_set_default_icon_name().
3834
* Returns: the fallback icon name for windows
3839
gtk_window_get_default_icon_name (void)
3841
return default_icon_name;
3845
* gtk_window_set_default_icon_from_file:
3846
* @filename: location of icon file
3847
* @err: (allow-none): location to store error, or %NULL.
3849
* Sets an icon to be used as fallback for windows that haven't
3850
* had gtk_window_set_icon_list() called on them from a file
3851
* on disk. Warns on failure if @err is %NULL.
3853
* Returns: %TRUE if setting the icon succeeded.
3858
gtk_window_set_default_icon_from_file (const gchar *filename,
3861
GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3865
gtk_window_set_default_icon (pixbuf);
3866
g_object_unref (pixbuf);
3875
* gtk_window_get_default_icon_list:
3877
* Gets the value set by gtk_window_set_default_icon_list().
3878
* The list is a copy and should be freed with g_list_free(),
3879
* but the pixbufs in the list have not had their reference count
3882
* Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
3885
gtk_window_get_default_icon_list (void)
3887
return g_list_copy (default_icon_list);
3891
gtk_window_set_default_size_internal (GtkWindow *window,
3892
gboolean change_width,
3894
gboolean change_height,
3896
gboolean is_geometry)
3898
GtkWindowGeometryInfo *info;
3900
g_return_if_fail (change_width == FALSE || width >= -1);
3901
g_return_if_fail (change_height == FALSE || height >= -1);
3903
info = gtk_window_get_geometry_info (window, TRUE);
3905
g_object_freeze_notify (G_OBJECT (window));
3907
info->default_is_geometry = is_geometry != FALSE;
3917
info->default_width = width;
3919
g_object_notify (G_OBJECT (window), "default-width");
3930
info->default_height = height;
3932
g_object_notify (G_OBJECT (window), "default-height");
3935
g_object_thaw_notify (G_OBJECT (window));
3937
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3941
* gtk_window_set_default_size:
3942
* @window: a #GtkWindow
3943
* @width: width in pixels, or -1 to unset the default width
3944
* @height: height in pixels, or -1 to unset the default height
3946
* Sets the default size of a window. If the window's "natural" size
3947
* (its size request) is larger than the default, the default will be
3948
* ignored. More generally, if the default size does not obey the
3949
* geometry hints for the window (gtk_window_set_geometry_hints() can
3950
* be used to set these explicitly), the default size will be clamped
3951
* to the nearest permitted size.
3953
* Unlike gtk_widget_set_size_request(), which sets a size request for
3954
* a widget and thus would keep users from shrinking the window, this
3955
* function only sets the initial size, just as if the user had
3956
* resized the window themselves. Users can still shrink the window
3957
* again as they normally would. Setting a default size of -1 means to
3958
* use the "natural" default size (the size request of the window).
3960
* For more control over a window's initial size and how resizing works,
3961
* investigate gtk_window_set_geometry_hints().
3963
* For some uses, gtk_window_resize() is a more appropriate function.
3964
* gtk_window_resize() changes the current size of the window, rather
3965
* than the size to be used on initial display. gtk_window_resize() always
3966
* affects the window itself, not the geometry widget.
3968
* The default size of a window only affects the first time a window is
3969
* shown; if a window is hidden and re-shown, it will remember the size
3970
* it had prior to hiding, rather than using the default size.
3972
* Windows can't actually be 0x0 in size, they must be at least 1x1, but
3973
* passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3976
gtk_window_set_default_size (GtkWindow *window,
3980
g_return_if_fail (GTK_IS_WINDOW (window));
3981
g_return_if_fail (width >= -1);
3982
g_return_if_fail (height >= -1);
3984
gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3988
* gtk_window_get_default_size:
3989
* @window: a #GtkWindow
3990
* @width: (allow-none): location to store the default width, or %NULL
3991
* @height: (allow-none): location to store the default height, or %NULL
3993
* Gets the default size of the window. A value of -1 for the width or
3994
* height indicates that a default size has not been explicitly set
3995
* for that dimension, so the "natural" size of the window will be
4000
gtk_window_get_default_size (GtkWindow *window,
4004
GtkWindowGeometryInfo *info;
4006
g_return_if_fail (GTK_IS_WINDOW (window));
4008
info = gtk_window_get_geometry_info (window, FALSE);
4011
*width = info ? info->default_width : -1;
4014
*height = info ? info->default_height : -1;
4018
* gtk_window_resize:
4019
* @window: a #GtkWindow
4020
* @width: width in pixels to resize the window to
4021
* @height: height in pixels to resize the window to
4023
* Resizes the window as if the user had done so, obeying geometry
4024
* constraints. The default geometry constraint is that windows may
4025
* not be smaller than their size request; to override this
4026
* constraint, call gtk_widget_set_size_request() to set the window's
4027
* request to a smaller value.
4029
* If gtk_window_resize() is called before showing a window for the
4030
* first time, it overrides any default size set with
4031
* gtk_window_set_default_size().
4033
* Windows may not be resized smaller than 1 by 1 pixels.
4037
gtk_window_resize (GtkWindow *window,
4041
GtkWindowGeometryInfo *info;
4043
g_return_if_fail (GTK_IS_WINDOW (window));
4044
g_return_if_fail (width > 0);
4045
g_return_if_fail (height > 0);
4047
info = gtk_window_get_geometry_info (window, TRUE);
4049
info->resize_width = width;
4050
info->resize_height = height;
4052
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4056
* gtk_window_get_size:
4057
* @window: a #GtkWindow
4058
* @width: (out) (allow-none): return location for width, or %NULL
4059
* @height: (out) (allow-none): return location for height, or %NULL
4061
* Obtains the current size of @window. If @window is not onscreen,
4062
* it returns the size GTK+ will suggest to the <link
4063
* linkend="gtk-X11-arch">window manager</link> for the initial window
4064
* size (but this is not reliably the same as the size the window
4065
* manager will actually select). The size obtained by
4066
* gtk_window_get_size() is the last size received in a
4067
* #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4068
* rather than querying the X server for the size. As a result, if you
4069
* call gtk_window_resize() then immediately call
4070
* gtk_window_get_size(), the size won't have taken effect yet. After
4071
* the window manager processes the resize request, GTK+ receives
4072
* notification that the size has changed via a configure event, and
4073
* the size of the window gets updated.
4075
* Note 1: Nearly any use of this function creates a race condition,
4076
* because the size of the window may change between the time that you
4077
* get the size and the time that you perform some action assuming
4078
* that size is the current size. To avoid race conditions, connect to
4079
* "configure-event" on the window and adjust your size-dependent
4080
* state to match the size delivered in the #GdkEventConfigure.
4082
* Note 2: The returned size does <emphasis>not</emphasis> include the
4083
* size of the window manager decorations (aka the window frame or
4084
* border). Those are not drawn by GTK+ and GTK+ has no reliable
4085
* method of determining their size.
4087
* Note 3: If you are getting a window size in order to position
4088
* the window onscreen, there may be a better way. The preferred
4089
* way is to simply set the window's semantic type with
4090
* gtk_window_set_type_hint(), which allows the window manager to
4091
* e.g. center dialogs. Also, if you set the transient parent of
4092
* dialogs with gtk_window_set_transient_for() window managers
4093
* will often center the dialog over its parent window. It's
4094
* much preferred to let the window manager handle these
4095
* things rather than doing it yourself, because all apps will
4096
* behave consistently and according to user prefs if the window
4097
* manager handles it. Also, the window manager can take the size
4098
* of the window decorations/border into account, while your
4099
* application cannot.
4101
* In any case, if you insist on application-specified window
4102
* positioning, there's <emphasis>still</emphasis> a better way than
4103
* doing it yourself - gtk_window_set_position() will frequently
4104
* handle the details for you.
4108
gtk_window_get_size (GtkWindow *window,
4114
g_return_if_fail (GTK_IS_WINDOW (window));
4116
if (width == NULL && height == NULL)
4119
if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4121
w = gdk_window_get_width (GTK_WIDGET (window)->window);
4122
h = gdk_window_get_height (GTK_WIDGET (window)->window);
4126
GdkRectangle configure_request;
4128
gtk_window_compute_configure_request (window,
4132
w = configure_request.width;
4133
h = configure_request.height;
4144
* @window: a #GtkWindow
4145
* @x: X coordinate to move window to
4146
* @y: Y coordinate to move window to
4148
* Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4149
* @window to the given position. Window managers are free to ignore
4150
* this; most window managers ignore requests for initial window
4151
* positions (instead using a user-defined placement algorithm) and
4152
* honor requests after the window has already been shown.
4154
* Note: the position is the position of the gravity-determined
4155
* reference point for the window. The gravity determines two things:
4156
* first, the location of the reference point in root window
4157
* coordinates; and second, which point on the window is positioned at
4158
* the reference point.
4160
* By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4161
* point is simply the @x, @y supplied to gtk_window_move(). The
4162
* top-left corner of the window decorations (aka window frame or
4163
* border) will be placed at @x, @y. Therefore, to position a window
4164
* at the top left of the screen, you want to use the default gravity
4165
* (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4167
* To position a window at the bottom right corner of the screen, you
4168
* would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4169
* point is at @x + the window width and @y + the window height, and
4170
* the bottom-right corner of the window border will be placed at that
4171
* reference point. So, to place a window in the bottom right corner
4172
* you would first set gravity to south east, then write:
4173
* <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4174
* gdk_screen_height () - window_height)</literal> (note that this
4175
* example does not take multi-head scenarios into account).
4177
* The Extended Window Manager Hints specification at <ulink
4178
* url="http://www.freedesktop.org/Standards/wm-spec">
4179
* http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4180
* nice table of gravities in the "implementation notes" section.
4182
* The gtk_window_get_position() documentation may also be relevant.
4185
gtk_window_move (GtkWindow *window,
4189
GtkWindowGeometryInfo *info;
4192
g_return_if_fail (GTK_IS_WINDOW (window));
4194
widget = GTK_WIDGET (window);
4196
info = gtk_window_get_geometry_info (window, TRUE);
4198
if (gtk_widget_get_mapped (widget))
4200
/* we have now sent a request with this position
4201
* with currently-active constraints, so toggle flag.
4203
info->position_constraints_changed = FALSE;
4205
/* we only constrain if mapped - if not mapped,
4206
* then gtk_window_compute_configure_request()
4207
* will apply the constraints later, and we
4208
* don't want to lose information about
4209
* what position the user set before then.
4210
* i.e. if you do a move() then turn off POS_CENTER
4211
* then show the window, your move() will work.
4213
gtk_window_constrain_position (window,
4214
widget->allocation.width,
4215
widget->allocation.height,
4218
/* Note that this request doesn't go through our standard request
4219
* framework, e.g. doesn't increment configure_request_count,
4220
* doesn't set info->last, etc.; that's because
4221
* we don't save the info needed to arrive at this same request
4224
* To gtk_window_move_resize(), this will end up looking exactly
4225
* the same as the position being changed by the window
4229
/* FIXME are we handling gravity properly for framed windows? */
4231
gdk_window_move (window->frame,
4232
x - window->frame_left,
4233
y - window->frame_top);
4235
gdk_window_move (GTK_WIDGET (window)->window,
4240
/* Save this position to apply on mapping */
4241
info->initial_x = x;
4242
info->initial_y = y;
4243
info->initial_pos_set = TRUE;
4248
* gtk_window_get_position:
4249
* @window: a #GtkWindow
4250
* @root_x: (out) (allow-none): return location for X coordinate of gravity-determined reference point
4251
* @root_y: (out) (allow-none): return location for Y coordinate of gravity-determined reference point
4253
* This function returns the position you need to pass to
4254
* gtk_window_move() to keep @window in its current position. This
4255
* means that the meaning of the returned value varies with window
4256
* gravity. See gtk_window_move() for more details.
4258
* If you haven't changed the window gravity, its gravity will be
4259
* #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4260
* gets the position of the top-left corner of the window manager
4261
* frame for the window. gtk_window_move() sets the position of this
4262
* same top-left corner.
4264
* gtk_window_get_position() is not 100% reliable because the X Window System
4265
* does not specify a way to obtain the geometry of the
4266
* decorations placed on a window by the window manager.
4267
* Thus GTK+ is using a "best guess" that works with most
4270
* Moreover, nearly all window managers are historically broken with
4271
* respect to their handling of window gravity. So moving a window to
4272
* its current position as returned by gtk_window_get_position() tends
4273
* to result in moving the window slightly. Window managers are
4274
* slowly getting better over time.
4276
* If a window has gravity #GDK_GRAVITY_STATIC the window manager
4277
* frame is not relevant, and thus gtk_window_get_position() will
4278
* always produce accurate results. However you can't use static
4279
* gravity to do things like place a window in a corner of the screen,
4280
* because static gravity ignores the window manager decorations.
4282
* If you are saving and restoring your application's window
4283
* positions, you should know that it's impossible for applications to
4284
* do this without getting it somewhat wrong because applications do
4285
* not have sufficient knowledge of window manager state. The Correct
4286
* Mechanism is to support the session management protocol (see the
4287
* "GnomeClient" object in the GNOME libraries for example) and allow
4288
* the window manager to save your window sizes and positions.
4293
gtk_window_get_position (GtkWindow *window,
4299
g_return_if_fail (GTK_IS_WINDOW (window));
4301
widget = GTK_WIDGET (window);
4303
if (window->gravity == GDK_GRAVITY_STATIC)
4305
if (gtk_widget_get_mapped (widget))
4307
/* This does a server round-trip, which is sort of wrong;
4308
* but a server round-trip is inevitable for
4309
* gdk_window_get_frame_extents() in the usual
4310
* NorthWestGravity case below, so not sure what else to
4311
* do. We should likely be consistent about whether we get
4312
* the client-side info or the server-side info.
4314
gdk_window_get_origin (widget->window, root_x, root_y);
4318
GdkRectangle configure_request;
4320
gtk_window_compute_configure_request (window,
4324
*root_x = configure_request.x;
4325
*root_y = configure_request.y;
4330
GdkRectangle frame_extents;
4335
if (gtk_widget_get_mapped (widget))
4338
gdk_window_get_frame_extents (window->frame, &frame_extents);
4340
gdk_window_get_frame_extents (widget->window, &frame_extents);
4341
x = frame_extents.x;
4342
y = frame_extents.y;
4343
gtk_window_get_size (window, &w, &h);
4347
/* We just say the frame has 0 size on all sides.
4348
* Not sure what else to do.
4350
gtk_window_compute_configure_request (window,
4353
x = frame_extents.x;
4354
y = frame_extents.y;
4355
w = frame_extents.width;
4356
h = frame_extents.height;
4359
switch (window->gravity)
4361
case GDK_GRAVITY_NORTH:
4362
case GDK_GRAVITY_CENTER:
4363
case GDK_GRAVITY_SOUTH:
4364
/* Find center of frame. */
4365
x += frame_extents.width / 2;
4366
/* Center client window on that point. */
4370
case GDK_GRAVITY_SOUTH_EAST:
4371
case GDK_GRAVITY_EAST:
4372
case GDK_GRAVITY_NORTH_EAST:
4373
/* Find right edge of frame */
4374
x += frame_extents.width;
4375
/* Align left edge of client at that point. */
4382
switch (window->gravity)
4384
case GDK_GRAVITY_WEST:
4385
case GDK_GRAVITY_CENTER:
4386
case GDK_GRAVITY_EAST:
4387
/* Find center of frame. */
4388
y += frame_extents.height / 2;
4389
/* Center client window there. */
4392
case GDK_GRAVITY_SOUTH_WEST:
4393
case GDK_GRAVITY_SOUTH:
4394
case GDK_GRAVITY_SOUTH_EAST:
4395
/* Find south edge of frame */
4396
y += frame_extents.height;
4397
/* Place bottom edge of client there */
4412
* gtk_window_reshow_with_initial_size:
4413
* @window: a #GtkWindow
4415
* Hides @window, then reshows it, resetting the
4416
* default size and position of the window. Used
4417
* by GUI builders only.
4420
gtk_window_reshow_with_initial_size (GtkWindow *window)
4424
g_return_if_fail (GTK_IS_WINDOW (window));
4426
widget = GTK_WIDGET (window);
4428
gtk_widget_hide (widget);
4429
gtk_widget_unrealize (widget);
4430
gtk_widget_show (widget);
4434
gtk_window_destroy (GtkObject *object)
4436
GtkWindow *window = GTK_WINDOW (object);
4438
toplevel_list = g_slist_remove (toplevel_list, window);
4440
if (window->transient_parent)
4441
gtk_window_set_transient_for (window, NULL);
4443
/* frees the icons */
4444
gtk_window_set_icon_list (window, NULL);
4446
if (window->has_user_ref_count)
4448
window->has_user_ref_count = FALSE;
4449
g_object_unref (window);
4453
gtk_window_group_remove_window (window->group, window);
4455
gtk_window_free_key_hash (window);
4457
GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4461
gtk_window_finalize (GObject *object)
4463
GtkWindow *window = GTK_WINDOW (object);
4464
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4465
GtkMnemonicHash *mnemonic_hash;
4467
g_free (window->title);
4468
g_free (window->wmclass_name);
4469
g_free (window->wmclass_class);
4470
g_free (window->wm_role);
4472
mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4474
_gtk_mnemonic_hash_free (mnemonic_hash);
4476
if (window->geometry_info)
4478
if (window->geometry_info->widget)
4479
g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4480
gtk_widget_destroyed,
4481
&window->geometry_info->widget);
4482
g_free (window->geometry_info);
4485
if (window->keys_changed_handler)
4487
g_source_remove (window->keys_changed_handler);
4488
window->keys_changed_handler = 0;
4492
g_signal_handlers_disconnect_by_func (window->screen,
4493
gtk_window_on_composited_changed, window);
4495
g_free (priv->startup_id);
4497
G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4501
gtk_window_show (GtkWidget *widget)
4503
GtkWindow *window = GTK_WINDOW (widget);
4504
GtkContainer *container = GTK_CONTAINER (window);
4505
gboolean need_resize;
4507
GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4509
need_resize = container->need_resize || !gtk_widget_get_realized (widget);
4510
container->need_resize = FALSE;
4514
GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4515
GtkAllocation allocation = { 0, 0 };
4516
GdkRectangle configure_request;
4517
GdkGeometry new_geometry;
4519
gboolean was_realized;
4521
/* We are going to go ahead and perform this configure request
4522
* and then emulate a configure notify by going ahead and
4523
* doing a size allocate. Sort of a synchronous
4524
* mini-copy of gtk_window_move_resize() here.
4526
gtk_window_compute_configure_request (window,
4531
/* We update this because we are going to go ahead
4532
* and gdk_window_resize() below, rather than
4535
info->last.configure_request.width = configure_request.width;
4536
info->last.configure_request.height = configure_request.height;
4538
/* and allocate the window - this is normally done
4539
* in move_resize in response to configure notify
4541
allocation.width = configure_request.width;
4542
allocation.height = configure_request.height;
4543
gtk_widget_size_allocate (widget, &allocation);
4545
/* Then we guarantee we have a realize */
4546
was_realized = FALSE;
4547
if (!gtk_widget_get_realized (widget))
4549
gtk_widget_realize (widget);
4550
was_realized = TRUE;
4553
/* Must be done after the windows are realized,
4554
* so that the decorations can be read
4556
gtk_decorated_window_calculate_frame_size (window);
4558
/* We only send configure request if we didn't just finish
4559
* creating the window; if we just created the window
4560
* then we created it with widget->allocation anyhow.
4563
gdk_window_move_resize (widget->window,
4564
configure_request.x,
4565
configure_request.y,
4566
configure_request.width,
4567
configure_request.height);
4570
gtk_container_check_resize (container);
4572
gtk_widget_map (widget);
4574
/* Try to make sure that we have some focused widget
4576
if (!window->focus_widget && !GTK_IS_PLUG (window))
4577
gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4580
gtk_grab_add (widget);
4584
gtk_window_hide (GtkWidget *widget)
4586
GtkWindow *window = GTK_WINDOW (widget);
4588
GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4589
gtk_widget_unmap (widget);
4592
gtk_grab_remove (widget);
4596
gtk_window_map (GtkWidget *widget)
4598
GtkWindow *window = GTK_WINDOW (widget);
4599
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4600
GdkWindow *toplevel;
4601
gboolean auto_mnemonics;
4603
gtk_widget_set_mapped (widget, TRUE);
4605
if (window->bin.child &&
4606
gtk_widget_get_visible (window->bin.child) &&
4607
!gtk_widget_get_mapped (window->bin.child))
4608
gtk_widget_map (window->bin.child);
4611
toplevel = window->frame;
4613
toplevel = widget->window;
4615
if (window->maximize_initially)
4616
gdk_window_maximize (toplevel);
4618
gdk_window_unmaximize (toplevel);
4620
if (window->stick_initially)
4621
gdk_window_stick (toplevel);
4623
gdk_window_unstick (toplevel);
4625
if (window->iconify_initially)
4626
gdk_window_iconify (toplevel);
4628
gdk_window_deiconify (toplevel);
4630
if (priv->fullscreen_initially)
4631
gdk_window_fullscreen (toplevel);
4633
gdk_window_unfullscreen (toplevel);
4635
gdk_window_set_keep_above (toplevel, priv->above_initially);
4637
gdk_window_set_keep_below (toplevel, priv->below_initially);
4639
/* No longer use the default settings */
4640
window->need_default_size = FALSE;
4641
window->need_default_position = FALSE;
4643
if (priv->reset_type_hint)
4645
/* We should only reset the type hint when the application
4646
* used gtk_window_set_type_hint() to change the hint.
4647
* Some applications use X directly to change the properties;
4648
* in that case, we shouldn't overwrite what they did.
4650
gdk_window_set_type_hint (widget->window, priv->type_hint);
4651
priv->reset_type_hint = FALSE;
4654
gdk_window_show (widget->window);
4657
gdk_window_show (window->frame);
4659
if (!disable_startup_notification)
4661
/* Do we have a custom startup-notification id? */
4662
if (priv->startup_id != NULL)
4664
/* Make sure we have a "real" id */
4665
if (!startup_id_is_fake (priv->startup_id))
4666
gdk_notify_startup_complete_with_id (priv->startup_id);
4668
g_free (priv->startup_id);
4669
priv->startup_id = NULL;
4671
else if (!sent_startup_notification)
4673
sent_startup_notification = TRUE;
4674
gdk_notify_startup_complete ();
4678
/* if auto-mnemonics is enabled and mnemonics visible is not already set
4679
* (as in the case of popup menus), then hide mnemonics initially
4681
g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4682
&auto_mnemonics, NULL);
4683
if (auto_mnemonics && !priv->mnemonics_visible_set)
4684
gtk_window_set_mnemonics_visible (window, FALSE);
4688
gtk_window_map_event (GtkWidget *widget,
4691
if (!gtk_widget_get_mapped (widget))
4693
/* we should be be unmapped, but are getting a MapEvent, this may happen
4694
* to toplevel XWindows if mapping was intercepted by a window manager
4695
* and an unmap request occoured while the MapRequestEvent was still
4696
* being handled. we work around this situaiton here by re-requesting
4697
* the window being unmapped. more details can be found in:
4698
* http://bugzilla.gnome.org/show_bug.cgi?id=316180
4700
gdk_window_hide (widget->window);
4706
gtk_window_unmap (GtkWidget *widget)
4708
GtkWindow *window = GTK_WINDOW (widget);
4709
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4710
GtkWindowGeometryInfo *info;
4711
GdkWindowState state;
4713
gtk_widget_set_mapped (widget, FALSE);
4715
gdk_window_withdraw (window->frame);
4717
gdk_window_withdraw (widget->window);
4719
window->configure_request_count = 0;
4720
window->configure_notify_received = FALSE;
4722
/* on unmap, we reset the default positioning of the window,
4723
* so it's placed again, but we don't reset the default
4724
* size of the window, so it's remembered.
4726
window->need_default_position = TRUE;
4728
info = gtk_window_get_geometry_info (window, FALSE);
4731
info->initial_pos_set = FALSE;
4732
info->position_constraints_changed = FALSE;
4735
state = gdk_window_get_state (widget->window);
4736
window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4737
window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4738
window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4739
priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4740
priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4744
gtk_window_realize (GtkWidget *widget)
4747
GdkWindow *parent_window;
4748
GdkWindowAttr attributes;
4749
gint attributes_mask;
4750
GtkWindowPrivate *priv;
4752
window = GTK_WINDOW (widget);
4753
priv = GTK_WINDOW_GET_PRIVATE (window);
4755
/* ensure widget tree is properly size allocated */
4756
if (widget->allocation.x == -1 &&
4757
widget->allocation.y == -1 &&
4758
widget->allocation.width == 1 &&
4759
widget->allocation.height == 1)
4761
GtkRequisition requisition;
4762
GtkAllocation allocation = { 0, 0, 200, 200 };
4764
gtk_widget_size_request (widget, &requisition);
4765
if (requisition.width || requisition.height)
4767
/* non-empty window */
4768
allocation.width = requisition.width;
4769
allocation.height = requisition.height;
4771
gtk_widget_size_allocate (widget, &allocation);
4773
_gtk_container_queue_resize (GTK_CONTAINER (widget));
4775
g_return_if_fail (!gtk_widget_get_realized (widget));
4778
gtk_widget_set_realized (widget, TRUE);
4780
switch (window->type)
4782
case GTK_WINDOW_TOPLEVEL:
4783
attributes.window_type = GDK_WINDOW_TOPLEVEL;
4785
case GTK_WINDOW_POPUP:
4786
attributes.window_type = GDK_WINDOW_TEMP;
4789
g_warning (G_STRLOC": Unknown window type %d!", window->type);
4793
attributes.title = window->title;
4794
attributes.wmclass_name = window->wmclass_name;
4795
attributes.wmclass_class = window->wmclass_class;
4796
attributes.wclass = GDK_INPUT_OUTPUT;
4797
attributes.visual = gtk_widget_get_visual (widget);
4798
attributes.colormap = gtk_widget_get_colormap (widget);
4800
if (window->has_frame)
4802
attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4803
attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4804
attributes.event_mask = (GDK_EXPOSURE_MASK |
4805
GDK_KEY_PRESS_MASK |
4806
GDK_ENTER_NOTIFY_MASK |
4807
GDK_LEAVE_NOTIFY_MASK |
4808
GDK_FOCUS_CHANGE_MASK |
4809
GDK_STRUCTURE_MASK |
4810
GDK_BUTTON_MOTION_MASK |
4811
GDK_POINTER_MOTION_HINT_MASK |
4812
GDK_BUTTON_PRESS_MASK |
4813
GDK_BUTTON_RELEASE_MASK);
4815
attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4817
window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4818
&attributes, attributes_mask);
4820
if (priv->opacity_set)
4821
gdk_window_set_opacity (window->frame, priv->opacity);
4823
gdk_window_set_user_data (window->frame, widget);
4825
attributes.window_type = GDK_WINDOW_CHILD;
4826
attributes.x = window->frame_left;
4827
attributes.y = window->frame_top;
4829
attributes_mask = GDK_WA_X | GDK_WA_Y;
4831
parent_window = window->frame;
4833
g_signal_connect (window,
4835
G_CALLBACK (gtk_window_event),
4840
attributes_mask = 0;
4841
parent_window = gtk_widget_get_root_window (widget);
4844
attributes.width = widget->allocation.width;
4845
attributes.height = widget->allocation.height;
4846
attributes.event_mask = gtk_widget_get_events (widget);
4847
attributes.event_mask |= (GDK_EXPOSURE_MASK |
4848
GDK_KEY_PRESS_MASK |
4849
GDK_KEY_RELEASE_MASK |
4850
GDK_ENTER_NOTIFY_MASK |
4851
GDK_LEAVE_NOTIFY_MASK |
4852
GDK_FOCUS_CHANGE_MASK |
4853
GDK_STRUCTURE_MASK);
4854
attributes.type_hint = priv->type_hint;
4856
attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4857
attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4858
attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4860
widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4862
if (!window->has_frame && priv->opacity_set)
4863
gdk_window_set_opacity (widget->window, priv->opacity);
4865
gdk_window_enable_synchronized_configure (widget->window);
4867
gdk_window_set_user_data (widget->window, window);
4869
widget->style = gtk_style_attach (widget->style, widget->window);
4870
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4872
gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4874
/* This is a bad hack to set the window background. */
4875
gtk_window_paint (widget, NULL);
4877
if (window->transient_parent &&
4878
gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)))
4879
gdk_window_set_transient_for (widget->window,
4880
GTK_WIDGET (window->transient_parent)->window);
4882
if (window->wm_role)
4883
gdk_window_set_role (widget->window, window->wm_role);
4885
if (!window->decorated)
4886
gdk_window_set_decorations (widget->window, 0);
4888
if (!priv->deletable)
4889
gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4891
if (gtk_window_get_skip_pager_hint (window))
4892
gdk_window_set_skip_pager_hint (widget->window, TRUE);
4894
if (gtk_window_get_skip_taskbar_hint (window))
4895
gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4897
if (gtk_window_get_accept_focus (window))
4898
gdk_window_set_accept_focus (widget->window, TRUE);
4900
gdk_window_set_accept_focus (widget->window, FALSE);
4902
if (gtk_window_get_focus_on_map (window))
4903
gdk_window_set_focus_on_map (widget->window, TRUE);
4905
gdk_window_set_focus_on_map (widget->window, FALSE);
4908
gdk_window_set_modal_hint (widget->window, TRUE);
4910
gdk_window_set_modal_hint (widget->window, FALSE);
4912
if (priv->startup_id)
4914
#ifdef GDK_WINDOWING_X11
4915
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4916
if (timestamp != GDK_CURRENT_TIME)
4917
gdk_x11_window_set_user_time (widget->window, timestamp);
4919
if (!startup_id_is_fake (priv->startup_id))
4920
gdk_window_set_startup_id (widget->window, priv->startup_id);
4924
gtk_window_realize_icon (window);
4928
gtk_window_unrealize (GtkWidget *widget)
4931
GtkWindowGeometryInfo *info;
4933
window = GTK_WINDOW (widget);
4935
/* On unrealize, we reset the size of the window such
4936
* that we will re-apply the default sizing stuff
4937
* next time we show the window.
4939
* Default positioning is reset on unmap, instead of unrealize.
4941
window->need_default_size = TRUE;
4942
info = gtk_window_get_geometry_info (window, FALSE);
4945
info->resize_width = -1;
4946
info->resize_height = -1;
4947
info->last.configure_request.x = 0;
4948
info->last.configure_request.y = 0;
4949
info->last.configure_request.width = -1;
4950
info->last.configure_request.height = -1;
4951
/* be sure we reset geom hints on re-realize */
4952
info->last.flags = 0;
4957
gdk_window_set_user_data (window->frame, NULL);
4958
gdk_window_destroy (window->frame);
4959
window->frame = NULL;
4963
gtk_window_unrealize_icon (window);
4965
GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4969
gtk_window_size_request (GtkWidget *widget,
4970
GtkRequisition *requisition)
4975
window = GTK_WINDOW (widget);
4976
bin = GTK_BIN (window);
4978
requisition->width = GTK_CONTAINER (window)->border_width * 2;
4979
requisition->height = GTK_CONTAINER (window)->border_width * 2;
4981
if (bin->child && gtk_widget_get_visible (bin->child))
4983
GtkRequisition child_requisition;
4985
gtk_widget_size_request (bin->child, &child_requisition);
4987
requisition->width += child_requisition.width;
4988
requisition->height += child_requisition.height;
4993
gtk_window_size_allocate (GtkWidget *widget,
4994
GtkAllocation *allocation)
4997
GtkAllocation child_allocation;
4999
window = GTK_WINDOW (widget);
5000
widget->allocation = *allocation;
5002
if (window->bin.child && gtk_widget_get_visible (window->bin.child))
5004
child_allocation.x = GTK_CONTAINER (window)->border_width;
5005
child_allocation.y = GTK_CONTAINER (window)->border_width;
5006
child_allocation.width =
5007
MAX (1, (gint)allocation->width - child_allocation.x * 2);
5008
child_allocation.height =
5009
MAX (1, (gint)allocation->height - child_allocation.y * 2);
5011
gtk_widget_size_allocate (window->bin.child, &child_allocation);
5014
if (gtk_widget_get_realized (widget) && window->frame)
5016
gdk_window_resize (window->frame,
5017
allocation->width + window->frame_left + window->frame_right,
5018
allocation->height + window->frame_top + window->frame_bottom);
5023
gtk_window_event (GtkWidget *widget, GdkEvent *event)
5026
gboolean return_val;
5028
window = GTK_WINDOW (widget);
5030
if (window->frame && (event->any.window == window->frame))
5032
if ((event->type != GDK_KEY_PRESS) &&
5033
(event->type != GDK_KEY_RELEASE) &&
5034
(event->type != GDK_FOCUS_CHANGE))
5036
g_signal_stop_emission_by_name (widget, "event");
5038
g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5043
g_object_unref (event->any.window);
5044
event->any.window = g_object_ref (widget->window);
5052
gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5054
GdkEventConfigure *configure_event;
5057
switch (event->type)
5060
configure_event = (GdkEventConfigure *)event;
5062
/* Invalidate the decorations */
5065
rect.width = configure_event->width;
5066
rect.height = configure_event->height;
5068
gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5070
/* Pass on the (modified) configure event */
5071
configure_event->width -= window->frame_left + window->frame_right;
5072
configure_event->height -= window->frame_top + window->frame_bottom;
5073
return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5082
gtk_window_configure_event (GtkWidget *widget,
5083
GdkEventConfigure *event)
5085
GtkWindow *window = GTK_WINDOW (widget);
5086
gboolean expected_reply = window->configure_request_count > 0;
5088
/* window->configure_request_count incremented for each
5089
* configure request, and decremented to a min of 0 for
5090
* each configure notify.
5092
* All it means is that we know we will get at least
5093
* window->configure_request_count more configure notifies.
5094
* We could get more configure notifies than that; some
5095
* of the configure notifies we get may be unrelated to
5096
* the configure requests. But we will get at least
5097
* window->configure_request_count notifies.
5100
if (window->configure_request_count > 0)
5102
window->configure_request_count -= 1;
5103
gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5106
/* As an optimization, we avoid a resize when possible.
5108
* The only times we can avoid a resize are:
5109
* - we know only the position changed, not the size
5110
* - we know we have made more requests and so will get more
5111
* notifies and can wait to resize when we get them
5114
if (!expected_reply &&
5115
(widget->allocation.width == event->width &&
5116
widget->allocation.height == event->height))
5118
gdk_window_configure_finished (widget->window);
5123
* If we do need to resize, we do that by:
5124
* - filling in widget->allocation with the new size
5125
* - setting configure_notify_received to TRUE
5126
* for use in gtk_window_move_resize()
5127
* - queueing a resize, leading to invocation of
5128
* gtk_window_move_resize() in an idle handler
5132
window->configure_notify_received = TRUE;
5134
widget->allocation.width = event->width;
5135
widget->allocation.height = event->height;
5137
_gtk_container_queue_resize (GTK_CONTAINER (widget));
5142
/* the accel_key and accel_mods fields of the key have to be setup
5143
* upon calling this function. it'll then return whether that key
5144
* is at all used as accelerator, and if so will OR in the
5145
* accel_flags member of the key.
5148
_gtk_window_query_nonaccels (GtkWindow *window,
5150
GdkModifierType accel_mods)
5152
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5154
/* movement keys are considered locked accels */
5157
static const guint bindings[] = {
5158
GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5159
GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5163
for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5164
if (bindings[i] == accel_key)
5168
/* mnemonics are considered locked accels */
5169
if (accel_mods == window->mnemonic_modifier)
5171
GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5172
if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5180
* gtk_window_propagate_key_event:
5181
* @window: a #GtkWindow
5182
* @event: a #GdkEventKey
5184
* Propagate a key press or release event to the focus widget and
5185
* up the focus container chain until a widget handles @event.
5186
* This is normally called by the default ::key_press_event and
5187
* ::key_release_event handlers for toplevel windows,
5188
* however in some cases it may be useful to call this directly when
5189
* overriding the standard key handling for a toplevel window.
5191
* Return value: %TRUE if a widget in the focus chain handled the event.
5196
gtk_window_propagate_key_event (GtkWindow *window,
5199
gboolean handled = FALSE;
5200
GtkWidget *widget, *focus;
5202
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5204
widget = GTK_WIDGET (window);
5205
focus = window->focus_widget;
5207
g_object_ref (focus);
5210
focus && focus != widget &&
5211
gtk_widget_get_toplevel (focus) == widget)
5215
if (gtk_widget_is_sensitive (focus))
5216
handled = gtk_widget_event (focus, (GdkEvent*) event);
5218
parent = focus->parent;
5220
g_object_ref (parent);
5222
g_object_unref (focus);
5228
g_object_unref (focus);
5234
gtk_window_key_press_event (GtkWidget *widget,
5237
GtkWindow *window = GTK_WINDOW (widget);
5238
gboolean handled = FALSE;
5240
/* handle mnemonics and accelerators */
5242
handled = gtk_window_activate_key (window, event);
5244
/* handle focus widget key events */
5246
handled = gtk_window_propagate_key_event (window, event);
5248
/* Chain up, invokes binding set */
5250
handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5256
gtk_window_key_release_event (GtkWidget *widget,
5259
GtkWindow *window = GTK_WINDOW (widget);
5260
gboolean handled = FALSE;
5262
/* handle focus widget key events */
5264
handled = gtk_window_propagate_key_event (window, event);
5266
/* Chain up, invokes binding set */
5268
handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5274
gtk_window_real_activate_default (GtkWindow *window)
5276
gtk_window_activate_default (window);
5280
gtk_window_real_activate_focus (GtkWindow *window)
5282
gtk_window_activate_focus (window);
5286
gtk_window_move_focus (GtkWindow *window,
5287
GtkDirectionType dir)
5289
gtk_widget_child_focus (GTK_WIDGET (window), dir);
5291
if (!GTK_CONTAINER (window)->focus_child)
5292
gtk_window_set_focus (window, NULL);
5296
gtk_window_enter_notify_event (GtkWidget *widget,
5297
GdkEventCrossing *event)
5303
gtk_window_leave_notify_event (GtkWidget *widget,
5304
GdkEventCrossing *event)
5310
do_focus_change (GtkWidget *widget,
5313
GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5315
fevent->focus_change.type = GDK_FOCUS_CHANGE;
5316
fevent->focus_change.window = widget->window;
5317
fevent->focus_change.in = in;
5319
g_object_ref (widget->window);
5321
gtk_widget_send_focus_change (widget, fevent);
5323
gdk_event_free (fevent);
5327
gtk_window_focus_in_event (GtkWidget *widget,
5328
GdkEventFocus *event)
5330
GtkWindow *window = GTK_WINDOW (widget);
5332
/* It appears spurious focus in events can occur when
5333
* the window is hidden. So we'll just check to see if
5334
* the window is visible before actually handling the
5337
if (gtk_widget_get_visible (widget))
5339
_gtk_window_set_has_toplevel_focus (window, TRUE);
5340
_gtk_window_set_is_active (window, TRUE);
5347
gtk_window_focus_out_event (GtkWidget *widget,
5348
GdkEventFocus *event)
5350
GtkWindow *window = GTK_WINDOW (widget);
5351
gboolean auto_mnemonics;
5353
_gtk_window_set_has_toplevel_focus (window, FALSE);
5354
_gtk_window_set_is_active (window, FALSE);
5356
/* set the mnemonic-visible property to false */
5357
g_object_get (gtk_widget_get_settings (widget),
5358
"gtk-auto-mnemonics", &auto_mnemonics, NULL);
5360
gtk_window_set_mnemonics_visible (window, FALSE);
5365
static GdkAtom atom_rcfiles = GDK_NONE;
5366
static GdkAtom atom_iconthemes = GDK_NONE;
5369
send_client_message_to_embedded_windows (GtkWidget *widget,
5370
GdkAtom message_type)
5372
GList *embedded_windows;
5374
embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5375
if (embedded_windows)
5377
GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5380
for (i = 0; i < 5; i++)
5381
send_event->client.data.l[i] = 0;
5382
send_event->client.data_format = 32;
5383
send_event->client.message_type = message_type;
5385
while (embedded_windows)
5387
GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5388
gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5389
embedded_windows = embedded_windows->next;
5392
gdk_event_free (send_event);
5397
gtk_window_client_event (GtkWidget *widget,
5398
GdkEventClient *event)
5402
atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5403
atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5406
if (event->message_type == atom_rcfiles)
5408
send_client_message_to_embedded_windows (widget, atom_rcfiles);
5409
gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5412
if (event->message_type == atom_iconthemes)
5414
send_client_message_to_embedded_windows (widget, atom_iconthemes);
5415
_gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5422
gtk_window_check_resize (GtkContainer *container)
5424
if (gtk_widget_get_visible (GTK_WIDGET (container)))
5425
gtk_window_move_resize (GTK_WINDOW (container));
5429
gtk_window_focus (GtkWidget *widget,
5430
GtkDirectionType direction)
5434
GtkContainer *container;
5435
GtkWidget *old_focus_child;
5438
container = GTK_CONTAINER (widget);
5439
window = GTK_WINDOW (widget);
5440
bin = GTK_BIN (widget);
5442
old_focus_child = container->focus_child;
5444
/* We need a special implementation here to deal properly with wrapping
5445
* around in the tab chain without the danger of going into an
5448
if (old_focus_child)
5450
if (gtk_widget_child_focus (old_focus_child, direction))
5454
if (window->focus_widget)
5456
if (direction == GTK_DIR_LEFT ||
5457
direction == GTK_DIR_RIGHT ||
5458
direction == GTK_DIR_UP ||
5459
direction == GTK_DIR_DOWN)
5464
/* Wrapped off the end, clear the focus setting for the toplpevel */
5465
parent = window->focus_widget->parent;
5468
gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5469
parent = GTK_WIDGET (parent)->parent;
5472
gtk_window_set_focus (GTK_WINDOW (container), NULL);
5475
/* Now try to focus the first widget in the window */
5478
if (gtk_widget_child_focus (bin->child, direction))
5486
gtk_window_real_set_focus (GtkWindow *window,
5489
GtkWidget *old_focus = window->focus_widget;
5490
gboolean had_default = FALSE;
5491
gboolean focus_had_default = FALSE;
5492
gboolean old_focus_had_default = FALSE;
5496
g_object_ref (old_focus);
5497
g_object_freeze_notify (G_OBJECT (old_focus));
5498
old_focus_had_default = gtk_widget_has_default (old_focus);
5502
g_object_ref (focus);
5503
g_object_freeze_notify (G_OBJECT (focus));
5504
focus_had_default = gtk_widget_has_default (focus);
5507
if (window->default_widget)
5508
had_default = gtk_widget_has_default (window->default_widget);
5510
if (window->focus_widget)
5512
if (gtk_widget_get_receives_default (window->focus_widget) &&
5513
(window->focus_widget != window->default_widget))
5515
_gtk_widget_set_has_default (window->focus_widget, FALSE);
5516
gtk_widget_queue_draw (window->focus_widget);
5518
if (window->default_widget)
5519
_gtk_widget_set_has_default (window->default_widget, TRUE);
5522
window->focus_widget = NULL;
5524
if (window->has_focus)
5525
do_focus_change (old_focus, FALSE);
5527
g_object_notify (G_OBJECT (old_focus), "is-focus");
5530
/* The above notifications may have set a new focus widget,
5531
* if so, we don't want to override it.
5533
if (focus && !window->focus_widget)
5535
window->focus_widget = focus;
5537
if (gtk_widget_get_receives_default (window->focus_widget) &&
5538
(window->focus_widget != window->default_widget))
5540
if (gtk_widget_get_can_default (window->focus_widget))
5541
_gtk_widget_set_has_default (window->focus_widget, TRUE);
5543
if (window->default_widget)
5544
_gtk_widget_set_has_default (window->default_widget, FALSE);
5547
if (window->has_focus)
5548
do_focus_change (window->focus_widget, TRUE);
5550
g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5553
/* If the default widget changed, a redraw will have been queued
5554
* on the old and new default widgets by gtk_window_set_default(), so
5555
* we only have to worry about the case where it didn't change.
5556
* We'll sometimes queue a draw twice on the new widget but that
5559
if (window->default_widget &&
5560
(had_default != gtk_widget_has_default (window->default_widget)))
5561
gtk_widget_queue_draw (window->default_widget);
5565
if (old_focus_had_default != gtk_widget_has_default (old_focus))
5566
gtk_widget_queue_draw (old_focus);
5568
g_object_thaw_notify (G_OBJECT (old_focus));
5569
g_object_unref (old_focus);
5573
if (focus_had_default != gtk_widget_has_default (focus))
5574
gtk_widget_queue_draw (focus);
5576
g_object_thaw_notify (G_OBJECT (focus));
5577
g_object_unref (focus);
5582
* _gtk_window_unset_focus_and_default:
5583
* @window: a #GtkWindow
5584
* @widget: a widget inside of @window
5586
* Checks whether the focus and default widgets of @window are
5587
* @widget or a descendent of @widget, and if so, unset them.
5590
_gtk_window_unset_focus_and_default (GtkWindow *window,
5596
g_object_ref (window);
5597
g_object_ref (widget);
5599
if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5601
child = window->focus_widget;
5603
while (child && child != widget)
5604
child = child->parent;
5606
if (child == widget)
5607
gtk_window_set_focus (GTK_WINDOW (window), NULL);
5610
child = window->default_widget;
5612
while (child && child != widget)
5613
child = child->parent;
5615
if (child == widget)
5616
gtk_window_set_default (window, NULL);
5618
g_object_unref (widget);
5619
g_object_unref (window);
5622
/*********************************
5623
* Functions related to resizing *
5624
*********************************/
5626
/* This function doesn't constrain to geometry hints */
5628
gtk_window_compute_configure_request_size (GtkWindow *window,
5632
GtkRequisition requisition;
5633
GtkWindowGeometryInfo *info;
5637
* - we've done a size request
5640
widget = GTK_WIDGET (window);
5642
info = gtk_window_get_geometry_info (window, FALSE);
5644
if (window->need_default_size)
5646
gtk_widget_get_child_requisition (widget, &requisition);
5648
/* Default to requisition */
5649
*width = requisition.width;
5650
*height = requisition.height;
5652
/* If window is empty so requests 0, default to random nonzero size */
5653
if (*width == 0 && *height == 0)
5659
/* Override requisition with default size */
5663
gint base_width = 0;
5664
gint base_height = 0;
5666
gint min_height = 0;
5668
gint height_inc = 1;
5670
if (info->default_is_geometry &&
5671
(info->default_width > 0 || info->default_height > 0))
5673
GdkGeometry geometry;
5676
gtk_window_compute_hints (window, &geometry, &flags);
5678
if (flags & GDK_HINT_BASE_SIZE)
5680
base_width = geometry.base_width;
5681
base_height = geometry.base_height;
5683
if (flags & GDK_HINT_MIN_SIZE)
5685
min_width = geometry.min_width;
5686
min_height = geometry.min_height;
5688
if (flags & GDK_HINT_RESIZE_INC)
5690
width_inc = geometry.width_inc;
5691
height_inc = geometry.height_inc;
5695
if (info->default_width > 0)
5696
*width = MAX (info->default_width * width_inc + base_width, min_width);
5698
if (info->default_height > 0)
5699
*height = MAX (info->default_height * height_inc + base_height, min_height);
5704
/* Default to keeping current size */
5705
*width = widget->allocation.width;
5706
*height = widget->allocation.height;
5709
/* Override any size with gtk_window_resize() values */
5712
if (info->resize_width > 0)
5713
*width = info->resize_width;
5715
if (info->resize_height > 0)
5716
*height = info->resize_height;
5719
/* Don't ever request zero width or height, its not supported by
5720
gdk. The size allocation code will round it to 1 anyway but if
5721
we do it then the value returned from this function will is
5722
not comparable to the size allocation read from the GtkWindow. */
5723
*width = MAX (*width, 1);
5724
*height = MAX (*height, 1);
5727
static GtkWindowPosition
5728
get_effective_position (GtkWindow *window)
5730
GtkWindowPosition pos = window->position;
5732
if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5733
(window->transient_parent == NULL ||
5734
!gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5735
pos = GTK_WIN_POS_NONE;
5741
get_center_monitor_of_window (GtkWindow *window)
5743
/* We could try to sort out the relative positions of the monitors and
5744
* stuff, or we could just be losers and assume you have a row
5745
* or column of monitors.
5747
return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5751
get_monitor_containing_pointer (GtkWindow *window)
5755
GdkScreen *window_screen;
5756
GdkScreen *pointer_screen;
5758
window_screen = gtk_window_check_screen (window);
5759
gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5763
if (pointer_screen == window_screen)
5764
monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5772
center_window_on_monitor (GtkWindow *window,
5778
GdkRectangle monitor;
5781
monitor_num = get_monitor_containing_pointer (window);
5783
if (monitor_num == -1)
5784
monitor_num = get_center_monitor_of_window (window);
5786
gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5787
monitor_num, &monitor);
5789
*x = (monitor.width - w) / 2 + monitor.x;
5790
*y = (monitor.height - h) / 2 + monitor.y;
5792
/* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5793
* and WM decorations.
5807
if (extent > clamp_extent)
5809
*base = clamp_base + clamp_extent/2 - extent/2;
5810
else if (*base < clamp_base)
5812
else if (*base + extent > clamp_base + clamp_extent)
5813
*base = clamp_base + clamp_extent - extent;
5817
clamp_window_to_rectangle (gint *x,
5821
const GdkRectangle *rect)
5823
#ifdef DEBUGGING_OUTPUT
5824
g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", G_STRFUNC, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
5827
/* If it is too large, center it. If it fits on the monitor but is
5828
* partially outside, move it to the closest edge. Do this
5829
* separately in x and y directions.
5831
clamp (x, w, rect->x, rect->width);
5832
clamp (y, h, rect->y, rect->height);
5833
#ifdef DEBUGGING_OUTPUT
5834
g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5840
gtk_window_compute_configure_request (GtkWindow *window,
5841
GdkRectangle *request,
5842
GdkGeometry *geometry,
5845
GdkGeometry new_geometry;
5849
GtkWindowPosition pos;
5850
GtkWidget *parent_widget;
5851
GtkWindowGeometryInfo *info;
5855
widget = GTK_WIDGET (window);
5857
screen = gtk_window_check_screen (window);
5859
gtk_widget_size_request (widget, NULL);
5860
gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5862
gtk_window_compute_hints (window, &new_geometry, &new_flags);
5863
gtk_window_constrain_size (window,
5864
&new_geometry, new_flags,
5868
parent_widget = (GtkWidget*) window->transient_parent;
5870
pos = get_effective_position (window);
5871
info = gtk_window_get_geometry_info (window, FALSE);
5873
/* by default, don't change position requested */
5876
x = info->last.configure_request.x;
5877
y = info->last.configure_request.y;
5886
if (window->need_default_position)
5889
/* FIXME this all interrelates with window gravity.
5890
* For most of them I think we want to set GRAVITY_CENTER.
5892
* Not sure how to go about that.
5897
/* here we are only handling CENTER_ALWAYS
5898
* as it relates to default positioning,
5899
* where it's equivalent to simply CENTER
5901
case GTK_WIN_POS_CENTER_ALWAYS:
5902
case GTK_WIN_POS_CENTER:
5903
center_window_on_monitor (window, w, h, &x, &y);
5906
case GTK_WIN_POS_CENTER_ON_PARENT:
5909
GdkRectangle monitor;
5912
g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5914
if (parent_widget->window != NULL)
5915
monitor_num = gdk_screen_get_monitor_at_window (screen,
5916
parent_widget->window);
5920
gdk_window_get_origin (parent_widget->window,
5923
x = ox + (parent_widget->allocation.width - w) / 2;
5924
y = oy + (parent_widget->allocation.height - h) / 2;
5926
/* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5927
* WM decorations. If parent wasn't on a monitor, just
5930
if (monitor_num >= 0)
5932
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5933
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5938
case GTK_WIN_POS_MOUSE:
5940
gint screen_width = gdk_screen_get_width (screen);
5941
gint screen_height = gdk_screen_get_height (screen);
5943
GdkRectangle monitor;
5944
GdkScreen *pointer_screen;
5947
gdk_display_get_pointer (gdk_screen_get_display (screen),
5951
if (pointer_screen == screen)
5952
monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5958
x = CLAMP (x, 0, screen_width - w);
5959
y = CLAMP (y, 0, screen_height - h);
5961
/* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5962
* WM decorations. Don't try to figure out what's going
5963
* on if the mouse wasn't inside a monitor.
5965
if (monitor_num >= 0)
5967
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5968
clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5976
} /* if (window->need_default_position) */
5978
if (window->need_default_position && info &&
5979
info->initial_pos_set)
5981
x = info->initial_x;
5982
y = info->initial_y;
5983
gtk_window_constrain_position (window, w, h, &x, &y);
5989
request->height = h;
5992
*geometry = new_geometry;
5998
gtk_window_constrain_position (GtkWindow *window,
6004
/* See long comments in gtk_window_move_resize()
6005
* on when it's safe to call this function.
6007
if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
6009
gint center_x, center_y;
6011
center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6019
gtk_window_move_resize (GtkWindow *window)
6023
* First we determine whether any information has changed that would
6024
* cause us to revise our last configure request. If we would send
6025
* a different configure request from last time, then
6026
* configure_request_size_changed = TRUE or
6027
* configure_request_pos_changed = TRUE. configure_request_size_changed
6028
* may be true due to new hints, a gtk_window_resize(), or whatever.
6029
* configure_request_pos_changed may be true due to gtk_window_set_position()
6030
* or gtk_window_move().
6032
* If the configure request has changed, we send off a new one. To
6033
* ensure GTK+ invariants are maintained (resize queue does what it
6034
* should), we go ahead and size_allocate the requested size in this
6037
* If the configure request has not changed, we don't ever resend
6038
* it, because it could mean fighting the user or window manager.
6041
* To prepare the configure request, we come up with a base size/pos:
6042
* - the one from gtk_window_move()/gtk_window_resize()
6043
* - else default_width, default_height if we haven't ever
6045
* - else the size request if we haven't ever been mapped,
6046
* as a substitute default size
6047
* - else the current size of the window, as received from
6048
* configure notifies (i.e. the current allocation)
6050
* If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6051
* the position request to be centered.
6054
GtkContainer *container;
6055
GtkWindowGeometryInfo *info;
6056
GdkGeometry new_geometry;
6058
GdkRectangle new_request;
6059
gboolean configure_request_size_changed;
6060
gboolean configure_request_pos_changed;
6061
gboolean hints_changed; /* do we need to send these again */
6062
GtkWindowLastGeometryInfo saved_last_info;
6064
widget = GTK_WIDGET (window);
6065
container = GTK_CONTAINER (widget);
6066
info = gtk_window_get_geometry_info (window, TRUE);
6068
configure_request_size_changed = FALSE;
6069
configure_request_pos_changed = FALSE;
6071
gtk_window_compute_configure_request (window, &new_request,
6072
&new_geometry, &new_flags);
6074
/* This check implies the invariant that we never set info->last
6075
* without setting the hints and sending off a configure request.
6077
* If we change info->last without sending the request, we may
6080
if (info->last.configure_request.x != new_request.x ||
6081
info->last.configure_request.y != new_request.y)
6082
configure_request_pos_changed = TRUE;
6084
if ((info->last.configure_request.width != new_request.width ||
6085
info->last.configure_request.height != new_request.height))
6086
configure_request_size_changed = TRUE;
6088
hints_changed = FALSE;
6090
if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6091
&new_geometry, new_flags))
6093
hints_changed = TRUE;
6096
/* Position Constraints
6097
* ====================
6099
* POS_CENTER_ALWAYS is conceptually a constraint rather than
6100
* a default. The other POS_ values are used only when the
6101
* window is shown, not after that.
6103
* However, we can't implement a position constraint as
6104
* "anytime the window size changes, center the window"
6105
* because this may well end up fighting the WM or user. In
6106
* fact it gets in an infinite loop with at least one WM.
6108
* Basically, applications are in no way in a position to
6109
* constrain the position of a window, with one exception:
6110
* override redirect windows. (Really the intended purpose
6111
* of CENTER_ALWAYS anyhow, I would think.)
6113
* So the way we implement this "constraint" is to say that when WE
6114
* cause a move or resize, i.e. we make a configure request changing
6115
* window size, we recompute the CENTER_ALWAYS position to reflect
6116
* the new window size, and include it in our request. Also, if we
6117
* just turned on CENTER_ALWAYS we snap to center with a new
6118
* request. Otherwise, if we are just NOTIFIED of a move or resize
6119
* done by someone else e.g. the window manager, we do NOT send a
6120
* new configure request.
6122
* For override redirect windows, this works fine; all window
6123
* sizes are from our configure requests. For managed windows,
6124
* it is at least semi-sane, though who knows what the
6125
* app author is thinking.
6128
/* This condition should be kept in sync with the condition later on
6129
* that determines whether we send a configure request. i.e. we
6130
* should do this position constraining anytime we were going to
6131
* send a configure request anyhow, plus when constraints have
6134
if (configure_request_pos_changed ||
6135
configure_request_size_changed ||
6137
info->position_constraints_changed)
6139
/* We request the constrained position if:
6140
* - we were changing position, and need to clamp
6141
* the change to the constraint
6142
* - we're changing the size anyway
6143
* - set_position() was called to toggle CENTER_ALWAYS on
6146
gtk_window_constrain_position (window,
6152
/* Update whether we need to request a move */
6153
if (info->last.configure_request.x != new_request.x ||
6154
info->last.configure_request.y != new_request.y)
6155
configure_request_pos_changed = TRUE;
6157
configure_request_pos_changed = FALSE;
6161
if (window->type == GTK_WINDOW_TOPLEVEL)
6163
int notify_x, notify_y;
6165
/* this is the position from the last configure notify */
6166
gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6168
g_message ("--- %s ---\n"
6169
"last : %d,%d\t%d x %d\n"
6170
"this : %d,%d\t%d x %d\n"
6171
"alloc : %d,%d\t%d x %d\n"
6173
"resize: \t%d x %d\n"
6174
"size_changed: %d pos_changed: %d hints_changed: %d\n"
6175
"configure_notify_received: %d\n"
6176
"configure_request_count: %d\n"
6177
"position_constraints_changed: %d\n",
6178
window->title ? window->title : "(no title)",
6179
info->last.configure_request.x,
6180
info->last.configure_request.y,
6181
info->last.configure_request.width,
6182
info->last.configure_request.height,
6188
widget->allocation.width,
6189
widget->allocation.height,
6190
widget->requisition.width,
6191
widget->requisition.height,
6193
info->resize_height,
6194
configure_request_pos_changed,
6195
configure_request_size_changed,
6197
window->configure_notify_received,
6198
window->configure_request_count,
6199
info->position_constraints_changed);
6203
saved_last_info = info->last;
6204
info->last.geometry = new_geometry;
6205
info->last.flags = new_flags;
6206
info->last.configure_request = new_request;
6208
/* need to set PPosition so the WM will look at our position,
6209
* but we don't want to count PPosition coming and going as a hints
6210
* change for future iterations. So we saved info->last prior to
6214
/* Also, if the initial position was explicitly set, then we always
6215
* toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6219
/* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6220
* this is an initial map
6223
if ((configure_request_pos_changed ||
6224
info->initial_pos_set ||
6225
(window->need_default_position &&
6226
get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6227
(new_flags & GDK_HINT_POS) == 0)
6229
new_flags |= GDK_HINT_POS;
6230
hints_changed = TRUE;
6233
/* Set hints if necessary
6236
gdk_window_set_geometry_hints (widget->window,
6240
/* handle resizing/moving and widget tree allocation
6242
if (window->configure_notify_received)
6244
GtkAllocation allocation;
6246
/* If we have received a configure event since
6247
* the last time in this function, we need to
6248
* accept our new size and size_allocate child widgets.
6249
* (see gtk_window_configure_event() for more details).
6251
* 1 or more configure notifies may have been received.
6252
* Also, configure_notify_received will only be TRUE
6253
* if all expected configure notifies have been received
6254
* (one per configure request), as an optimization.
6257
window->configure_notify_received = FALSE;
6259
/* gtk_window_configure_event() filled in widget->allocation */
6260
allocation = widget->allocation;
6261
gtk_widget_size_allocate (widget, &allocation);
6263
gdk_window_process_updates (widget->window, TRUE);
6265
gdk_window_configure_finished (widget->window);
6267
/* If the configure request changed, it means that
6269
* 1) coincidentally changed hints or widget properties
6270
* impacting the configure request before getting
6271
* a configure notify, or
6272
* 2) some broken widget is changing its size request
6273
* during size allocation, resulting in
6274
* a false appearance of changed configure request.
6276
* For 1), we could just go ahead and ask for the
6277
* new size right now, but doing that for 2)
6278
* might well be fighting the user (and can even
6279
* trigger a loop). Since we really don't want to
6280
* do that, we requeue a resize in hopes that
6281
* by the time it gets handled, the child has seen
6282
* the light and is willing to go along with the
6283
* new size. (this happens for the zvt widget, since
6284
* the size_allocate() above will have stored the
6285
* requisition corresponding to the new size in the
6288
* This doesn't buy us anything for 1), but it shouldn't
6289
* hurt us too badly, since it is what would have
6290
* happened if we had gotten the configure event before
6291
* the new size had been set.
6294
if (configure_request_size_changed ||
6295
configure_request_pos_changed)
6297
/* Don't change the recorded last info after all, because we
6298
* haven't actually updated to the new info yet - we decided
6299
* to postpone our configure request until later.
6301
info->last = saved_last_info;
6303
gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6306
return; /* Bail out, we didn't really process the move/resize */
6308
else if ((configure_request_size_changed || hints_changed) &&
6309
(widget->allocation.width != new_request.width ||
6310
widget->allocation.height != new_request.height))
6313
/* We are in one of the following situations:
6314
* A. configure_request_size_changed
6315
* our requisition has changed and we need a different window size,
6316
* so we request it from the window manager.
6317
* B. !configure_request_size_changed && hints_changed
6318
* the window manager rejects our size, but we have just changed the
6319
* window manager hints, so there's a chance our request will
6320
* be honoured this time, so we try again.
6322
* However, if the new requisition is the same as the current allocation,
6323
* we don't request it again, since we won't get a ConfigureNotify back from
6324
* the window manager unless it decides to change our requisition. If
6325
* we don't get the ConfigureNotify back, the resize queue will never be run.
6328
/* Now send the configure request */
6329
if (configure_request_pos_changed)
6333
gdk_window_move_resize (window->frame,
6334
new_request.x - window->frame_left,
6335
new_request.y - window->frame_top,
6336
new_request.width + window->frame_left + window->frame_right,
6337
new_request.height + window->frame_top + window->frame_bottom);
6338
gdk_window_resize (widget->window,
6339
new_request.width, new_request.height);
6342
gdk_window_move_resize (widget->window,
6343
new_request.x, new_request.y,
6344
new_request.width, new_request.height);
6346
else /* only size changed */
6349
gdk_window_resize (window->frame,
6350
new_request.width + window->frame_left + window->frame_right,
6351
new_request.height + window->frame_top + window->frame_bottom);
6352
gdk_window_resize (widget->window,
6353
new_request.width, new_request.height);
6356
if (window->type == GTK_WINDOW_POPUP)
6358
GtkAllocation allocation;
6360
/* Directly size allocate for override redirect (popup) windows. */
6363
allocation.width = new_request.width;
6364
allocation.height = new_request.height;
6366
gtk_widget_size_allocate (widget, &allocation);
6368
gdk_window_process_updates (widget->window, TRUE);
6370
if (container->resize_mode == GTK_RESIZE_QUEUE)
6371
gtk_widget_queue_draw (widget);
6375
/* Increment the number of have-not-yet-received-notify requests */
6376
window->configure_request_count += 1;
6377
gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6379
/* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6380
* configure event in response to our resizing request.
6381
* the configure event will cause a new resize with
6382
* ->configure_notify_received=TRUE.
6383
* until then, we want to
6384
* - discard expose events
6385
* - coalesce resizes for our children
6386
* - defer any window resizes until the configure event arrived
6387
* to achieve this, we queue a resize for the window, but remove its
6388
* resizing handler, so resizing will not be handled from the next
6389
* idle handler but when the configure event arrives.
6391
* FIXME: we should also dequeue the pending redraws here, since
6392
* we handle those ourselves upon ->configure_notify_received==TRUE.
6394
if (container->resize_mode == GTK_RESIZE_QUEUE)
6396
gtk_widget_queue_resize_no_redraw (widget);
6397
_gtk_container_dequeue_resize_handler (container);
6403
/* Handle any position changes.
6405
if (configure_request_pos_changed)
6409
gdk_window_move (window->frame,
6410
new_request.x - window->frame_left,
6411
new_request.y - window->frame_top);
6414
gdk_window_move (widget->window,
6415
new_request.x, new_request.y);
6418
/* And run the resize queue.
6420
gtk_container_resize_children (container);
6423
/* We have now processed a move/resize since the last position
6424
* constraint change, setting of the initial position, or resize.
6425
* (Not resetting these flags here can lead to infinite loops for
6426
* GTK_RESIZE_IMMEDIATE containers)
6428
info->position_constraints_changed = FALSE;
6429
info->initial_pos_set = FALSE;
6430
info->resize_width = -1;
6431
info->resize_height = -1;
6434
/* Compare two sets of Geometry hints for equality.
6437
gtk_window_compare_hints (GdkGeometry *geometry_a,
6439
GdkGeometry *geometry_b,
6442
if (flags_a != flags_b)
6445
if ((flags_a & GDK_HINT_MIN_SIZE) &&
6446
(geometry_a->min_width != geometry_b->min_width ||
6447
geometry_a->min_height != geometry_b->min_height))
6450
if ((flags_a & GDK_HINT_MAX_SIZE) &&
6451
(geometry_a->max_width != geometry_b->max_width ||
6452
geometry_a->max_height != geometry_b->max_height))
6455
if ((flags_a & GDK_HINT_BASE_SIZE) &&
6456
(geometry_a->base_width != geometry_b->base_width ||
6457
geometry_a->base_height != geometry_b->base_height))
6460
if ((flags_a & GDK_HINT_ASPECT) &&
6461
(geometry_a->min_aspect != geometry_b->min_aspect ||
6462
geometry_a->max_aspect != geometry_b->max_aspect))
6465
if ((flags_a & GDK_HINT_RESIZE_INC) &&
6466
(geometry_a->width_inc != geometry_b->width_inc ||
6467
geometry_a->height_inc != geometry_b->height_inc))
6470
if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6471
geometry_a->win_gravity != geometry_b->win_gravity)
6478
_gtk_window_constrain_size (GtkWindow *window,
6484
GtkWindowGeometryInfo *info;
6486
g_return_if_fail (GTK_IS_WINDOW (window));
6488
info = window->geometry_info;
6491
GdkWindowHints flags = info->last.flags;
6492
GdkGeometry *geometry = &info->last.geometry;
6494
gtk_window_constrain_size (window,
6505
gtk_window_constrain_size (GtkWindow *window,
6506
GdkGeometry *geometry,
6513
gdk_window_constrain_size (geometry, flags, width, height,
6514
new_width, new_height);
6517
/* Compute the set of geometry hints and flags for a window
6518
* based on the application set geometry, and requisiition
6519
* of the window. gtk_widget_size_request() must have been
6523
gtk_window_compute_hints (GtkWindow *window,
6524
GdkGeometry *new_geometry,
6528
gint extra_width = 0;
6529
gint extra_height = 0;
6530
GtkWindowGeometryInfo *geometry_info;
6531
GtkRequisition requisition;
6533
widget = GTK_WIDGET (window);
6535
gtk_widget_get_child_requisition (widget, &requisition);
6536
geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6540
*new_flags = geometry_info->mask;
6541
*new_geometry = geometry_info->geometry;
6548
if (geometry_info && geometry_info->widget)
6550
GtkRequisition child_requisition;
6552
/* FIXME: This really isn't right. It gets the min size wrong and forces
6553
* callers to do horrible hacks like set a huge usize on the child requisition
6554
* to get the base size right. We really want to find the answers to:
6556
* - If the geometry widget was infinitely big, how much extra space
6557
* would be needed for the stuff around it.
6559
* - If the geometry widget was infinitely small, how big would the
6560
* window still have to be.
6562
* Finding these answers would be a bit of a mess here. (Bug #68668)
6564
gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6566
extra_width = widget->requisition.width - child_requisition.width;
6567
extra_height = widget->requisition.height - child_requisition.height;
6570
/* We don't want to set GDK_HINT_POS in here, we just set it
6571
* in gtk_window_move_resize() when we want the position
6575
if (*new_flags & GDK_HINT_BASE_SIZE)
6577
new_geometry->base_width += extra_width;
6578
new_geometry->base_height += extra_height;
6580
else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6581
(*new_flags & GDK_HINT_RESIZE_INC) &&
6582
((extra_width != 0) || (extra_height != 0)))
6584
*new_flags |= GDK_HINT_BASE_SIZE;
6586
new_geometry->base_width = extra_width;
6587
new_geometry->base_height = extra_height;
6590
if (*new_flags & GDK_HINT_MIN_SIZE)
6592
if (new_geometry->min_width < 0)
6593
new_geometry->min_width = requisition.width;
6595
new_geometry->min_width += extra_width;
6597
if (new_geometry->min_height < 0)
6598
new_geometry->min_height = requisition.height;
6600
new_geometry->min_height += extra_height;
6602
else if (!window->allow_shrink)
6604
*new_flags |= GDK_HINT_MIN_SIZE;
6606
new_geometry->min_width = requisition.width;
6607
new_geometry->min_height = requisition.height;
6610
if (*new_flags & GDK_HINT_MAX_SIZE)
6612
if (new_geometry->max_width < 0)
6613
new_geometry->max_width = requisition.width;
6615
new_geometry->max_width += extra_width;
6617
if (new_geometry->max_height < 0)
6618
new_geometry->max_height = requisition.height;
6620
new_geometry->max_height += extra_height;
6622
else if (!window->allow_grow)
6624
*new_flags |= GDK_HINT_MAX_SIZE;
6626
new_geometry->max_width = requisition.width;
6627
new_geometry->max_height = requisition.height;
6630
*new_flags |= GDK_HINT_WIN_GRAVITY;
6631
new_geometry->win_gravity = window->gravity;
6634
/***********************
6635
* Redrawing functions *
6636
***********************/
6639
gtk_window_paint (GtkWidget *widget,
6642
gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6643
GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6647
gtk_window_expose (GtkWidget *widget,
6648
GdkEventExpose *event)
6650
if (!gtk_widget_get_app_paintable (widget))
6651
gtk_window_paint (widget, &event->area);
6653
if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6654
return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6660
* gtk_window_set_has_frame:
6661
* @window: a #GtkWindow
6662
* @setting: a boolean
6664
* (Note: this is a special-purpose function for the framebuffer port,
6665
* that causes GTK+ to draw its own window border. For most applications,
6666
* you want gtk_window_set_decorated() instead, which tells the window
6667
* manager whether to draw the window border.)
6669
* If this function is called on a window with setting of %TRUE, before
6670
* it is realized or showed, it will have a "frame" window around
6671
* @window->window, accessible in @window->frame. Using the signal
6672
* frame_event you can receive all events targeted at the frame.
6674
* This function is used by the linux-fb port to implement managed
6675
* windows, but it could conceivably be used by X-programs that
6676
* want to do their own window decorations.
6678
* Deprecated: 2.24: This function will be removed in GTK+ 3
6681
gtk_window_set_has_frame (GtkWindow *window,
6684
g_return_if_fail (GTK_IS_WINDOW (window));
6685
g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6687
window->has_frame = setting != FALSE;
6691
* gtk_window_get_has_frame:
6692
* @window: a #GtkWindow
6694
* Accessor for whether the window has a frame window exterior to
6695
* @window->window. Gets the value set by gtk_window_set_has_frame ().
6697
* Return value: %TRUE if a frame has been added to the window
6698
* via gtk_window_set_has_frame().
6700
* Deprecated: 2.24: This function will be removed in GTK+ 3
6703
gtk_window_get_has_frame (GtkWindow *window)
6705
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6707
return window->has_frame;
6711
* gtk_window_set_frame_dimensions:
6712
* @window: a #GtkWindow that has a frame
6713
* @left: The width of the left border
6714
* @top: The height of the top border
6715
* @right: The width of the right border
6716
* @bottom: The height of the bottom border
6718
* (Note: this is a special-purpose function intended for the framebuffer
6719
* port; see gtk_window_set_has_frame(). It will have no effect on the
6720
* window border drawn by the window manager, which is the normal
6721
* case when using the X Window system.)
6723
* For windows with frames (see gtk_window_set_has_frame()) this function
6724
* can be used to change the size of the frame border.
6726
* Deprecated: 2.24: This function will be removed in GTK+ 3
6729
gtk_window_set_frame_dimensions (GtkWindow *window,
6737
g_return_if_fail (GTK_IS_WINDOW (window));
6739
widget = GTK_WIDGET (window);
6741
if (window->frame_left == left &&
6742
window->frame_top == top &&
6743
window->frame_right == right &&
6744
window->frame_bottom == bottom)
6747
window->frame_left = left;
6748
window->frame_top = top;
6749
window->frame_right = right;
6750
window->frame_bottom = bottom;
6752
if (gtk_widget_get_realized (widget) && window->frame)
6754
gint width = widget->allocation.width + left + right;
6755
gint height = widget->allocation.height + top + bottom;
6756
gdk_window_resize (window->frame, width, height);
6757
gtk_decorated_window_move_resize_window (window,
6759
widget->allocation.width,
6760
widget->allocation.height);
6765
* gtk_window_present:
6766
* @window: a #GtkWindow
6768
* Presents a window to the user. This may mean raising the window
6769
* in the stacking order, deiconifying it, moving it to the current
6770
* desktop, and/or giving it the keyboard focus, possibly dependent
6771
* on the user's platform, window manager, and preferences.
6773
* If @window is hidden, this function calls gtk_widget_show()
6776
* This function should be used when the user tries to open a window
6777
* that's already open. Say for example the preferences dialog is
6778
* currently open, and the user chooses Preferences from the menu
6779
* a second time; use gtk_window_present() to move the already-open dialog
6780
* where the user can see it.
6782
* If you are calling this function in response to a user interaction,
6783
* it is preferable to use gtk_window_present_with_time().
6787
gtk_window_present (GtkWindow *window)
6789
gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6793
* gtk_window_present_with_time:
6794
* @window: a #GtkWindow
6795
* @timestamp: the timestamp of the user interaction (typically a
6796
* button or key press event) which triggered this call
6798
* Presents a window to the user in response to a user interaction.
6799
* If you need to present a window without a timestamp, use
6800
* gtk_window_present(). See gtk_window_present() for details.
6805
gtk_window_present_with_time (GtkWindow *window,
6810
g_return_if_fail (GTK_IS_WINDOW (window));
6812
widget = GTK_WIDGET (window);
6814
if (gtk_widget_get_visible (widget))
6816
g_assert (widget->window != NULL);
6818
gdk_window_show (widget->window);
6820
/* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6821
if (timestamp == GDK_CURRENT_TIME)
6823
#ifdef GDK_WINDOWING_X11
6824
GdkDisplay *display;
6826
display = gtk_widget_get_display (GTK_WIDGET (window));
6827
timestamp = gdk_x11_display_get_user_time (display);
6829
timestamp = gtk_get_current_event_time ();
6833
gdk_window_focus (widget->window, timestamp);
6837
gtk_widget_show (widget);
6842
* gtk_window_iconify:
6843
* @window: a #GtkWindow
6845
* Asks to iconify (i.e. minimize) the specified @window. Note that
6846
* you shouldn't assume the window is definitely iconified afterward,
6847
* because other entities (e.g. the user or <link
6848
* linkend="gtk-X11-arch">window manager</link>) could deiconify it
6849
* again, or there may not be a window manager in which case
6850
* iconification isn't possible, etc. But normally the window will end
6851
* up iconified. Just don't write code that crashes if not.
6853
* It's permitted to call this function before showing a window,
6854
* in which case the window will be iconified before it ever appears
6857
* You can track iconification via the "window-state-event" signal
6862
gtk_window_iconify (GtkWindow *window)
6865
GdkWindow *toplevel;
6867
g_return_if_fail (GTK_IS_WINDOW (window));
6869
widget = GTK_WIDGET (window);
6871
window->iconify_initially = TRUE;
6874
toplevel = window->frame;
6876
toplevel = widget->window;
6878
if (toplevel != NULL)
6879
gdk_window_iconify (toplevel);
6883
* gtk_window_deiconify:
6884
* @window: a #GtkWindow
6886
* Asks to deiconify (i.e. unminimize) the specified @window. Note
6887
* that you shouldn't assume the window is definitely deiconified
6888
* afterward, because other entities (e.g. the user or <link
6889
* linkend="gtk-X11-arch">window manager</link>) could iconify it
6890
* again before your code which assumes deiconification gets to run.
6892
* You can track iconification via the "window-state-event" signal
6896
gtk_window_deiconify (GtkWindow *window)
6899
GdkWindow *toplevel;
6901
g_return_if_fail (GTK_IS_WINDOW (window));
6903
widget = GTK_WIDGET (window);
6905
window->iconify_initially = FALSE;
6908
toplevel = window->frame;
6910
toplevel = widget->window;
6912
if (toplevel != NULL)
6913
gdk_window_deiconify (toplevel);
6918
* @window: a #GtkWindow
6920
* Asks to stick @window, which means that it will appear on all user
6921
* desktops. Note that you shouldn't assume the window is definitely
6922
* stuck afterward, because other entities (e.g. the user or <link
6923
* linkend="gtk-X11-arch">window manager</link>) could unstick it
6924
* again, and some window managers do not support sticking
6925
* windows. But normally the window will end up stuck. Just don't
6926
* write code that crashes if not.
6928
* It's permitted to call this function before showing a window.
6930
* You can track stickiness via the "window-state-event" signal
6935
gtk_window_stick (GtkWindow *window)
6938
GdkWindow *toplevel;
6940
g_return_if_fail (GTK_IS_WINDOW (window));
6942
widget = GTK_WIDGET (window);
6944
window->stick_initially = TRUE;
6947
toplevel = window->frame;
6949
toplevel = widget->window;
6951
if (toplevel != NULL)
6952
gdk_window_stick (toplevel);
6956
* gtk_window_unstick:
6957
* @window: a #GtkWindow
6959
* Asks to unstick @window, which means that it will appear on only
6960
* one of the user's desktops. Note that you shouldn't assume the
6961
* window is definitely unstuck afterward, because other entities
6962
* (e.g. the user or <link linkend="gtk-X11-arch">window
6963
* manager</link>) could stick it again. But normally the window will
6964
* end up stuck. Just don't write code that crashes if not.
6966
* You can track stickiness via the "window-state-event" signal
6971
gtk_window_unstick (GtkWindow *window)
6974
GdkWindow *toplevel;
6976
g_return_if_fail (GTK_IS_WINDOW (window));
6978
widget = GTK_WIDGET (window);
6980
window->stick_initially = FALSE;
6983
toplevel = window->frame;
6985
toplevel = widget->window;
6987
if (toplevel != NULL)
6988
gdk_window_unstick (toplevel);
6992
* gtk_window_maximize:
6993
* @window: a #GtkWindow
6995
* Asks to maximize @window, so that it becomes full-screen. Note that
6996
* you shouldn't assume the window is definitely maximized afterward,
6997
* because other entities (e.g. the user or <link
6998
* linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6999
* again, and not all window managers support maximization. But
7000
* normally the window will end up maximized. Just don't write code
7001
* that crashes if not.
7003
* It's permitted to call this function before showing a window,
7004
* in which case the window will be maximized when it appears onscreen
7007
* You can track maximization via the "window-state-event" signal
7012
gtk_window_maximize (GtkWindow *window)
7015
GdkWindow *toplevel;
7017
g_return_if_fail (GTK_IS_WINDOW (window));
7019
widget = GTK_WIDGET (window);
7021
window->maximize_initially = TRUE;
7024
toplevel = window->frame;
7026
toplevel = widget->window;
7028
if (toplevel != NULL)
7029
gdk_window_maximize (toplevel);
7033
* gtk_window_unmaximize:
7034
* @window: a #GtkWindow
7036
* Asks to unmaximize @window. Note that you shouldn't assume the
7037
* window is definitely unmaximized afterward, because other entities
7038
* (e.g. the user or <link linkend="gtk-X11-arch">window
7039
* manager</link>) could maximize it again, and not all window
7040
* managers honor requests to unmaximize. But normally the window will
7041
* end up unmaximized. Just don't write code that crashes if not.
7043
* You can track maximization via the "window-state-event" signal
7048
gtk_window_unmaximize (GtkWindow *window)
7051
GdkWindow *toplevel;
7053
g_return_if_fail (GTK_IS_WINDOW (window));
7055
widget = GTK_WIDGET (window);
7057
window->maximize_initially = FALSE;
7060
toplevel = window->frame;
7062
toplevel = widget->window;
7064
if (toplevel != NULL)
7065
gdk_window_unmaximize (toplevel);
7069
* gtk_window_fullscreen:
7070
* @window: a #GtkWindow
7072
* Asks to place @window in the fullscreen state. Note that you
7073
* shouldn't assume the window is definitely full screen afterward,
7074
* because other entities (e.g. the user or <link
7075
* linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7076
* again, and not all window managers honor requests to fullscreen
7077
* windows. But normally the window will end up fullscreen. Just
7078
* don't write code that crashes if not.
7080
* You can track the fullscreen state via the "window-state-event" signal
7086
gtk_window_fullscreen (GtkWindow *window)
7089
GdkWindow *toplevel;
7090
GtkWindowPrivate *priv;
7092
g_return_if_fail (GTK_IS_WINDOW (window));
7094
widget = GTK_WIDGET (window);
7095
priv = GTK_WINDOW_GET_PRIVATE (window);
7097
priv->fullscreen_initially = TRUE;
7100
toplevel = window->frame;
7102
toplevel = widget->window;
7104
if (toplevel != NULL)
7105
gdk_window_fullscreen (toplevel);
7109
* gtk_window_unfullscreen:
7110
* @window: a #GtkWindow
7112
* Asks to toggle off the fullscreen state for @window. Note that you
7113
* shouldn't assume the window is definitely not full screen
7114
* afterward, because other entities (e.g. the user or <link
7115
* linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7116
* again, and not all window managers honor requests to unfullscreen
7117
* windows. But normally the window will end up restored to its normal
7118
* state. Just don't write code that crashes if not.
7120
* You can track the fullscreen state via the "window-state-event" signal
7126
gtk_window_unfullscreen (GtkWindow *window)
7129
GdkWindow *toplevel;
7130
GtkWindowPrivate *priv;
7132
g_return_if_fail (GTK_IS_WINDOW (window));
7134
widget = GTK_WIDGET (window);
7135
priv = GTK_WINDOW_GET_PRIVATE (window);
7137
priv->fullscreen_initially = FALSE;
7140
toplevel = window->frame;
7142
toplevel = widget->window;
7144
if (toplevel != NULL)
7145
gdk_window_unfullscreen (toplevel);
7149
* gtk_window_set_keep_above:
7150
* @window: a #GtkWindow
7151
* @setting: whether to keep @window above other windows
7153
* Asks to keep @window above, so that it stays on top. Note that
7154
* you shouldn't assume the window is definitely above afterward,
7155
* because other entities (e.g. the user or <link
7156
* linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7157
* and not all window managers support keeping windows above. But
7158
* normally the window will end kept above. Just don't write code
7159
* that crashes if not.
7161
* It's permitted to call this function before showing a window,
7162
* in which case the window will be kept above when it appears onscreen
7165
* You can track the above state via the "window-state-event" signal
7168
* Note that, according to the <ulink
7169
* url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7170
* Manager Hints</ulink> specification, the above state is mainly meant
7171
* for user preferences and should not be used by applications e.g. for
7172
* drawing attention to their dialogs.
7177
gtk_window_set_keep_above (GtkWindow *window,
7181
GtkWindowPrivate *priv;
7182
GdkWindow *toplevel;
7184
g_return_if_fail (GTK_IS_WINDOW (window));
7186
widget = GTK_WIDGET (window);
7187
priv = GTK_WINDOW_GET_PRIVATE (window);
7189
priv->above_initially = setting != FALSE;
7191
priv->below_initially = FALSE;
7194
toplevel = window->frame;
7196
toplevel = widget->window;
7198
if (toplevel != NULL)
7199
gdk_window_set_keep_above (toplevel, setting);
7203
* gtk_window_set_keep_below:
7204
* @window: a #GtkWindow
7205
* @setting: whether to keep @window below other windows
7207
* Asks to keep @window below, so that it stays in bottom. Note that
7208
* you shouldn't assume the window is definitely below afterward,
7209
* because other entities (e.g. the user or <link
7210
* linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7211
* and not all window managers support putting windows below. But
7212
* normally the window will be kept below. Just don't write code
7213
* that crashes if not.
7215
* It's permitted to call this function before showing a window,
7216
* in which case the window will be kept below when it appears onscreen
7219
* You can track the below state via the "window-state-event" signal
7222
* Note that, according to the <ulink
7223
* url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7224
* Manager Hints</ulink> specification, the above state is mainly meant
7225
* for user preferences and should not be used by applications e.g. for
7226
* drawing attention to their dialogs.
7231
gtk_window_set_keep_below (GtkWindow *window,
7235
GtkWindowPrivate *priv;
7236
GdkWindow *toplevel;
7238
g_return_if_fail (GTK_IS_WINDOW (window));
7240
widget = GTK_WIDGET (window);
7241
priv = GTK_WINDOW_GET_PRIVATE (window);
7243
priv->below_initially = setting != FALSE;
7245
priv->above_initially = FALSE;
7248
toplevel = window->frame;
7250
toplevel = widget->window;
7252
if (toplevel != NULL)
7253
gdk_window_set_keep_below (toplevel, setting);
7257
* gtk_window_set_resizable:
7258
* @window: a #GtkWindow
7259
* @resizable: %TRUE if the user can resize this window
7261
* Sets whether the user can resize a window. Windows are user resizable
7265
gtk_window_set_resizable (GtkWindow *window,
7268
g_return_if_fail (GTK_IS_WINDOW (window));
7270
gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7274
* gtk_window_get_resizable:
7275
* @window: a #GtkWindow
7277
* Gets the value set by gtk_window_set_resizable().
7279
* Return value: %TRUE if the user can resize the window
7282
gtk_window_get_resizable (GtkWindow *window)
7284
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7286
/* allow_grow is most likely to indicate the semantic concept we
7287
* mean by "resizable" (and will be a reliable indicator if
7288
* set_policy() hasn't been called)
7290
return window->allow_grow;
7294
* gtk_window_set_gravity:
7295
* @window: a #GtkWindow
7296
* @gravity: window gravity
7298
* Window gravity defines the meaning of coordinates passed to
7299
* gtk_window_move(). See gtk_window_move() and #GdkGravity for
7302
* The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7303
* typically "do what you mean."
7307
gtk_window_set_gravity (GtkWindow *window,
7310
g_return_if_fail (GTK_IS_WINDOW (window));
7312
if (gravity != window->gravity)
7314
window->gravity = gravity;
7316
/* gtk_window_move_resize() will adapt gravity
7318
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7320
g_object_notify (G_OBJECT (window), "gravity");
7325
* gtk_window_get_gravity:
7326
* @window: a #GtkWindow
7328
* Gets the value set by gtk_window_set_gravity().
7330
* Return value: (transfer none): window gravity
7333
gtk_window_get_gravity (GtkWindow *window)
7335
g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7337
return window->gravity;
7341
* gtk_window_begin_resize_drag:
7342
* @window: a #GtkWindow
7343
* @button: mouse button that initiated the drag
7344
* @edge: position of the resize control
7345
* @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7346
* @root_y: Y position where the user clicked to initiate the drag
7347
* @timestamp: timestamp from the click event that initiated the drag
7349
* Starts resizing a window. This function is used if an application
7350
* has window resizing controls. When GDK can support it, the resize
7351
* will be done using the standard mechanism for the <link
7352
* linkend="gtk-X11-arch">window manager</link> or windowing
7353
* system. Otherwise, GDK will try to emulate window resizing,
7354
* potentially not all that well, depending on the windowing system.
7358
gtk_window_begin_resize_drag (GtkWindow *window,
7366
GdkWindow *toplevel;
7368
g_return_if_fail (GTK_IS_WINDOW (window));
7369
widget = GTK_WIDGET (window);
7370
g_return_if_fail (gtk_widget_get_visible (widget));
7373
toplevel = window->frame;
7375
toplevel = widget->window;
7377
gdk_window_begin_resize_drag (toplevel,
7384
* gtk_window_get_frame_dimensions:
7385
* @window: a #GtkWindow
7386
* @left: (out) (allow-none): location to store the width of the frame at the left, or %NULL
7387
* @top: (out) (allow-none): location to store the height of the frame at the top, or %NULL
7388
* @right: (out) (allow-none): location to store the width of the frame at the returns, or %NULL
7389
* @bottom: (out) (allow-none): location to store the height of the frame at the bottom, or %NULL
7391
* (Note: this is a special-purpose function intended for the
7392
* framebuffer port; see gtk_window_set_has_frame(). It will not
7393
* return the size of the window border drawn by the <link
7394
* linkend="gtk-X11-arch">window manager</link>, which is the normal
7395
* case when using a windowing system. See
7396
* gdk_window_get_frame_extents() to get the standard window border
7399
* Retrieves the dimensions of the frame window for this toplevel.
7400
* See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7402
* Deprecated: 2.24: This function will be removed in GTK+ 3
7405
gtk_window_get_frame_dimensions (GtkWindow *window,
7411
g_return_if_fail (GTK_IS_WINDOW (window));
7414
*left = window->frame_left;
7416
*top = window->frame_top;
7418
*right = window->frame_right;
7420
*bottom = window->frame_bottom;
7424
* gtk_window_begin_move_drag:
7425
* @window: a #GtkWindow
7426
* @button: mouse button that initiated the drag
7427
* @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7428
* @root_y: Y position where the user clicked to initiate the drag
7429
* @timestamp: timestamp from the click event that initiated the drag
7431
* Starts moving a window. This function is used if an application has
7432
* window movement grips. When GDK can support it, the window movement
7433
* will be done using the standard mechanism for the <link
7434
* linkend="gtk-X11-arch">window manager</link> or windowing
7435
* system. Otherwise, GDK will try to emulate window movement,
7436
* potentially not all that well, depending on the windowing system.
7440
gtk_window_begin_move_drag (GtkWindow *window,
7447
GdkWindow *toplevel;
7449
g_return_if_fail (GTK_IS_WINDOW (window));
7450
widget = GTK_WIDGET (window);
7451
g_return_if_fail (gtk_widget_get_visible (widget));
7454
toplevel = window->frame;
7456
toplevel = widget->window;
7458
gdk_window_begin_move_drag (toplevel,
7465
* gtk_window_set_screen:
7466
* @window: a #GtkWindow.
7467
* @screen: a #GdkScreen.
7469
* Sets the #GdkScreen where the @window is displayed; if
7470
* the window is already mapped, it will be unmapped, and
7471
* then remapped on the new screen.
7476
gtk_window_set_screen (GtkWindow *window,
7480
GdkScreen *previous_screen;
7481
gboolean was_mapped;
7483
g_return_if_fail (GTK_IS_WINDOW (window));
7484
g_return_if_fail (GDK_IS_SCREEN (screen));
7486
if (screen == window->screen)
7489
widget = GTK_WIDGET (window);
7491
previous_screen = window->screen;
7492
was_mapped = gtk_widget_get_mapped (widget);
7495
gtk_widget_unmap (widget);
7496
if (gtk_widget_get_realized (widget))
7497
gtk_widget_unrealize (widget);
7499
gtk_window_free_key_hash (window);
7500
window->screen = screen;
7501
gtk_widget_reset_rc_styles (widget);
7502
if (screen != previous_screen)
7504
g_signal_handlers_disconnect_by_func (previous_screen,
7505
gtk_window_on_composited_changed, window);
7506
g_signal_connect (screen, "composited-changed",
7507
G_CALLBACK (gtk_window_on_composited_changed), window);
7509
_gtk_widget_propagate_screen_changed (widget, previous_screen);
7510
_gtk_widget_propagate_composited_changed (widget);
7512
g_object_notify (G_OBJECT (window), "screen");
7515
gtk_widget_map (widget);
7519
gtk_window_on_composited_changed (GdkScreen *screen,
7522
gtk_widget_queue_draw (GTK_WIDGET (window));
7524
_gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7528
gtk_window_check_screen (GtkWindow *window)
7531
return window->screen;
7534
g_warning ("Screen for GtkWindow not set; you must always set\n"
7535
"a screen for a GtkWindow before using the window");
7541
* gtk_window_get_screen:
7542
* @window: a #GtkWindow.
7544
* Returns the #GdkScreen associated with @window.
7546
* Return value: (transfer none): a #GdkScreen.
7551
gtk_window_get_screen (GtkWindow *window)
7553
g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7555
return window->screen;
7559
* gtk_window_is_active:
7560
* @window: a #GtkWindow
7562
* Returns whether the window is part of the current active toplevel.
7563
* (That is, the toplevel window receiving keystrokes.)
7564
* The return value is %TRUE if the window is active toplevel
7565
* itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7566
* You might use this function if you wanted to draw a widget
7567
* differently in an active window from a widget in an inactive window.
7568
* See gtk_window_has_toplevel_focus()
7570
* Return value: %TRUE if the window part of the current active window.
7575
gtk_window_is_active (GtkWindow *window)
7577
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7579
return window->is_active;
7583
* gtk_window_has_toplevel_focus:
7584
* @window: a #GtkWindow
7586
* Returns whether the input focus is within this GtkWindow.
7587
* For real toplevel windows, this is identical to gtk_window_is_active(),
7588
* but for embedded windows, like #GtkPlug, the results will differ.
7590
* Return value: %TRUE if the input focus is within this GtkWindow
7595
gtk_window_has_toplevel_focus (GtkWindow *window)
7597
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7599
return window->has_toplevel_focus;
7603
gtk_window_group_class_init (GtkWindowGroupClass *klass)
7608
gtk_window_group_get_type (void)
7610
static GType window_group_type = 0;
7612
if (!window_group_type)
7614
const GTypeInfo window_group_info =
7616
sizeof (GtkWindowGroupClass),
7617
NULL, /* base_init */
7618
NULL, /* base_finalize */
7619
(GClassInitFunc) gtk_window_group_class_init,
7620
NULL, /* class_finalize */
7621
NULL, /* class_data */
7622
sizeof (GtkWindowGroup),
7623
0, /* n_preallocs */
7624
(GInstanceInitFunc) NULL,
7627
window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7628
&window_group_info, 0);
7631
return window_group_type;
7635
* gtk_window_group_new:
7637
* Creates a new #GtkWindowGroup object. Grabs added with
7638
* gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7640
* Return value: a new #GtkWindowGroup.
7643
gtk_window_group_new (void)
7645
return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7649
window_group_cleanup_grabs (GtkWindowGroup *group,
7653
GSList *to_remove = NULL;
7655
tmp_list = group->grabs;
7658
if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7659
to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7660
tmp_list = tmp_list->next;
7665
gtk_grab_remove (to_remove->data);
7666
g_object_unref (to_remove->data);
7667
to_remove = g_slist_delete_link (to_remove, to_remove);
7672
* gtk_window_group_add_window:
7673
* @window_group: a #GtkWindowGroup
7674
* @window: the #GtkWindow to add
7676
* Adds a window to a #GtkWindowGroup.
7679
gtk_window_group_add_window (GtkWindowGroup *window_group,
7682
g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7683
g_return_if_fail (GTK_IS_WINDOW (window));
7685
if (window->group != window_group)
7687
g_object_ref (window);
7688
g_object_ref (window_group);
7691
gtk_window_group_remove_window (window->group, window);
7693
window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7695
window->group = window_group;
7697
g_object_unref (window);
7702
* gtk_window_group_remove_window:
7703
* @window_group: a #GtkWindowGroup
7704
* @window: the #GtkWindow to remove
7706
* Removes a window from a #GtkWindowGroup.
7709
gtk_window_group_remove_window (GtkWindowGroup *window_group,
7712
g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7713
g_return_if_fail (GTK_IS_WINDOW (window));
7714
g_return_if_fail (window->group == window_group);
7716
g_object_ref (window);
7718
window_group_cleanup_grabs (window_group, window);
7719
window->group = NULL;
7721
g_object_unref (window_group);
7722
g_object_unref (window);
7726
* gtk_window_group_list_windows:
7727
* @window_group: a #GtkWindowGroup
7729
* Returns a list of the #GtkWindows that belong to @window_group.
7731
* Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7732
* windows inside the group.
7737
gtk_window_group_list_windows (GtkWindowGroup *window_group)
7739
GList *toplevels, *toplevel, *group_windows;
7741
g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7743
group_windows = NULL;
7744
toplevels = gtk_window_list_toplevels ();
7746
for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7748
GtkWindow *window = toplevel->data;
7750
if (window_group == window->group)
7751
group_windows = g_list_prepend (group_windows, window);
7754
return g_list_reverse (group_windows);
7758
* gtk_window_get_group:
7759
* @window: (allow-none): a #GtkWindow, or %NULL
7761
* Returns the group for @window or the default group, if
7762
* @window is %NULL or if @window does not have an explicit
7765
* Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7770
gtk_window_get_group (GtkWindow *window)
7772
if (window && window->group)
7773
return window->group;
7776
static GtkWindowGroup *default_group = NULL;
7779
default_group = gtk_window_group_new ();
7781
return default_group;
7786
* gtk_window_has_group:
7787
* @window: a #GtkWindow
7789
* Returns whether @window has an explicit window group.
7791
* Return value: %TRUE if @window has an explicit window group.
7796
gtk_window_has_group (GtkWindow *window)
7798
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7800
return window->group != NULL;
7804
* gtk_window_group_get_current_current_grab:
7805
* @window_group: a #GtkWindowGroup
7807
* Gets the current grab widget of the given group,
7808
* see gtk_grab_add().
7810
* Returns: (transfer none): the current grab widget of the group
7815
gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7817
if (window_group->grabs)
7818
return GTK_WIDGET (window_group->grabs->data);
7823
Derived from XParseGeometry() in XFree86
7825
Copyright 1985, 1986, 1987,1998 The Open Group
7827
All Rights Reserved.
7829
The above copyright notice and this permission notice shall be included
7830
in all copies or substantial portions of the Software.
7832
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7833
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7834
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7835
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7836
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7837
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7838
OTHER DEALINGS IN THE SOFTWARE.
7840
Except as contained in this notice, the name of The Open Group shall
7841
not be used in advertising or otherwise to promote the sale, use or
7842
other dealings in this Software without prior written authorization
7843
from The Open Group.
7848
* XParseGeometry parses strings of the form
7849
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7850
* width, height, xoffset, and yoffset are unsigned integers.
7851
* Example: "=80x24+300-49"
7852
* The equal sign is optional.
7853
* It returns a bitmask that indicates which of the four values
7854
* were actually found in the string. For each value found,
7855
* the corresponding argument is updated; for each value
7856
* not found, the corresponding argument is left unchanged.
7859
/* The following code is from Xlib, and is minimally modified, so we
7860
* can track any upstream changes if required. Don't change this
7861
* code. Or if you do, put in a huge comment marking which thing
7866
read_int (gchar *string,
7874
else if (*string == '-')
7880
for (; (*string >= '0') && (*string <= '9'); string++)
7882
result = (result * 10) + (*string - '0');
7894
* Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7895
* value (x, y, width, height) was found in the parsed string.
7897
#define NoValue 0x0000
7898
#define XValue 0x0001
7899
#define YValue 0x0002
7900
#define WidthValue 0x0004
7901
#define HeightValue 0x0008
7902
#define AllValues 0x000F
7903
#define XNegative 0x0010
7904
#define YNegative 0x0020
7906
/* Try not to reformat/modify, so we can compare/sync with X sources */
7908
gtk_XParseGeometry (const char *string,
7911
unsigned int *width,
7912
unsigned int *height)
7916
unsigned int tempWidth, tempHeight;
7918
char *nextCharacter;
7920
/* These initializations are just to silence gcc */
7926
if ( (string == NULL) || (*string == '\0')) return(mask);
7928
string++; /* ignore possible '=' at beg of geometry spec */
7930
strind = (char *)string;
7931
if (*strind != '+' && *strind != '-' && *strind != 'x') {
7932
tempWidth = read_int(strind, &nextCharacter);
7933
if (strind == nextCharacter)
7935
strind = nextCharacter;
7939
if (*strind == 'x' || *strind == 'X') {
7941
tempHeight = read_int(strind, &nextCharacter);
7942
if (strind == nextCharacter)
7944
strind = nextCharacter;
7945
mask |= HeightValue;
7948
if ((*strind == '+') || (*strind == '-')) {
7949
if (*strind == '-') {
7951
tempX = -read_int(strind, &nextCharacter);
7952
if (strind == nextCharacter)
7954
strind = nextCharacter;
7960
tempX = read_int(strind, &nextCharacter);
7961
if (strind == nextCharacter)
7963
strind = nextCharacter;
7966
if ((*strind == '+') || (*strind == '-')) {
7967
if (*strind == '-') {
7969
tempY = -read_int(strind, &nextCharacter);
7970
if (strind == nextCharacter)
7972
strind = nextCharacter;
7979
tempY = read_int(strind, &nextCharacter);
7980
if (strind == nextCharacter)
7982
strind = nextCharacter;
7988
/* If strind isn't at the end of the string the it's an invalid
7989
geometry specification. */
7991
if (*strind != '\0') return (0);
7997
if (mask & WidthValue)
7999
if (mask & HeightValue)
8000
*height = tempHeight;
8005
* gtk_window_parse_geometry:
8006
* @window: a #GtkWindow
8007
* @geometry: geometry string
8009
* Parses a standard X Window System geometry string - see the
8010
* manual page for X (type 'man X') for details on this.
8011
* gtk_window_parse_geometry() does work on all GTK+ ports
8012
* including Win32 but is primarily intended for an X environment.
8014
* If either a size or a position can be extracted from the
8015
* geometry string, gtk_window_parse_geometry() returns %TRUE
8016
* and calls gtk_window_set_default_size() and/or gtk_window_move()
8017
* to resize/move the window.
8019
* If gtk_window_parse_geometry() returns %TRUE, it will also
8020
* set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
8021
* indicating to the window manager that the size/position of
8022
* the window was user-specified. This causes most window
8023
* managers to honor the geometry.
8025
* Note that for gtk_window_parse_geometry() to work as expected, it has
8026
* to be called when the window has its "final" size, i.e. after calling
8027
* gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
8030
* #include <gtk/gtk.h>
8033
* fill_with_content (GtkWidget *vbox)
8035
* /* fill with content... */
8039
* main (int argc, char *argv[])
8041
* GtkWidget *window, *vbox;
8042
* GdkGeometry size_hints = {
8043
* 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
8046
* gtk_init (&argc, &argv);
8048
* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8049
* vbox = gtk_vbox_new (FALSE, 0);
8051
* gtk_container_add (GTK_CONTAINER (window), vbox);
8052
* fill_with_content (vbox);
8053
* gtk_widget_show_all (vbox);
8055
* gtk_window_set_geometry_hints (GTK_WINDOW (window),
8058
* GDK_HINT_MIN_SIZE |
8059
* GDK_HINT_BASE_SIZE |
8060
* GDK_HINT_RESIZE_INC);
8064
* if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8065
* fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8068
* gtk_widget_show_all (window);
8075
* Return value: %TRUE if string was parsed successfully
8078
gtk_window_parse_geometry (GtkWindow *window,
8079
const gchar *geometry)
8081
gint result, x = 0, y = 0;
8084
gboolean size_set, pos_set;
8087
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8088
g_return_val_if_fail (geometry != NULL, FALSE);
8090
screen = gtk_window_check_screen (window);
8092
result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8095
if ((result & WidthValue) || (result & HeightValue))
8097
gtk_window_set_default_size_internal (window,
8098
TRUE, result & WidthValue ? w : -1,
8099
TRUE, result & HeightValue ? h : -1,
8104
gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8106
grav = GDK_GRAVITY_NORTH_WEST;
8108
if ((result & XNegative) && (result & YNegative))
8109
grav = GDK_GRAVITY_SOUTH_EAST;
8110
else if (result & XNegative)
8111
grav = GDK_GRAVITY_NORTH_EAST;
8112
else if (result & YNegative)
8113
grav = GDK_GRAVITY_SOUTH_WEST;
8115
if ((result & XValue) == 0)
8118
if ((result & YValue) == 0)
8121
if (grav == GDK_GRAVITY_SOUTH_WEST ||
8122
grav == GDK_GRAVITY_SOUTH_EAST)
8123
y = gdk_screen_get_height (screen) - h + y;
8125
if (grav == GDK_GRAVITY_SOUTH_EAST ||
8126
grav == GDK_GRAVITY_NORTH_EAST)
8127
x = gdk_screen_get_width (screen) - w + x;
8129
/* we don't let you put a window offscreen; maybe some people would
8130
* prefer to be able to, but it's kind of a bogus thing to do.
8139
if ((result & XValue) || (result & YValue))
8141
gtk_window_set_gravity (window, grav);
8142
gtk_window_move (window, x, y);
8146
if (size_set || pos_set)
8148
/* Set USSize, USPosition hints */
8149
GtkWindowGeometryInfo *info;
8151
info = gtk_window_get_geometry_info (window, TRUE);
8154
info->mask |= GDK_HINT_USER_POS;
8156
info->mask |= GDK_HINT_USER_SIZE;
8163
gtk_window_mnemonic_hash_foreach (guint keyval,
8169
GtkWindowKeysForeachFunc func;
8173
(*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8177
_gtk_window_keys_foreach (GtkWindow *window,
8178
GtkWindowKeysForeachFunc func,
8182
GtkMnemonicHash *mnemonic_hash;
8186
GtkWindowKeysForeachFunc func;
8190
info.window = window;
8192
info.func_data = func_data;
8194
mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8196
_gtk_mnemonic_hash_foreach (mnemonic_hash,
8197
gtk_window_mnemonic_hash_foreach, &info);
8199
groups = gtk_accel_groups_from_object (G_OBJECT (window));
8202
GtkAccelGroup *group = groups->data;
8205
for (i = 0; i < group->n_accels; i++)
8207
GtkAccelKey *key = &group->priv_accels[i].key;
8210
(*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8213
groups = groups->next;
8218
gtk_window_keys_changed (GtkWindow *window)
8220
gtk_window_free_key_hash (window);
8221
gtk_window_get_key_hash (window);
8224
typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8226
struct _GtkWindowKeyEntry
8230
guint is_mnemonic : 1;
8234
window_key_entry_destroy (gpointer data)
8236
g_slice_free (GtkWindowKeyEntry, data);
8240
add_to_key_hash (GtkWindow *window,
8242
GdkModifierType modifiers,
8243
gboolean is_mnemonic,
8246
GtkKeyHash *key_hash = data;
8248
GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8250
entry->keyval = keyval;
8251
entry->modifiers = modifiers;
8252
entry->is_mnemonic = is_mnemonic;
8254
/* GtkAccelGroup stores lowercased accelerators. To deal
8255
* with this, if <Shift> was specified, uppercase.
8257
if (modifiers & GDK_SHIFT_MASK)
8259
if (keyval == GDK_Tab)
8260
keyval = GDK_ISO_Left_Tab;
8262
keyval = gdk_keyval_to_upper (keyval);
8265
_gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8269
gtk_window_get_key_hash (GtkWindow *window)
8271
GdkScreen *screen = gtk_window_check_screen (window);
8272
GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8277
key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8278
(GDestroyNotify)window_key_entry_destroy);
8279
_gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8280
g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8286
gtk_window_free_key_hash (GtkWindow *window)
8288
GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8291
_gtk_key_hash_free (key_hash);
8292
g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8297
* gtk_window_activate_key:
8298
* @window: a #GtkWindow
8299
* @event: a #GdkEventKey
8301
* Activates mnemonics and accelerators for this #GtkWindow. This is normally
8302
* called by the default ::key_press_event handler for toplevel windows,
8303
* however in some cases it may be useful to call this directly when
8304
* overriding the standard key handling for a toplevel window.
8306
* Return value: %TRUE if a mnemonic or accelerator was found and activated.
8311
gtk_window_activate_key (GtkWindow *window,
8314
GtkKeyHash *key_hash;
8315
GtkWindowKeyEntry *found_entry = NULL;
8316
gboolean enable_mnemonics;
8317
gboolean enable_accels;
8319
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8320
g_return_val_if_fail (event != NULL, FALSE);
8322
key_hash = gtk_window_get_key_hash (window);
8327
GSList *entries = _gtk_key_hash_lookup (key_hash,
8328
event->hardware_keycode,
8330
gtk_accelerator_get_default_mod_mask (),
8333
g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8334
"gtk-enable-mnemonics", &enable_mnemonics,
8335
"gtk-enable-accels", &enable_accels,
8338
for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8340
GtkWindowKeyEntry *entry = tmp_list->data;
8341
if (entry->is_mnemonic)
8343
if (enable_mnemonics)
8345
found_entry = entry;
8351
if (enable_accels && !found_entry)
8353
found_entry = entry;
8358
g_slist_free (entries);
8363
if (found_entry->is_mnemonic)
8365
if (enable_mnemonics)
8366
return gtk_window_mnemonic_activate (window, found_entry->keyval,
8367
found_entry->modifiers);
8372
return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8373
found_entry->modifiers);
8381
window_update_has_focus (GtkWindow *window)
8383
GtkWidget *widget = GTK_WIDGET (window);
8384
gboolean has_focus = window->has_toplevel_focus && window->is_active;
8386
if (has_focus != window->has_focus)
8388
window->has_focus = has_focus;
8392
if (window->focus_widget &&
8393
window->focus_widget != widget &&
8394
!gtk_widget_has_focus (window->focus_widget))
8395
do_focus_change (window->focus_widget, TRUE);
8399
if (window->focus_widget &&
8400
window->focus_widget != widget &&
8401
gtk_widget_has_focus (window->focus_widget))
8402
do_focus_change (window->focus_widget, FALSE);
8408
* _gtk_window_set_is_active:
8409
* @window: a #GtkWindow
8410
* @is_active: %TRUE if the window is in the currently active toplevel
8412
* Internal function that sets whether the #GtkWindow is part
8413
* of the currently active toplevel window (taking into account inter-process
8417
_gtk_window_set_is_active (GtkWindow *window,
8420
g_return_if_fail (GTK_IS_WINDOW (window));
8422
is_active = is_active != FALSE;
8424
if (is_active != window->is_active)
8426
window->is_active = is_active;
8427
window_update_has_focus (window);
8429
g_object_notify (G_OBJECT (window), "is-active");
8434
* _gtk_window_set_is_toplevel:
8435
* @window: a #GtkWindow
8436
* @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8437
* parent of the root window); %FALSE if it is not (for example, for an
8438
* in-process, parented GtkPlug)
8440
* Internal function used by #GtkPlug when it gets parented/unparented by a
8441
* #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8442
* global list of toplevel windows.
8445
_gtk_window_set_is_toplevel (GtkWindow *window,
8446
gboolean is_toplevel)
8450
widget = GTK_WIDGET (window);
8452
if (gtk_widget_is_toplevel (widget))
8453
g_assert (g_slist_find (toplevel_list, window) != NULL);
8455
g_assert (g_slist_find (toplevel_list, window) == NULL);
8457
if (is_toplevel == gtk_widget_is_toplevel (widget))
8462
_gtk_widget_set_is_toplevel (widget, TRUE);
8463
toplevel_list = g_slist_prepend (toplevel_list, window);
8467
_gtk_widget_set_is_toplevel (widget, FALSE);
8468
toplevel_list = g_slist_remove (toplevel_list, window);
8473
* _gtk_window_set_has_toplevel_focus:
8474
* @window: a #GtkWindow
8475
* @has_toplevel_focus: %TRUE if the in
8477
* Internal function that sets whether the keyboard focus for the
8478
* toplevel window (taking into account inter-process embedding.)
8481
_gtk_window_set_has_toplevel_focus (GtkWindow *window,
8482
gboolean has_toplevel_focus)
8484
g_return_if_fail (GTK_IS_WINDOW (window));
8486
has_toplevel_focus = has_toplevel_focus != FALSE;
8488
if (has_toplevel_focus != window->has_toplevel_focus)
8490
window->has_toplevel_focus = has_toplevel_focus;
8491
window_update_has_focus (window);
8493
g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8498
* gtk_window_set_auto_startup_notification:
8499
* @setting: %TRUE to automatically do startup notification
8501
* By default, after showing the first #GtkWindow, GTK+ calls
8502
* gdk_notify_startup_complete(). Call this function to disable
8503
* the automatic startup notification. You might do this if your
8504
* first window is a splash screen, and you want to delay notification
8505
* until after your real main window has been shown, for example.
8507
* In that example, you would disable startup notification
8508
* temporarily, show your splash screen, then re-enable it so that
8509
* showing the main window would automatically result in notification.
8514
gtk_window_set_auto_startup_notification (gboolean setting)
8516
disable_startup_notification = !setting;
8520
* gtk_window_get_window_type:
8521
* @window: a #GtkWindow
8523
* Gets the type of the window. See #GtkWindowType.
8525
* Return value: the type of the window
8530
gtk_window_get_window_type (GtkWindow *window)
8532
g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8534
return window->type;
8537
/* gtk_window_get_mnemonics_visible:
8538
* @window: a #GtkWindow
8540
* Gets the value of the #GtkWindow:mnemonics-visible property.
8542
* Returns: %TRUE if mnemonics are supposed to be visible
8548
gtk_window_get_mnemonics_visible (GtkWindow *window)
8550
GtkWindowPrivate *priv;
8552
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8554
priv = GTK_WINDOW_GET_PRIVATE (window);
8556
return priv->mnemonics_visible;
8560
* gtk_window_set_mnemonics_visible:
8561
* @window: a #GtkWindow
8562
* @setting: the new value
8564
* Sets the #GtkWindow:mnemonics-visible property.
8569
gtk_window_set_mnemonics_visible (GtkWindow *window,
8572
GtkWindowPrivate *priv;
8574
g_return_if_fail (GTK_IS_WINDOW (window));
8576
priv = GTK_WINDOW_GET_PRIVATE (window);
8578
setting = setting != FALSE;
8580
if (priv->mnemonics_visible != setting)
8582
priv->mnemonics_visible = setting;
8583
g_object_notify (G_OBJECT (window), "mnemonics-visible");
8586
priv->mnemonics_visible_set = TRUE;
8589
#if defined (G_OS_WIN32) && !defined (_WIN64)
8591
#undef gtk_window_set_icon_from_file
8594
gtk_window_set_icon_from_file (GtkWindow *window,
8595
const gchar *filename,
8598
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8601
if (utf8_filename == NULL)
8604
retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8606
g_free (utf8_filename);
8611
#undef gtk_window_set_default_icon_from_file
8614
gtk_window_set_default_icon_from_file (const gchar *filename,
8617
gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8620
if (utf8_filename == NULL)
8623
retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8625
g_free (utf8_filename);
8632
#define __GTK_WINDOW_C__
8633
#include "gtkaliasdef.c"