Bug Summary

File:ctk/ctkwindow.c
Warning:line 4083, column 37
Access to field 'win_gravity' results in a dereference of a null pointer (loaded from variable 'geometry')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctkwindow.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172241-43638-1 -x c ctkwindow.c
1/* CTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
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.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the CTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
23 */
24
25#include "config.h"
26
27#include "ctkwindow.h"
28
29#include <string.h>
30#include <stdlib.h>
31#include <errno(*__errno_location ()).h>
32#include <limits.h>
33
34#include "ctkprivate.h"
35#include "ctkwindowprivate.h"
36#include "ctkaccelgroupprivate.h"
37#include "ctkbindings.h"
38#include "ctkcsscornervalueprivate.h"
39#include "ctkcssiconthemevalueprivate.h"
40#include "ctkcssrgbavalueprivate.h"
41#include "ctkcssshadowsvalueprivate.h"
42#include "ctkkeyhash.h"
43#include "ctkmain.h"
44#include "ctkmnemonichash.h"
45#include "ctkmenubar.h"
46#include "ctkmenushellprivate.h"
47#include "ctkicontheme.h"
48#include "ctkmarshalers.h"
49#include "ctkplug.h"
50#include "ctkbuildable.h"
51#include "ctkbuilderprivate.h"
52#include "ctkwidgetprivate.h"
53#include "ctkcontainerprivate.h"
54#include "ctkintl.h"
55#include "ctkstylecontextprivate.h"
56#include "ctktypebuiltins.h"
57#include "ctkbox.h"
58#include "ctkbutton.h"
59#include "ctkheaderbar.h"
60#include "ctkheaderbarprivate.h"
61#include "ctkpopoverprivate.h"
62#include "a11y/ctkwindowaccessible.h"
63#include "a11y/ctkcontaineraccessibleprivate.h"
64#include "ctkapplicationprivate.h"
65#include "ctkgestureprivate.h"
66#include "inspector/init.h"
67#include "inspector/window.h"
68#include "ctkcssstylepropertyprivate.h"
69
70#include "cdk/cdk-private.h"
71
72#ifdef CDK_WINDOWING_X11
73#include "x11/cdkx.h"
74#endif
75
76#ifdef CDK_WINDOWING_WIN32
77#include "win32/cdkwin32.h"
78#endif
79
80#ifdef CDK_WINDOWING_WAYLAND
81#include "wayland/cdkwayland.h"
82#endif
83
84#ifdef CDK_WINDOWING_BROADWAY
85#include "broadway/cdkbroadway.h"
86#endif
87
88/**
89 * SECTION:ctkwindow
90 * @title: CtkWindow
91 * @short_description: Toplevel which can contain other widgets
92 *
93 * A CtkWindow is a toplevel window which can contain other widgets.
94 * Windows normally have decorations that are under the control
95 * of the windowing system and allow the user to manipulate the window
96 * (resize it, move it, close it,...).
97 *
98 * # CtkWindow as CtkBuildable
99 *
100 * The CtkWindow implementation of the #CtkBuildable interface supports a
101 * custom <accel-groups> element, which supports any number of <group>
102 * elements representing the #CtkAccelGroup objects you want to add to
103 * your window (synonymous with ctk_window_add_accel_group().
104 *
105 * It also supports the <initial-focus> element, whose name property names
106 * the widget to receive the focus when the window is mapped.
107 *
108 * An example of a UI definition fragment with accel groups:
109 * |[
110 * <object class="CtkWindow">
111 * <accel-groups>
112 * <group name="accelgroup1"/>
113 * </accel-groups>
114 * <initial-focus name="thunderclap"/>
115 * </object>
116 *
117 * ...
118 *
119 * <object class="CtkAccelGroup" id="accelgroup1"/>
120 * ]|
121 *
122 * The CtkWindow implementation of the #CtkBuildable interface supports
123 * setting a child as the titlebar by specifying “titlebar” as the “type”
124 * attribute of a <child> element.
125 *
126 * # CSS nodes
127 *
128 * |[<!-- language="plain" -->
129 * window.background
130 * ├── decoration
131 * ├── <titlebar child>.titlebar [.default-decoration]
132 * ╰── <child>
133 * ]|
134 *
135 * CtkWindow has a main CSS node with name window and style class .background,
136 * and a subnode with name decoration.
137 *
138 * Style classes that are typically used with the main CSS node are .csd (when
139 * client-side decorations are in use), .solid-csd (for client-side decorations
140 * without invisible borders), .ssd (used by mutter when rendering server-side
141 * decorations). CtkWindow also represents window states with the following
142 * style classes on the main node: .tiled, .maximized, .fullscreen. Specialized
143 * types of window often add their own discriminating style classes, such as
144 * .popup or .tooltip.
145 *
146 * CtkWindow adds the .titlebar and .default-decoration style classes to the
147 * widget that is added as a titlebar child.
148 */
149
150#define MNEMONICS_DELAY300 300 /* ms */
151#define NO_CONTENT_CHILD_NAT200 200
152/* In case the content (excluding header bar and shadows) of the window
153 * would be empty, either because there is no visible child widget or only an
154 * empty container widget, we use NO_CONTENT_CHILD_NAT as natural width/height
155 * instead.
156 */
157
158typedef struct _CtkWindowPopover CtkWindowPopover;
159
160struct _CtkWindowPopover
161{
162 CtkWidget *widget;
163 CtkWidget *parent;
164 CdkWindow *window;
165 CtkPositionType pos;
166 cairo_rectangle_int_t rect;
167 gulong unmap_id;
168 guint clamp_allocation : 1;
169};
170
171struct _CtkWindowPrivate
172{
173 CtkMnemonicHash *mnemonic_hash;
174
175 CtkWidget *attach_widget;
176 CtkWidget *default_widget;
177 CtkWidget *initial_focus;
178 CtkWidget *focus_widget;
179 CtkWindow *transient_parent;
180 CtkWindowGeometryInfo *geometry_info;
181 CtkWindowGroup *group;
182 CdkScreen *screen;
183 CdkDisplay *display;
184 CtkApplication *application;
185
186 GList *popovers;
187
188 CdkModifierType mnemonic_modifier;
189
190 gchar *startup_id;
191 gchar *title;
192 gchar *wmclass_class;
193 gchar *wmclass_name;
194 gchar *wm_role;
195
196 guint keys_changed_handler;
197 guint delete_event_handler;
198
199 guint32 initial_timestamp;
200
201 guint16 configure_request_count;
202
203 guint mnemonics_display_timeout_id;
204
205 gint scale;
206
207 gint title_height;
208 CtkWidget *title_box;
209 CtkWidget *titlebar;
210 CtkWidget *popup_menu;
211
212 CdkWindow *border_window[8];
213 gint initial_fullscreen_monitor;
214 guint edge_constraints;
215
216 /* The following flags are initially TRUE (before a window is mapped).
217 * They cause us to compute a configure request that involves
218 * default-only parameters. Once mapped, we set them to FALSE.
219 * Then we set them to TRUE again on unmap (for position)
220 * and on unrealize (for size).
221 */
222 guint need_default_position : 1;
223 guint need_default_size : 1;
224
225 guint above_initially : 1;
226 guint accept_focus : 1;
227 guint below_initially : 1;
228 guint builder_visible : 1;
229 guint configure_notify_received : 1;
230 guint decorated : 1;
231 guint deletable : 1;
232 guint destroy_with_parent : 1;
233 guint focus_on_map : 1;
234 guint fullscreen_initially : 1;
235 guint has_focus : 1;
236 guint has_user_ref_count : 1;
237 guint has_toplevel_focus : 1;
238 guint hide_titlebar_when_maximized : 1;
239 guint iconify_initially : 1; /* ctk_window_iconify() called before realization */
240 guint is_active : 1;
241 guint maximize_initially : 1;
242 guint mnemonics_visible : 1;
243 guint mnemonics_visible_set : 1;
244 guint focus_visible : 1;
245 guint modal : 1;
246 guint position : 3;
247 guint resizable : 1;
248 guint skips_pager : 1;
249 guint skips_taskbar : 1;
250 guint stick_initially : 1;
251 guint transient_parent_group : 1;
252 guint type : 4; /* CtkWindowType */
253 guint urgent : 1;
254 guint gravity : 5; /* CdkGravity */
255 guint csd_requested : 1;
256 guint client_decorated : 1; /* Decorations drawn client-side */
257 guint use_client_shadow : 1; /* Decorations use client-side shadows */
258 guint maximized : 1;
259 guint fullscreen : 1;
260 guint tiled : 1;
261 guint unlimited_guessed_size_x : 1;
262 guint unlimited_guessed_size_y : 1;
263 guint force_resize : 1;
264 guint fixate_size : 1;
265
266 guint use_subsurface : 1;
267
268 CdkWindowTypeHint type_hint;
269
270 CtkGesture *multipress_gesture;
271 CtkGesture *drag_gesture;
272
273 CdkWindow *hardcoded_window;
274
275 CtkCssNode *decoration_node;
276};
277
278#ifdef CDK_WINDOWING_X11
279static const CtkTargetEntry dnd_dest_targets [] = {
280 { "application/x-rootwindow-drop", 0, 0 },
281};
282#endif
283
284enum {
285 SET_FOCUS,
286 ACTIVATE_FOCUS,
287 ACTIVATE_DEFAULT,
288 KEYS_CHANGED,
289 ENABLE_DEBUGGING,
290 LAST_SIGNAL
291};
292
293enum {
294 PROP_0,
295
296 /* Construct */
297 PROP_TYPE,
298
299 /* Normal Props */
300 PROP_TITLE,
301 PROP_ROLE,
302 PROP_RESIZABLE,
303 PROP_MODAL,
304 PROP_WIN_POS,
305 PROP_DEFAULT_WIDTH,
306 PROP_DEFAULT_HEIGHT,
307 PROP_DESTROY_WITH_PARENT,
308 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
309 PROP_ICON,
310 PROP_ICON_NAME,
311 PROP_SCREEN,
312 PROP_TYPE_HINT,
313 PROP_SKIP_TASKBAR_HINT,
314 PROP_SKIP_PAGER_HINT,
315 PROP_URGENCY_HINT,
316 PROP_ACCEPT_FOCUS,
317 PROP_FOCUS_ON_MAP,
318 PROP_DECORATED,
319 PROP_DELETABLE,
320 PROP_GRAVITY,
321 PROP_TRANSIENT_FOR,
322 PROP_ATTACHED_TO,
323 PROP_HAS_RESIZE_GRIP,
324 PROP_RESIZE_GRIP_VISIBLE,
325 PROP_APPLICATION,
326 /* Readonly properties */
327 PROP_IS_ACTIVE,
328 PROP_HAS_TOPLEVEL_FOCUS,
329
330 /* Writeonly properties */
331 PROP_STARTUP_ID,
332
333 PROP_MNEMONICS_VISIBLE,
334 PROP_FOCUS_VISIBLE,
335
336 PROP_IS_MAXIMIZED,
337
338 LAST_ARG
339};
340
341static GParamSpec *window_props[LAST_ARG] = { NULL((void*)0), };
342
343/* Must be kept in sync with CdkWindowEdge ! */
344typedef enum
345{
346 CTK_WINDOW_REGION_EDGE_NW,
347 CTK_WINDOW_REGION_EDGE_N,
348 CTK_WINDOW_REGION_EDGE_NE,
349 CTK_WINDOW_REGION_EDGE_W,
350 CTK_WINDOW_REGION_EDGE_E,
351 CTK_WINDOW_REGION_EDGE_SW,
352 CTK_WINDOW_REGION_EDGE_S,
353 CTK_WINDOW_REGION_EDGE_SE,
354 CTK_WINDOW_REGION_CONTENT,
355 CTK_WINDOW_REGION_TITLE,
356} CtkWindowRegion;
357
358typedef struct
359{
360 GList *icon_list;
361 gchar *icon_name;
362 guint realized : 1;
363 guint using_default_icon : 1;
364 guint using_parent_icon : 1;
365 guint using_themed_icon : 1;
366} CtkWindowIconInfo;
367
368typedef struct {
369 CdkGeometry geometry; /* Last set of geometry hints we set */
370 CdkWindowHints flags;
371 CdkRectangle configure_request;
372} CtkWindowLastGeometryInfo;
373
374struct _CtkWindowGeometryInfo
375{
376 /* Properties that the app has set on the window
377 */
378 CdkGeometry geometry; /* Geometry hints */
379 CdkWindowHints mask;
380 /* from last ctk_window_resize () - if > 0, indicates that
381 * we should resize to this size.
382 */
383 gint resize_width;
384 gint resize_height;
385
386 /* From last ctk_window_move () prior to mapping -
387 * only used if initial_pos_set
388 */
389 gint initial_x;
390 gint initial_y;
391
392 /* Default size - used only the FIRST time we map a window,
393 * only if > 0.
394 */
395 gint default_width;
396 gint default_height;
397 /* whether to use initial_x, initial_y */
398 guint initial_pos_set : 1;
399 /* CENTER_ALWAYS or other position constraint changed since
400 * we sent the last configure request.
401 */
402 guint position_constraints_changed : 1;
403
404 /* if true, default_width, height should be multiplied by the
405 * increments and affect the geometry widget only
406 */
407 guint default_is_geometry : 1;
408
409 CtkWindowLastGeometryInfo last;
410};
411
412
413static void ctk_window_constructed (GObject *object);
414static void ctk_window_dispose (GObject *object);
415static void ctk_window_finalize (GObject *object);
416static void ctk_window_destroy (CtkWidget *widget);
417static void ctk_window_show (CtkWidget *widget);
418static void ctk_window_hide (CtkWidget *widget);
419static void ctk_window_map (CtkWidget *widget);
420static void ctk_window_unmap (CtkWidget *widget);
421static void ctk_window_realize (CtkWidget *widget);
422static void ctk_window_unrealize (CtkWidget *widget);
423static void ctk_window_size_allocate (CtkWidget *widget,
424 CtkAllocation *allocation);
425static gboolean ctk_window_map_event (CtkWidget *widget,
426 CdkEventAny *event);
427static gint ctk_window_configure_event (CtkWidget *widget,
428 CdkEventConfigure *event);
429static gboolean ctk_window_event (CtkWidget *widget,
430 CdkEvent *event);
431static gint ctk_window_key_press_event (CtkWidget *widget,
432 CdkEventKey *event);
433static gint ctk_window_key_release_event (CtkWidget *widget,
434 CdkEventKey *event);
435static gint ctk_window_focus_in_event (CtkWidget *widget,
436 CdkEventFocus *event);
437static gint ctk_window_focus_out_event (CtkWidget *widget,
438 CdkEventFocus *event);
439static gboolean ctk_window_state_event (CtkWidget *widget,
440 CdkEventWindowState *event);
441static void ctk_window_remove (CtkContainer *container,
442 CtkWidget *widget);
443static void ctk_window_check_resize (CtkContainer *container);
444static void ctk_window_forall (CtkContainer *container,
445 gboolean include_internals,
446 CtkCallback callback,
447 gpointer callback_data);
448static gint ctk_window_focus (CtkWidget *widget,
449 CtkDirectionType direction);
450static void ctk_window_move_focus (CtkWidget *widget,
451 CtkDirectionType dir);
452static void ctk_window_real_set_focus (CtkWindow *window,
453 CtkWidget *focus);
454
455static void ctk_window_real_activate_default (CtkWindow *window);
456static void ctk_window_real_activate_focus (CtkWindow *window);
457static void ctk_window_keys_changed (CtkWindow *window);
458static gboolean ctk_window_enable_debugging (CtkWindow *window,
459 gboolean toggle);
460static gint ctk_window_draw (CtkWidget *widget,
461 cairo_t *cr);
462static void ctk_window_unset_transient_for (CtkWindow *window);
463static void ctk_window_transient_parent_realized (CtkWidget *parent,
464 CtkWidget *window);
465static void ctk_window_transient_parent_unrealized (CtkWidget *parent,
466 CtkWidget *window);
467
468static CdkScreen *ctk_window_check_screen (CtkWindow *window);
469
470static CtkWindowGeometryInfo* ctk_window_get_geometry_info (CtkWindow *window,
471 gboolean create);
472
473static gboolean ctk_window_compare_hints (CdkGeometry *geometry_a,
474 guint flags_a,
475 CdkGeometry *geometry_b,
476 guint flags_b);
477static void ctk_window_constrain_size (CtkWindow *window,
478 CdkGeometry *geometry,
479 guint flags,
480 gint width,
481 gint height,
482 gint *new_width,
483 gint *new_height);
484static void ctk_window_constrain_position (CtkWindow *window,
485 gint new_width,
486 gint new_height,
487 gint *x,
488 gint *y);
489static void ctk_window_update_fixed_size (CtkWindow *window,
490 CdkGeometry *new_geometry,
491 gint new_width,
492 gint new_height);
493static void ctk_window_compute_hints (CtkWindow *window,
494 CdkGeometry *new_geometry,
495 guint *new_flags);
496static void ctk_window_compute_configure_request (CtkWindow *window,
497 CdkRectangle *request,
498 CdkGeometry *geometry,
499 guint *flags);
500
501static void ctk_window_set_default_size_internal (CtkWindow *window,
502 gboolean change_width,
503 gint width,
504 gboolean change_height,
505 gint height,
506 gboolean is_geometry);
507
508static void update_themed_icon (CtkWindow *window);
509static GList *icon_list_from_theme (CtkWindow *window,
510 const gchar *name);
511static void ctk_window_realize_icon (CtkWindow *window);
512static void ctk_window_unrealize_icon (CtkWindow *window);
513static void update_window_buttons (CtkWindow *window);
514static void get_shadow_width (CtkWindow *window,
515 CtkBorder *shadow_width);
516
517static CtkKeyHash *ctk_window_get_key_hash (CtkWindow *window);
518static void ctk_window_free_key_hash (CtkWindow *window);
519static void ctk_window_on_composited_changed (CdkScreen *screen,
520 CtkWindow *window);
521#ifdef CDK_WINDOWING_X11
522static void ctk_window_on_theme_variant_changed (CtkSettings *settings,
523 GParamSpec *pspec,
524 CtkWindow *window);
525#endif
526static void ctk_window_set_theme_variant (CtkWindow *window);
527
528static void ctk_window_do_popup (CtkWindow *window,
529 CdkEventButton *event);
530
531static void ctk_window_get_preferred_width (CtkWidget *widget,
532 gint *minimum_size,
533 gint *natural_size);
534static void ctk_window_get_preferred_width_for_height (CtkWidget *widget,
535 gint height,
536 gint *minimum_size,
537 gint *natural_size);
538
539static void ctk_window_get_preferred_height (CtkWidget *widget,
540 gint *minimum_size,
541 gint *natural_size);
542static void ctk_window_get_preferred_height_for_width (CtkWidget *widget,
543 gint width,
544 gint *minimum_size,
545 gint *natural_size);
546static void ctk_window_style_updated (CtkWidget *widget);
547static void ctk_window_state_flags_changed (CtkWidget *widget,
548 CtkStateFlags previous_state);
549
550static void ctk_window_get_remembered_size (CtkWindow *window,
551 int *width,
552 int *height);
553
554static GSList *toplevel_list = NULL((void*)0);
555static guint window_signals[LAST_SIGNAL] = { 0 };
556static GList *default_icon_list = NULL((void*)0);
557static gchar *default_icon_name = NULL((void*)0);
558static guint default_icon_serial = 0;
559static gboolean disable_startup_notification = FALSE(0);
560
561static GQuark quark_ctk_embedded = 0;
562static GQuark quark_ctk_window_key_hash = 0;
563static GQuark quark_ctk_window_icon_info = 0;
564static GQuark quark_ctk_buildable_accels = 0;
565
566static CtkBuildableIface *parent_buildable_iface;
567
568static void ctk_window_set_property (GObject *object,
569 guint prop_id,
570 const GValue *value,
571 GParamSpec *pspec);
572static void ctk_window_get_property (GObject *object,
573 guint prop_id,
574 GValue *value,
575 GParamSpec *pspec);
576
577/* CtkBuildable */
578static void ctk_window_buildable_interface_init (CtkBuildableIface *iface);
579static void ctk_window_buildable_add_child (CtkBuildable *buildable,
580 CtkBuilder *builder,
581 GObject *child,
582 const gchar *type);
583static void ctk_window_buildable_set_buildable_property (CtkBuildable *buildable,
584 CtkBuilder *builder,
585 const gchar *name,
586 const GValue *value);
587static void ctk_window_buildable_parser_finished (CtkBuildable *buildable,
588 CtkBuilder *builder);
589static gboolean ctk_window_buildable_custom_tag_start (CtkBuildable *buildable,
590 CtkBuilder *builder,
591 GObject *child,
592 const gchar *tagname,
593 GMarkupParser *parser,
594 gpointer *data);
595static void ctk_window_buildable_custom_finished (CtkBuildable *buildable,
596 CtkBuilder *builder,
597 GObject *child,
598 const gchar *tagname,
599 gpointer user_data);
600
601static void ensure_state_flag_backdrop (CtkWidget *widget);
602static void unset_titlebar (CtkWindow *window);
603static void on_titlebar_title_notify (CtkHeaderBar *titlebar,
604 GParamSpec *pspec,
605 CtkWindow *self);
606static CtkWindowRegion get_active_region_type (CtkWindow *window,
607 CdkEventAny *event,
608 gint x,
609 gint y);
610
611static void ctk_window_update_debugging (void);
612
613G_DEFINE_TYPE_WITH_CODE (CtkWindow, ctk_window, CTK_TYPE_BIN,static void ctk_window_init (CtkWindow *self); static void ctk_window_class_init
(CtkWindowClass *klass); static GType ctk_window_get_type_once
(void); static gpointer ctk_window_parent_class = ((void*)0)
; static gint CtkWindow_private_offset; static void ctk_window_class_intern_init
(gpointer klass) { ctk_window_parent_class = g_type_class_peek_parent
(klass); if (CtkWindow_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkWindow_private_offset); ctk_window_class_init
((CtkWindowClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_window_get_instance_private (CtkWindow *
self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkWindow_private_offset
)))); } GType ctk_window_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_window_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_window_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_bin_get_type
()), g_intern_static_string ("CtkWindow"), sizeof (CtkWindowClass
), (GClassInitFunc)(void (*)(void)) ctk_window_class_intern_init
, sizeof (CtkWindow), (GInstanceInitFunc)(void (*)(void)) ctk_window_init
, (GTypeFlags) 0); { {{ CtkWindow_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkWindowPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_window_buildable_interface_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
614 G_ADD_PRIVATE (CtkWindow)static void ctk_window_init (CtkWindow *self); static void ctk_window_class_init
(CtkWindowClass *klass); static GType ctk_window_get_type_once
(void); static gpointer ctk_window_parent_class = ((void*)0)
; static gint CtkWindow_private_offset; static void ctk_window_class_intern_init
(gpointer klass) { ctk_window_parent_class = g_type_class_peek_parent
(klass); if (CtkWindow_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkWindow_private_offset); ctk_window_class_init
((CtkWindowClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_window_get_instance_private (CtkWindow *
self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkWindow_private_offset
)))); } GType ctk_window_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_window_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_window_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_bin_get_type
()), g_intern_static_string ("CtkWindow"), sizeof (CtkWindowClass
), (GClassInitFunc)(void (*)(void)) ctk_window_class_intern_init
, sizeof (CtkWindow), (GInstanceInitFunc)(void (*)(void)) ctk_window_init
, (GTypeFlags) 0); { {{ CtkWindow_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkWindowPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_window_buildable_interface_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
615 G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_window_init (CtkWindow *self); static void ctk_window_class_init
(CtkWindowClass *klass); static GType ctk_window_get_type_once
(void); static gpointer ctk_window_parent_class = ((void*)0)
; static gint CtkWindow_private_offset; static void ctk_window_class_intern_init
(gpointer klass) { ctk_window_parent_class = g_type_class_peek_parent
(klass); if (CtkWindow_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkWindow_private_offset); ctk_window_class_init
((CtkWindowClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_window_get_instance_private (CtkWindow *
self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkWindow_private_offset
)))); } GType ctk_window_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_window_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_window_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_bin_get_type
()), g_intern_static_string ("CtkWindow"), sizeof (CtkWindowClass
), (GClassInitFunc)(void (*)(void)) ctk_window_class_intern_init
, sizeof (CtkWindow), (GInstanceInitFunc)(void (*)(void)) ctk_window_init
, (GTypeFlags) 0); { {{ CtkWindow_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkWindowPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_window_buildable_interface_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
616 ctk_window_buildable_interface_init))static void ctk_window_init (CtkWindow *self); static void ctk_window_class_init
(CtkWindowClass *klass); static GType ctk_window_get_type_once
(void); static gpointer ctk_window_parent_class = ((void*)0)
; static gint CtkWindow_private_offset; static void ctk_window_class_intern_init
(gpointer klass) { ctk_window_parent_class = g_type_class_peek_parent
(klass); if (CtkWindow_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CtkWindow_private_offset); ctk_window_class_init
((CtkWindowClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer ctk_window_get_instance_private (CtkWindow *
self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkWindow_private_offset
)))); } GType ctk_window_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_window_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_window_get_type_once (void) {
GType g_define_type_id = g_type_register_static_simple ((ctk_bin_get_type
()), g_intern_static_string ("CtkWindow"), sizeof (CtkWindowClass
), (GClassInitFunc)(void (*)(void)) ctk_window_class_intern_init
, sizeof (CtkWindow), (GInstanceInitFunc)(void (*)(void)) ctk_window_init
, (GTypeFlags) 0); { {{ CtkWindow_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CtkWindowPrivate)); } { const GInterfaceInfo
g_implement_interface_info = { (GInterfaceInitFunc)(void (*)
(void)) ctk_window_buildable_interface_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_buildable_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
617
618static void
619add_tab_bindings (CtkBindingSet *binding_set,
620 CdkModifierType modifiers,
621 CtkDirectionType direction)
622{
623 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Tab0xff09, modifiers,
624 "move-focus", 1,
625 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
626 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Tab0xff89, modifiers,
627 "move-focus", 1,
628 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
629}
630
631static void
632add_arrow_bindings (CtkBindingSet *binding_set,
633 guint keysym,
634 CtkDirectionType direction)
635{
636 guint keypad_keysym = keysym - CDK_KEY_Left0xff51 + CDK_KEY_KP_Left0xff96;
637
638 ctk_binding_entry_add_signal (binding_set, keysym, 0,
639 "move-focus", 1,
640 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
641 ctk_binding_entry_add_signal (binding_set, keysym, CDK_CONTROL_MASK,
642 "move-focus", 1,
643 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
644 ctk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
645 "move-focus", 1,
646 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
647 ctk_binding_entry_add_signal (binding_set, keypad_keysym, CDK_CONTROL_MASK,
648 "move-focus", 1,
649 CTK_TYPE_DIRECTION_TYPE(ctk_direction_type_get_type ()), direction);
650}
651
652static guint32
653extract_time_from_startup_id (const gchar* startup_id)
654{
655 gchar *timestr = g_strrstr (startup_id, "_TIME");
656 guint32 retval = CDK_CURRENT_TIME0L;
657
658 if (timestr)
659 {
660 gchar *end;
661 guint32 timestamp;
662
663 /* Skip past the "_TIME" part */
664 timestr += 5;
665
666 end = NULL((void*)0);
667 errno(*__errno_location ()) = 0;
668 timestamp = g_ascii_strtoull (timestr, &end, 0);
669 if (errno(*__errno_location ()) == 0 && end != timestr)
670 retval = timestamp;
671 }
672
673 return retval;
674}
675
676static gboolean
677startup_id_is_fake (const gchar* startup_id)
678{
679 return strncmp (startup_id, "_TIME", 5) == 0;
680}
681
682static void
683ctk_window_class_init (CtkWindowClass *klass)
684{
685 GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
686 CtkWidgetClass *widget_class;
687 CtkContainerClass *container_class;
688 CtkBindingSet *binding_set;
689
690 widget_class = (CtkWidgetClass*) klass;
691 container_class = (CtkContainerClass*) klass;
692
693 quark_ctk_embedded = g_quark_from_static_string ("ctk-embedded");
694 quark_ctk_window_key_hash = g_quark_from_static_string ("ctk-window-key-hash");
695 quark_ctk_window_icon_info = g_quark_from_static_string ("ctk-window-icon-info");
696 quark_ctk_buildable_accels = g_quark_from_static_string ("ctk-window-buildable-accels");
697
698 gobject_class->constructed = ctk_window_constructed;
699 gobject_class->dispose = ctk_window_dispose;
700 gobject_class->finalize = ctk_window_finalize;
701
702 gobject_class->set_property = ctk_window_set_property;
703 gobject_class->get_property = ctk_window_get_property;
704
705 widget_class->destroy = ctk_window_destroy;
706 widget_class->show = ctk_window_show;
707 widget_class->hide = ctk_window_hide;
708 widget_class->map = ctk_window_map;
709 widget_class->map_event = ctk_window_map_event;
710 widget_class->unmap = ctk_window_unmap;
711 widget_class->realize = ctk_window_realize;
712 widget_class->unrealize = ctk_window_unrealize;
713 widget_class->size_allocate = ctk_window_size_allocate;
714 widget_class->configure_event = ctk_window_configure_event;
715 widget_class->event = ctk_window_event;
716 widget_class->key_press_event = ctk_window_key_press_event;
717 widget_class->key_release_event = ctk_window_key_release_event;
718 widget_class->focus_in_event = ctk_window_focus_in_event;
719 widget_class->focus_out_event = ctk_window_focus_out_event;
720 widget_class->focus = ctk_window_focus;
721 widget_class->move_focus = ctk_window_move_focus;
722 widget_class->draw = ctk_window_draw;
723 widget_class->window_state_event = ctk_window_state_event;
724 widget_class->get_preferred_width = ctk_window_get_preferred_width;
725 widget_class->get_preferred_width_for_height = ctk_window_get_preferred_width_for_height;
726 widget_class->get_preferred_height = ctk_window_get_preferred_height;
727 widget_class->get_preferred_height_for_width = ctk_window_get_preferred_height_for_width;
728 widget_class->state_flags_changed = ctk_window_state_flags_changed;
729 widget_class->style_updated = ctk_window_style_updated;
730
731 container_class->remove = ctk_window_remove;
732 container_class->check_resize = ctk_window_check_resize;
733 container_class->forall = ctk_window_forall;
734
735 klass->set_focus = ctk_window_real_set_focus;
736
737 klass->activate_default = ctk_window_real_activate_default;
738 klass->activate_focus = ctk_window_real_activate_focus;
739 klass->keys_changed = ctk_window_keys_changed;
740 klass->enable_debugging = ctk_window_enable_debugging;
741
742 window_props[PROP_TYPE] =
743 g_param_spec_enum ("type",
744 P_("Window Type")g_dgettext("ctk30" "-properties","Window Type"),
745 P_("The type of the window")g_dgettext("ctk30" "-properties","The type of the window"),
746 CTK_TYPE_WINDOW_TYPE(ctk_window_type_get_type ()),
747 CTK_WINDOW_TOPLEVEL,
748 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY);
749
750 window_props[PROP_TITLE] =
751 g_param_spec_string ("title",
752 P_("Window Title")g_dgettext("ctk30" "-properties","Window Title"),
753 P_("The title of the window")g_dgettext("ctk30" "-properties","The title of the window"),
754 NULL((void*)0),
755 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
756
757 window_props[PROP_ROLE] =
758 g_param_spec_string ("role",
759 P_("Window Role")g_dgettext("ctk30" "-properties","Window Role"),
760 P_("Unique identifier for the window to be used when restoring a session")g_dgettext("ctk30" "-properties","Unique identifier for the window to be used when restoring a session"
)
,
761 NULL((void*)0),
762 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
763
764 /**
765 * CtkWindow:startup-id:
766 *
767 * The :startup-id is a write-only property for setting window's
768 * startup notification identifier. See ctk_window_set_startup_id()
769 * for more details.
770 *
771 * Since: 2.12
772 */
773 window_props[PROP_STARTUP_ID] =
774 g_param_spec_string ("startup-id",
775 P_("Startup ID")g_dgettext("ctk30" "-properties","Startup ID"),
776 P_("Unique startup identifier for the window used by startup-notification")g_dgettext("ctk30" "-properties","Unique startup identifier for the window used by startup-notification"
)
,
777 NULL((void*)0),
778 CTK_PARAM_WRITABLEG_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
779
780 window_props[PROP_RESIZABLE] =
781 g_param_spec_boolean ("resizable",
782 P_("Resizable")g_dgettext("ctk30" "-properties","Resizable"),
783 P_("If TRUE, users can resize the window")g_dgettext("ctk30" "-properties","If TRUE, users can resize the window"
)
,
784 TRUE(!(0)),
785 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
786
787 window_props[PROP_MODAL] =
788 g_param_spec_boolean ("modal",
789 P_("Modal")g_dgettext("ctk30" "-properties","Modal"),
790 P_("If TRUE, the window is modal (other windows are not usable while this one is up)")g_dgettext("ctk30" "-properties","If TRUE, the window is modal (other windows are not usable while this one is up)"
)
,
791 FALSE(0),
792 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
793
794 window_props[PROP_WIN_POS] =
795 g_param_spec_enum ("window-position",
796 P_("Window Position")g_dgettext("ctk30" "-properties","Window Position"),
797 P_("The initial position of the window")g_dgettext("ctk30" "-properties","The initial position of the window"
)
,
798 CTK_TYPE_WINDOW_POSITION(ctk_window_position_get_type ()),
799 CTK_WIN_POS_NONE,
800 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
801
802 window_props[PROP_DEFAULT_WIDTH] =
803 g_param_spec_int ("default-width",
804 P_("Default Width")g_dgettext("ctk30" "-properties","Default Width"),
805 P_("The default width of the window, used when initially showing the window")g_dgettext("ctk30" "-properties","The default width of the window, used when initially showing the window"
)
,
806 -1, G_MAXINT2147483647,
807 -1,
808 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
809
810 window_props[PROP_DEFAULT_HEIGHT] =
811 g_param_spec_int ("default-height",
812 P_("Default Height")g_dgettext("ctk30" "-properties","Default Height"),
813 P_("The default height of the window, used when initially showing the window")g_dgettext("ctk30" "-properties","The default height of the window, used when initially showing the window"
)
,
814 -1, G_MAXINT2147483647,
815 -1,
816 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
817
818 window_props[PROP_DESTROY_WITH_PARENT] =
819 g_param_spec_boolean ("destroy-with-parent",
820 P_("Destroy with Parent")g_dgettext("ctk30" "-properties","Destroy with Parent"),
821 P_("If this window should be destroyed when the parent is destroyed")g_dgettext("ctk30" "-properties","If this window should be destroyed when the parent is destroyed"
)
,
822 FALSE(0),
823 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
824
825 /**
826 * CtkWindow:hide-titlebar-when-maximized:
827 *
828 * Whether the titlebar should be hidden during maximization.
829 *
830 * Since: 3.4
831 */
832 window_props[PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED] =
833 g_param_spec_boolean ("hide-titlebar-when-maximized",
834 P_("Hide the titlebar during maximization")g_dgettext("ctk30" "-properties","Hide the titlebar during maximization"
)
,
835 P_("If this window's titlebar should be hidden when the window is maximized")g_dgettext("ctk30" "-properties","If this window's titlebar should be hidden when the window is maximized"
)
,
836 FALSE(0),
837 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
838
839 window_props[PROP_ICON] =
840 g_param_spec_object ("icon",
841 P_("Icon")g_dgettext("ctk30" "-properties","Icon"),
842 P_("Icon for this window")g_dgettext("ctk30" "-properties","Icon for this window"),
843 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()),
844 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
845
846 /**
847 * CtkWindow:mnemonics-visible:
848 *
849 * Whether mnemonics are currently visible in this window.
850 *
851 * This property is maintained by CTK+ based on user input,
852 * and should not be set by applications.
853 *
854 * Since: 2.20
855 */
856 window_props[PROP_MNEMONICS_VISIBLE] =
857 g_param_spec_boolean ("mnemonics-visible",
858 P_("Mnemonics Visible")g_dgettext("ctk30" "-properties","Mnemonics Visible"),
859 P_("Whether mnemonics are currently visible in this window")g_dgettext("ctk30" "-properties","Whether mnemonics are currently visible in this window"
)
,
860 TRUE(!(0)),
861 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
862
863 /**
864 * CtkWindow:focus-visible:
865 *
866 * Whether 'focus rectangles' are currently visible in this window.
867 *
868 * This property is maintained by CTK+ based on user input
869 * and should not be set by applications.
870 *
871 * Since: 2.20
872 */
873 window_props[PROP_FOCUS_VISIBLE] =
874 g_param_spec_boolean ("focus-visible",
875 P_("Focus Visible")g_dgettext("ctk30" "-properties","Focus Visible"),
876 P_("Whether focus rectangles are currently visible in this window")g_dgettext("ctk30" "-properties","Whether focus rectangles are currently visible in this window"
)
,
877 TRUE(!(0)),
878 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
879
880 /**
881 * CtkWindow:icon-name:
882 *
883 * The :icon-name property specifies the name of the themed icon to
884 * use as the window icon. See #CtkIconTheme for more details.
885 *
886 * Since: 2.6
887 */
888 window_props[PROP_ICON_NAME] =
889 g_param_spec_string ("icon-name",
890 P_("Icon Name")g_dgettext("ctk30" "-properties","Icon Name"),
891 P_("Name of the themed icon for this window")g_dgettext("ctk30" "-properties","Name of the themed icon for this window"
)
,
892 NULL((void*)0),
893 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
894
895 window_props[PROP_SCREEN] =
896 g_param_spec_object ("screen",
897 P_("Screen")g_dgettext("ctk30" "-properties","Screen"),
898 P_("The screen where this window will be displayed")g_dgettext("ctk30" "-properties","The screen where this window will be displayed"
)
,
899 CDK_TYPE_SCREEN(cdk_screen_get_type ()),
900 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
901
902 window_props[PROP_IS_ACTIVE] =
903 g_param_spec_boolean ("is-active",
904 P_("Is Active")g_dgettext("ctk30" "-properties","Is Active"),
905 P_("Whether the toplevel is the current active window")g_dgettext("ctk30" "-properties","Whether the toplevel is the current active window"
)
,
906 FALSE(0),
907 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
908
909 window_props[PROP_HAS_TOPLEVEL_FOCUS] =
910 g_param_spec_boolean ("has-toplevel-focus",
911 P_("Focus in Toplevel")g_dgettext("ctk30" "-properties","Focus in Toplevel"),
912 P_("Whether the input focus is within this CtkWindow")g_dgettext("ctk30" "-properties","Whether the input focus is within this CtkWindow"
)
,
913 FALSE(0),
914 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
915
916 window_props[PROP_TYPE_HINT] =
917 g_param_spec_enum ("type-hint",
918 P_("Type hint")g_dgettext("ctk30" "-properties","Type hint"),
919 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it.")g_dgettext("ctk30" "-properties","Hint to help the desktop environment understand what kind of window this is and how to treat it."
)
,
920 CDK_TYPE_WINDOW_TYPE_HINT(cdk_window_type_hint_get_type ()),
921 CDK_WINDOW_TYPE_HINT_NORMAL,
922 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
923
924 window_props[PROP_SKIP_TASKBAR_HINT] =
925 g_param_spec_boolean ("skip-taskbar-hint",
926 P_("Skip taskbar")g_dgettext("ctk30" "-properties","Skip taskbar"),
927 P_("TRUE if the window should not be in the task bar.")g_dgettext("ctk30" "-properties","TRUE if the window should not be in the task bar."
)
,
928 FALSE(0),
929 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
930
931 window_props[PROP_SKIP_PAGER_HINT] =
932 g_param_spec_boolean ("skip-pager-hint",
933 P_("Skip pager")g_dgettext("ctk30" "-properties","Skip pager"),
934 P_("TRUE if the window should not be in the pager.")g_dgettext("ctk30" "-properties","TRUE if the window should not be in the pager."
)
,
935 FALSE(0),
936 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
937
938 window_props[PROP_URGENCY_HINT] =
939 g_param_spec_boolean ("urgency-hint",
940 P_("Urgent")g_dgettext("ctk30" "-properties","Urgent"),
941 P_("TRUE if the window should be brought to the user's attention.")g_dgettext("ctk30" "-properties","TRUE if the window should be brought to the user's attention."
)
,
942 FALSE(0),
943 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
944
945 /**
946 * CtkWindow:accept-focus:
947 *
948 * Whether the window should receive the input focus.
949 *
950 * Since: 2.4
951 */
952 window_props[PROP_ACCEPT_FOCUS] =
953 g_param_spec_boolean ("accept-focus",
954 P_("Accept focus")g_dgettext("ctk30" "-properties","Accept focus"),
955 P_("TRUE if the window should receive the input focus.")g_dgettext("ctk30" "-properties","TRUE if the window should receive the input focus."
)
,
956 TRUE(!(0)),
957 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
958
959 /**
960 * CtkWindow:focus-on-map:
961 *
962 * Whether the window should receive the input focus when mapped.
963 *
964 * Since: 2.6
965 */
966 window_props[PROP_FOCUS_ON_MAP] =
967 g_param_spec_boolean ("focus-on-map",
968 P_("Focus on map")g_dgettext("ctk30" "-properties","Focus on map"),
969 P_("TRUE if the window should receive the input focus when mapped.")g_dgettext("ctk30" "-properties","TRUE if the window should receive the input focus when mapped."
)
,
970 TRUE(!(0)),
971 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
972
973 /**
974 * CtkWindow:decorated:
975 *
976 * Whether the window should be decorated by the window manager.
977 *
978 * Since: 2.4
979 */
980 window_props[PROP_DECORATED] =
981 g_param_spec_boolean ("decorated",
982 P_("Decorated")g_dgettext("ctk30" "-properties","Decorated"),
983 P_("Whether the window should be decorated by the window manager")g_dgettext("ctk30" "-properties","Whether the window should be decorated by the window manager"
)
,
984 TRUE(!(0)),
985 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
986
987 /**
988 * CtkWindow:deletable:
989 *
990 * Whether the window frame should have a close button.
991 *
992 * Since: 2.10
993 */
994 window_props[PROP_DELETABLE] =
995 g_param_spec_boolean ("deletable",
996 P_("Deletable")g_dgettext("ctk30" "-properties","Deletable"),
997 P_("Whether the window frame should have a close button")g_dgettext("ctk30" "-properties","Whether the window frame should have a close button"
)
,
998 TRUE(!(0)),
999 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1000
1001 /**
1002 * CtkWindow:has-resize-grip:
1003 *
1004 * Whether the window has a corner resize grip.
1005 *
1006 * Note that the resize grip is only shown if the window is
1007 * actually resizable and not maximized. Use
1008 * #CtkWindow:resize-grip-visible to find out if the resize
1009 * grip is currently shown.
1010 *
1011 * Deprecated: 3.14: Resize grips have been removed.
1012 *
1013 * Since: 3.0
1014 */
1015 window_props[PROP_HAS_RESIZE_GRIP] =
1016 g_param_spec_boolean ("has-resize-grip",
1017 P_("Resize grip")g_dgettext("ctk30" "-properties","Resize grip"),
1018 P_("Specifies whether the window should have a resize grip")g_dgettext("ctk30" "-properties","Specifies whether the window should have a resize grip"
)
,
1019 FALSE(0),
1020 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED);
1021
1022 /**
1023 * CtkWindow:resize-grip-visible:
1024 *
1025 * Whether a corner resize grip is currently shown.
1026 *
1027 * Deprecated: 3.14: Resize grips have been removed.
1028 *
1029 * Since: 3.0
1030 */
1031 window_props[PROP_RESIZE_GRIP_VISIBLE] =
1032 g_param_spec_boolean ("resize-grip-visible",
1033 P_("Resize grip is visible")g_dgettext("ctk30" "-properties","Resize grip is visible"),
1034 P_("Specifies whether the window's resize grip is visible.")g_dgettext("ctk30" "-properties","Specifies whether the window's resize grip is visible."
)
,
1035 FALSE(0),
1036 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED);
1037
1038 /**
1039 * CtkWindow:gravity:
1040 *
1041 * The window gravity of the window. See ctk_window_move() and #CdkGravity for
1042 * more details about window gravity.
1043 *
1044 * Since: 2.4
1045 */
1046 window_props[PROP_GRAVITY] =
1047 g_param_spec_enum ("gravity",
1048 P_("Gravity")g_dgettext("ctk30" "-properties","Gravity"),
1049 P_("The window gravity of the window")g_dgettext("ctk30" "-properties","The window gravity of the window"
)
,
1050 CDK_TYPE_GRAVITY(cdk_gravity_get_type ()),
1051 CDK_GRAVITY_NORTH_WEST,
1052 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY);
1053
1054 /**
1055 * CtkWindow:transient-for:
1056 *
1057 * The transient parent of the window. See ctk_window_set_transient_for() for
1058 * more details about transient windows.
1059 *
1060 * Since: 2.10
1061 */
1062 window_props[PROP_TRANSIENT_FOR] =
1063 g_param_spec_object ("transient-for",
1064 P_("Transient for Window")g_dgettext("ctk30" "-properties","Transient for Window"),
1065 P_("The transient parent of the dialog")g_dgettext("ctk30" "-properties","The transient parent of the dialog"
)
,
1066 CTK_TYPE_WINDOW(ctk_window_get_type ()),
1067 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY);
1068
1069 /**
1070 * CtkWindow:attached-to:
1071 *
1072 * The widget to which this window is attached.
1073 * See ctk_window_set_attached_to().
1074 *
1075 * Examples of places where specifying this relation is useful are
1076 * for instance a #CtkMenu created by a #CtkComboBox, a completion
1077 * popup window created by #CtkEntry or a typeahead search entry
1078 * created by #CtkTreeView.
1079 *
1080 * Since: 3.4
1081 */
1082 window_props[PROP_ATTACHED_TO] =
1083 g_param_spec_object ("attached-to",
1084 P_("Attached to Widget")g_dgettext("ctk30" "-properties","Attached to Widget"),
1085 P_("The widget where the window is attached")g_dgettext("ctk30" "-properties","The widget where the window is attached"
)
,
1086 CTK_TYPE_WIDGET(ctk_widget_get_type ()),
1087 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY);
1088
1089 window_props[PROP_IS_MAXIMIZED] =
1090 g_param_spec_boolean ("is-maximized",
1091 P_("Is maximized")g_dgettext("ctk30" "-properties","Is maximized"),
1092 P_("Whether the window is maximized")g_dgettext("ctk30" "-properties","Whether the window is maximized"
)
,
1093 FALSE(0),
1094 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB);
1095
1096 /**
1097 * CtkWindow:application:
1098 *
1099 * The #CtkApplication associated with the window.
1100 *
1101 * The application will be kept alive for at least as long as it
1102 * has any windows associated with it (see g_application_hold()
1103 * for a way to keep it alive without windows).
1104 *
1105 * Normally, the connection between the application and the window
1106 * will remain until the window is destroyed, but you can explicitly
1107 * remove it by setting the :application property to %NULL.
1108 *
1109 * Since: 3.0
1110 */
1111 window_props[PROP_APPLICATION] =
1112 g_param_spec_object ("application",
1113 P_("CtkApplication")g_dgettext("ctk30" "-properties","CtkApplication"),
1114 P_("The CtkApplication for the window")g_dgettext("ctk30" "-properties","The CtkApplication for the window"
)
,
1115 CTK_TYPE_APPLICATION(ctk_application_get_type ()),
1116 CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
|G_PARAM_EXPLICIT_NOTIFY);
1117
1118 g_object_class_install_properties (gobject_class, LAST_ARG, window_props);
1119
1120 /* Style properties.
1121 */
1122 ctk_widget_class_install_style_property (widget_class,
1123 g_param_spec_string ("decoration-button-layout",
1124 P_("Decorated button layout")g_dgettext("ctk30" "-properties","Decorated button layout"),
1125 P_("Decorated button layout")g_dgettext("ctk30" "-properties","Decorated button layout"),
1126 "menu:close",
1127 CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_DEPRECATED));
1128
1129 ctk_widget_class_install_style_property (widget_class,
1130 g_param_spec_int ("decoration-resize-handle",
1131 P_("Decoration resize handle size")g_dgettext("ctk30" "-properties","Decoration resize handle size"
)
,
1132 P_("Decoration resize handle size")g_dgettext("ctk30" "-properties","Decoration resize handle size"
)
,
1133 0, G_MAXINT2147483647,
1134 20, CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
1135
1136 /**
1137 * CtkWindow::set-focus:
1138 * @window: the window which received the signal
1139 * @widget: (nullable): the newly focused widget (or %NULL for no focus)
1140 *
1141 * This signal is emitted whenever the currently focused widget in
1142 * this window changes.
1143 *
1144 * Since: 2.24
1145 */
1146 window_signals[SET_FOCUS] =
1147 g_signal_new (I_("set-focus")g_intern_static_string ("set-focus"),
1148 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1149 G_SIGNAL_RUN_LAST,
1150 G_STRUCT_OFFSET (CtkWindowClass, set_focus)((glong) __builtin_offsetof(CtkWindowClass, set_focus)),
1151 NULL((void*)0), NULL((void*)0),
1152 NULL((void*)0),
1153 G_TYPE_NONE((GType) ((1) << (2))), 1,
1154 CTK_TYPE_WIDGET(ctk_widget_get_type ()));
1155
1156 /**
1157 * CtkWindow::activate-focus:
1158 * @window: the window which received the signal
1159 *
1160 * The ::activate-focus signal is a
1161 * [keybinding signal][CtkBindingSignal]
1162 * which gets emitted when the user activates the currently
1163 * focused widget of @window.
1164 */
1165 window_signals[ACTIVATE_FOCUS] =
1166 g_signal_new (I_("activate-focus")g_intern_static_string ("activate-focus"),
1167 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1168 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1169 G_STRUCT_OFFSET (CtkWindowClass, activate_focus)((glong) __builtin_offsetof(CtkWindowClass, activate_focus)),
1170 NULL((void*)0), NULL((void*)0),
1171 NULL((void*)0),
1172 G_TYPE_NONE((GType) ((1) << (2))),
1173 0);
1174
1175 /**
1176 * CtkWindow::activate-default:
1177 * @window: the window which received the signal
1178 *
1179 * The ::activate-default signal is a
1180 * [keybinding signal][CtkBindingSignal]
1181 * which gets emitted when the user activates the default widget
1182 * of @window.
1183 */
1184 window_signals[ACTIVATE_DEFAULT] =
1185 g_signal_new (I_("activate-default")g_intern_static_string ("activate-default"),
1186 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1187 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1188 G_STRUCT_OFFSET (CtkWindowClass, activate_default)((glong) __builtin_offsetof(CtkWindowClass, activate_default)
)
,
1189 NULL((void*)0), NULL((void*)0),
1190 NULL((void*)0),
1191 G_TYPE_NONE((GType) ((1) << (2))),
1192 0);
1193
1194 /**
1195 * CtkWindow::keys-changed:
1196 * @window: the window which received the signal
1197 *
1198 * The ::keys-changed signal gets emitted when the set of accelerators
1199 * or mnemonics that are associated with @window changes.
1200 */
1201 window_signals[KEYS_CHANGED] =
1202 g_signal_new (I_("keys-changed")g_intern_static_string ("keys-changed"),
1203 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1204 G_SIGNAL_RUN_FIRST,
1205 G_STRUCT_OFFSET (CtkWindowClass, keys_changed)((glong) __builtin_offsetof(CtkWindowClass, keys_changed)),
1206 NULL((void*)0), NULL((void*)0),
1207 NULL((void*)0),
1208 G_TYPE_NONE((GType) ((1) << (2))),
1209 0);
1210
1211 /**
1212 * CtkWindow::enable-debugging:
1213 * @window: the window on which the signal is emitted
1214 * @toggle: toggle the debugger
1215 *
1216 * The ::enable-debugging signal is a [keybinding signal][CtkBindingSignal]
1217 * which gets emitted when the user enables or disables interactive
1218 * debugging. When @toggle is %TRUE, interactive debugging is toggled
1219 * on or off, when it is %FALSE, the debugger will be pointed at the
1220 * widget under the pointer.
1221 *
1222 * The default bindings for this signal are Ctrl-Shift-I
1223 * and Ctrl-Shift-D.
1224 *
1225 * Return: %TRUE if the key binding was handled
1226 */
1227 window_signals[ENABLE_DEBUGGING] =
1228 g_signal_new (I_("enable-debugging")g_intern_static_string ("enable-debugging"),
1229 G_TYPE_FROM_CLASS (gobject_class)(((GTypeClass*) (gobject_class))->g_type),
1230 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1231 G_STRUCT_OFFSET (CtkWindowClass, enable_debugging)((glong) __builtin_offsetof(CtkWindowClass, enable_debugging)
)
,
1232 NULL((void*)0), NULL((void*)0),
1233 _ctk_marshal_BOOLEAN__BOOLEAN,
1234 G_TYPE_BOOLEAN((GType) ((5) << (2))),
1235 1, G_TYPE_BOOLEAN((GType) ((5) << (2))));
1236
1237 /*
1238 * Key bindings
1239 */
1240
1241 binding_set = ctk_binding_set_by_class (klass);
1242
1243 ctk_binding_entry_add_signal (binding_set, CDK_KEY_space0x020, 0,
1244 "activate-focus", 0);
1245 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Space0xff80, 0,
1246 "activate-focus", 0);
1247
1248 ctk_binding_entry_add_signal (binding_set, CDK_KEY_Return0xff0d, 0,
1249 "activate-default", 0);
1250 ctk_binding_entry_add_signal (binding_set, CDK_KEY_ISO_Enter0xfe34, 0,
1251 "activate-default", 0);
1252 ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Enter0xff8d, 0,
1253 "activate-default", 0);
1254
1255 ctk_binding_entry_add_signal (binding_set, CDK_KEY_I0x049, CDK_CONTROL_MASK|CDK_SHIFT_MASK,
1256 "enable-debugging", 1,
1257 G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0));
1258 ctk_binding_entry_add_signal (binding_set, CDK_KEY_D0x044, CDK_CONTROL_MASK|CDK_SHIFT_MASK,
1259 "enable-debugging", 1,
1260 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)));
1261
1262 add_arrow_bindings (binding_set, CDK_KEY_Up0xff52, CTK_DIR_UP);
1263 add_arrow_bindings (binding_set, CDK_KEY_Down0xff54, CTK_DIR_DOWN);
1264 add_arrow_bindings (binding_set, CDK_KEY_Left0xff51, CTK_DIR_LEFT);
1265 add_arrow_bindings (binding_set, CDK_KEY_Right0xff53, CTK_DIR_RIGHT);
1266
1267 add_tab_bindings (binding_set, 0, CTK_DIR_TAB_FORWARD);
1268 add_tab_bindings (binding_set, CDK_CONTROL_MASK, CTK_DIR_TAB_FORWARD);
1269 add_tab_bindings (binding_set, CDK_SHIFT_MASK, CTK_DIR_TAB_BACKWARD);
1270 add_tab_bindings (binding_set, CDK_CONTROL_MASK | CDK_SHIFT_MASK, CTK_DIR_TAB_BACKWARD);
1271
1272 ctk_widget_class_set_accessible_type (widget_class, CTK_TYPE_WINDOW_ACCESSIBLE(ctk_window_accessible_get_type ()));
1273 ctk_widget_class_set_css_name (widget_class, "window");
1274}
1275
1276/**
1277 * ctk_window_is_maximized:
1278 * @window: a #CtkWindow
1279 *
1280 * Retrieves the current maximized state of @window.
1281 *
1282 * Note that since maximization is ultimately handled by the window
1283 * manager and happens asynchronously to an application request, you
1284 * shouldn’t assume the return value of this function changing
1285 * immediately (or at all), as an effect of calling
1286 * ctk_window_maximize() or ctk_window_unmaximize().
1287 *
1288 * Returns: whether the window has a maximized state.
1289 *
1290 * Since: 3.12
1291 */
1292gboolean
1293ctk_window_is_maximized (CtkWindow *window)
1294{
1295 CtkWindowPrivate *priv = window->priv;
1296
1297 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
1298
1299 return priv->maximized;
1300}
1301
1302void
1303_ctk_window_toggle_maximized (CtkWindow *window)
1304{
1305 CtkWindowPrivate *priv = window->priv;
1306
1307 if (priv->maximized)
1308 ctk_window_unmaximize (window);
1309 else
1310 ctk_window_maximize (window);
1311}
1312
1313static gboolean
1314send_delete_event (gpointer data)
1315{
1316 CtkWidget *window = data;
1317 CtkWindowPrivate *priv = CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
->priv;
1318 CdkWindow *cdk_window;
1319
1320 priv->delete_event_handler = 0;
1321
1322 cdk_window = _ctk_widget_get_window (window);
1323 if (cdk_window)
1324 {
1325 CdkEvent *event;
1326
1327 event = cdk_event_new (CDK_DELETE);
1328 event->any.window = g_object_ref (cdk_window)((__typeof__ (cdk_window)) (g_object_ref) (cdk_window));
1329 event->any.send_event = TRUE(!(0));
1330
1331 ctk_main_do_event (event);
1332
1333 cdk_event_free (event);
1334 }
1335
1336 return G_SOURCE_REMOVE(0);
1337}
1338
1339/**
1340 * ctk_window_close:
1341 * @window: a #CtkWindow
1342 *
1343 * Requests that the window is closed, similar to what happens
1344 * when a window manager close button is clicked.
1345 *
1346 * This function can be used with close buttons in custom
1347 * titlebars.
1348 *
1349 * Since: 3.10
1350 */
1351void
1352ctk_window_close (CtkWindow *window)
1353{
1354 if (!_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
1355 return;
1356
1357 window->priv->delete_event_handler = cdk_threads_add_idle_full (G_PRIORITY_DEFAULT0, send_delete_event, window, NULL((void*)0));
1358 g_source_set_name_by_id (window->priv->delete_event_handler, "[ctk+] send_delete_event");
1359}
1360
1361static void
1362popover_destroy (CtkWindowPopover *popover)
1363{
1364 if (popover->unmap_id)
1365 {
1366 g_signal_handler_disconnect (popover->widget, popover->unmap_id);
1367 popover->unmap_id = 0;
1368 }
1369
1370 if (popover->widget && _ctk_widget_get_parent (popover->widget))
1371 ctk_widget_unparent (popover->widget);
1372
1373 if (popover->window)
1374 cdk_window_destroy (popover->window);
1375
1376 g_free (popover);
1377}
1378
1379static gboolean
1380ctk_window_titlebar_action (CtkWindow *window,
1381 const CdkEvent *event,
1382 guint button,
1383 gint n_press)
1384{
1385 CtkSettings *settings;
1386 gchar *action = NULL((void*)0);
1387 gboolean retval = TRUE(!(0));
1388
1389 settings = ctk_widget_get_settings (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
1390 switch (button)
1391 {
1392 case CDK_BUTTON_PRIMARY(1):
1393 if (n_press == 2)
1394 g_object_get (settings, "ctk-titlebar-double-click", &action, NULL((void*)0));
1395 break;
1396 case CDK_BUTTON_MIDDLE(2):
1397 g_object_get (settings, "ctk-titlebar-middle-click", &action, NULL((void*)0));
1398 break;
1399 case CDK_BUTTON_SECONDARY(3):
1400 g_object_get (settings, "ctk-titlebar-right-click", &action, NULL((void*)0));
1401 break;
1402 }
1403
1404 if (action == NULL((void*)0))
1405 retval = FALSE(0);
1406 else if (g_str_equal (action, "none")(strcmp ((const char *) (action), (const char *) ("none")) ==
0)
)
1407 retval = FALSE(0);
1408 /* treat all maximization variants the same */
1409 else if (g_str_has_prefix (action, "toggle-maximize")(__builtin_constant_p ("toggle-maximize")? __extension__ ({ const
char * const __str = (action); const char * const __prefix =
("toggle-maximize"); gboolean __result = (0); if (__str == (
(void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix
) (__str, __prefix); else { const size_t __str_len = strlen (
((__str) + !(__str))); const size_t __prefix_len = strlen (((
__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (action, "toggle-maximize"
) )
)
1410 {
1411 /*
1412 * ctk header bar won't show the maximize button if the following
1413 * properties are not met, apply the same to title bar actions for
1414 * consistency.
1415 */
1416 if (ctk_window_get_resizable (window) &&
1417 ctk_window_get_type_hint (window) == CDK_WINDOW_TYPE_HINT_NORMAL)
1418 _ctk_window_toggle_maximized (window);
1419 }
1420 else if (g_str_equal (action, "lower")(strcmp ((const char *) (action), (const char *) ("lower")) ==
0)
)
1421 cdk_window_lower (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
1422 else if (g_str_equal (action, "minimize")(strcmp ((const char *) (action), (const char *) ("minimize")
) == 0)
)
1423 cdk_window_iconify (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
1424 else if (g_str_equal (action, "menu")(strcmp ((const char *) (action), (const char *) ("menu")) ==
0)
)
1425 ctk_window_do_popup (window, (CdkEventButton*) event);
1426 else
1427 {
1428 g_warning ("Unsupported titlebar action %s", action);
1429 retval = FALSE(0);
1430 }
1431
1432 g_free (action);
1433
1434 return retval;
1435}
1436
1437static void
1438multipress_gesture_pressed_cb (CtkGestureMultiPress *gesture,
1439 gint n_press,
1440 gdouble x,
1441 gdouble y,
1442 CtkWindow *window)
1443{
1444 CtkWidget *event_widget, *widget;
1445 CdkEventSequence *sequence;
1446 CtkWindowRegion region;
1447 CtkWindowPrivate *priv;
1448 const CdkEvent *event;
1449 guint button;
1450 gboolean window_drag = FALSE(0);
1451
1452 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
1453 priv = ctk_window_get_instance_private (window);
1454 sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
1455 button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
1456 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence);
1457
1458 if (!event)
1459 return;
1460
1461 if (n_press > 1)
1462 ctk_gesture_set_state (priv->drag_gesture, CTK_EVENT_SEQUENCE_DENIED);
1463
1464 region = get_active_region_type (window, (CdkEventAny*) event, x, y);
1465
1466 if (cdk_display_device_is_grabbed (ctk_widget_get_display (widget),
1467 ctk_gesture_get_device (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
)))
1468 {
1469 ctk_gesture_set_state (priv->drag_gesture, CTK_EVENT_SEQUENCE_DENIED);
1470 return;
1471 }
1472
1473 if (button == CDK_BUTTON_SECONDARY(3) && region == CTK_WINDOW_REGION_TITLE)
1474 {
1475 if (ctk_window_titlebar_action (window, event, button, n_press))
1476 ctk_gesture_set_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
,
1477 sequence, CTK_EVENT_SEQUENCE_CLAIMED);
1478
1479 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
);
1480 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (priv->drag_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->drag_gesture)), ((ctk_event_controller_get_type
()))))))
);
1481 return;
1482 }
1483 else if (button == CDK_BUTTON_MIDDLE(2) && region == CTK_WINDOW_REGION_TITLE)
1484 {
1485 if (ctk_window_titlebar_action (window, event, button, n_press))
1486 ctk_gesture_set_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
,
1487 sequence, CTK_EVENT_SEQUENCE_CLAIMED);
1488 return;
1489 }
1490 else if (button != CDK_BUTTON_PRIMARY(1))
1491 return;
1492
1493 event_widget = ctk_get_event_widget ((CdkEvent *) event);
1494
1495 if (region == CTK_WINDOW_REGION_TITLE)
1496 cdk_window_raise (_ctk_widget_get_window (widget));
1497
1498 switch (region)
1499 {
1500 case CTK_WINDOW_REGION_CONTENT:
1501 if (event_widget != widget)
1502 ctk_widget_style_get (event_widget, "window-dragging", &window_drag, NULL((void*)0));
1503
1504 if (!window_drag)
1505 {
1506 ctk_gesture_set_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
,
1507 sequence, CTK_EVENT_SEQUENCE_DENIED);
1508 return;
1509 }
1510 /* fall through */
1511
1512 case CTK_WINDOW_REGION_TITLE:
1513 if (n_press == 2)
1514 ctk_window_titlebar_action (window, event, button, n_press);
1515
1516 if (ctk_widget_has_grab (widget))
1517 ctk_gesture_set_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
,
1518 sequence, CTK_EVENT_SEQUENCE_CLAIMED);
1519 break;
1520 default:
1521 if (!priv->maximized)
1522 {
1523 gdouble x_root, y_root;
1524
1525 ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, CTK_EVENT_SEQUENCE_CLAIMED);
1526
1527 cdk_event_get_root_coords (event, &x_root, &y_root);
1528 cdk_window_begin_resize_drag_for_device (_ctk_widget_get_window (widget),
1529 (CdkWindowEdge) region,
1530 cdk_event_get_device ((CdkEvent *) event),
1531 CDK_BUTTON_PRIMARY(1),
1532 x_root, y_root,
1533 cdk_event_get_time (event));
1534
1535 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
);
1536 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (priv->drag_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->drag_gesture)), ((ctk_event_controller_get_type
()))))))
);
1537 }
1538
1539 break;
1540 }
1541}
1542
1543static void
1544drag_gesture_begin_cb (CtkGestureDrag *gesture,
1545 gdouble x,
1546 gdouble y,
1547 CtkWindow *window)
1548{
1549 CdkEventSequence *sequence;
1550 CtkWindowRegion region;
1551 CtkWidget *event_widget;
1552 gboolean widget_drag;
1553 const CdkEvent *event;
1554
1555 sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
1556 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence);
1557
1558 if (!event)
1559 return;
1560
1561 region = get_active_region_type (window, (CdkEventAny*) event, x, y);
1562
1563 switch (region)
1564 {
1565 case CTK_WINDOW_REGION_TITLE:
1566 /* Claim it */
1567 break;
1568 case CTK_WINDOW_REGION_CONTENT:
1569 event_widget = ctk_get_event_widget ((CdkEvent *) event);
1570
1571 ctk_widget_style_get (event_widget, "window-dragging", &widget_drag, NULL((void*)0));
1572
1573 if (!widget_drag)
1574 ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, CTK_EVENT_SEQUENCE_DENIED);
1575
1576 break;
1577 default:
1578 ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, CTK_EVENT_SEQUENCE_DENIED);
1579 }
1580}
1581
1582static void
1583drag_gesture_update_cb (CtkGestureDrag *gesture,
1584 gdouble offset_x,
1585 gdouble offset_y,
1586 CtkWindow *window)
1587{
1588 CtkWindowPrivate *priv = window->priv;
1589 gint double_click_distance;
1590 CtkSettings *settings;
1591
1592 settings = ctk_widget_get_settings (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
1593 g_object_get (settings,
1594 "ctk-double-click-distance", &double_click_distance,
1595 NULL((void*)0));
1596
1597 if (ABS (offset_x)(((offset_x) < 0) ? -(offset_x) : (offset_x)) > double_click_distance ||
1598 ABS (offset_y)(((offset_y) < 0) ? -(offset_y) : (offset_y)) > double_click_distance)
1599 {
1600 CdkEventSequence *sequence;
1601 gdouble start_x, start_y;
1602 gint x_root, y_root;
1603 const CdkEvent *event;
1604 CtkWidget *event_widget;
1605
1606 sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
);
1607 event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, sequence);
1608 event_widget = ctk_get_event_widget ((CdkEvent *) event);
1609
1610 /* Check whether the target widget should be left alone at handling
1611 * the sequence, this is better done late to give room for gestures
1612 * there to go denied.
1613 *
1614 * Besides claiming gestures, we must bail out too if there's gestures
1615 * in the "none" state at this point, as those are still handling events
1616 * and can potentially go claimed, and we don't want to stop the target
1617 * widget from doing anything.
1618 */
1619 if (event_widget != CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
&&
1620 !ctk_widget_has_grab (event_widget) &&
1621 _ctk_widget_consumes_motion (event_widget, sequence))
1622 {
1623 ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, CTK_EVENT_SEQUENCE_DENIED);
1624 return;
1625 }
1626
1627 ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
, CTK_EVENT_SEQUENCE_CLAIMED);
1628
1629 ctk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
1630 cdk_window_get_root_coords (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
1631 start_x, start_y, &x_root, &y_root);
1632
1633 cdk_window_begin_move_drag_for_device (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
1634 ctk_gesture_get_device (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gesture)), ((ctk_gesture_get_type ()))))))
),
1635 ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type ()
))))))
),
1636 x_root, y_root,
1637 ctk_get_current_event_time ());
1638
1639 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
);
1640 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (priv->multipress_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->multipress_gesture)), ((ctk_event_controller_get_type
()))))))
);
1641 }
1642}
1643
1644static void
1645node_style_changed_cb (CtkCssNode *node G_GNUC_UNUSED__attribute__ ((__unused__)),
1646 CtkCssStyleChange *change,
1647 CtkWidget *widget)
1648{
1649 if (ctk_css_style_change_affects (change, CTK_CSS_AFFECTS_SIZE | CTK_CSS_AFFECTS_CLIP))
1650 ctk_widget_queue_resize (widget);
1651 else
1652 ctk_widget_queue_draw (widget);
1653}
1654
1655static void
1656ctk_window_init (CtkWindow *window)
1657{
1658 CtkWindowPrivate *priv;
1659 CtkWidget *widget;
1660 CtkCssNode *widget_node;
1661
1662 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
1663
1664 window->priv = ctk_window_get_instance_private (window);
1665 priv = window->priv;
1666
1667 ctk_widget_set_has_window (widget, TRUE(!(0)));
1668 _ctk_widget_set_is_toplevel (widget, TRUE(!(0)));
1669 _ctk_widget_set_anchored (widget, TRUE(!(0)));
1670
1671 ctk_container_set_default_resize_mode (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, CTK_RESIZE_QUEUE);
1672
1673 priv->title = NULL((void*)0);
1674 priv->wmclass_name = g_strdup (g_get_prgname ())g_strdup_inline (g_get_prgname ());
1675 priv->wmclass_class = g_strdup (cdk_get_program_class ())g_strdup_inline (cdk_get_program_class ());
1676 priv->wm_role = NULL((void*)0);
1677 priv->geometry_info = NULL((void*)0);
1678 priv->type = CTK_WINDOW_TOPLEVEL;
1679 priv->focus_widget = NULL((void*)0);
1680 priv->default_widget = NULL((void*)0);
1681 priv->configure_request_count = 0;
1682 priv->resizable = TRUE(!(0));
1683 priv->configure_notify_received = FALSE(0);
1684 priv->position = CTK_WIN_POS_NONE;
1685 priv->need_default_size = TRUE(!(0));
1686 priv->need_default_position = TRUE(!(0));
1687 priv->modal = FALSE(0);
1688 priv->gravity = CDK_GRAVITY_NORTH_WEST;
1689 priv->decorated = TRUE(!(0));
1690 priv->mnemonic_modifier = CDK_MOD1_MASK;
1691 priv->screen = cdk_screen_get_default ();
1692
1693 priv->accept_focus = TRUE(!(0));
1694 priv->focus_on_map = TRUE(!(0));
1695 priv->deletable = TRUE(!(0));
1696 priv->type_hint = CDK_WINDOW_TYPE_HINT_NORMAL;
1697 priv->startup_id = NULL((void*)0);
1698 priv->initial_timestamp = CDK_CURRENT_TIME0L;
1699 priv->mnemonics_visible = TRUE(!(0));
1700 priv->focus_visible = TRUE(!(0));
1701 priv->initial_fullscreen_monitor = -1;
1702
1703 g_object_ref_sink (window)((__typeof__ (window)) (g_object_ref_sink) (window));
1704 priv->has_user_ref_count = TRUE(!(0));
1705 toplevel_list = g_slist_prepend (toplevel_list, window);
1706 ctk_window_update_debugging ();
1707
1708 if (priv->screen)
1709 {
1710 g_signal_connect (priv->screen, "composited-changed",g_signal_connect_data ((priv->screen), ("composited-changed"
), (((GCallback) (ctk_window_on_composited_changed))), (window
), ((void*)0), (GConnectFlags) 0)
1711 G_CALLBACK (ctk_window_on_composited_changed), window)g_signal_connect_data ((priv->screen), ("composited-changed"
), (((GCallback) (ctk_window_on_composited_changed))), (window
), ((void*)0), (GConnectFlags) 0)
;
1712
1713#ifdef CDK_WINDOWING_X11
1714 g_signal_connect (ctk_settings_get_for_screen (priv->screen),g_signal_connect_data ((ctk_settings_get_for_screen (priv->
screen)), ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
1715 "notify::ctk-application-prefer-dark-theme",g_signal_connect_data ((ctk_settings_get_for_screen (priv->
screen)), ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
1716 G_CALLBACK (ctk_window_on_theme_variant_changed), window)g_signal_connect_data ((ctk_settings_get_for_screen (priv->
screen)), ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
;
1717#endif
1718 }
1719
1720 widget_node = ctk_widget_get_css_node (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
1721 priv->decoration_node = ctk_css_node_new ();
1722 ctk_css_node_set_name (priv->decoration_node, I_("decoration")g_intern_static_string ("decoration"));
1723 ctk_css_node_set_parent (priv->decoration_node, widget_node);
1724 ctk_css_node_set_state (priv->decoration_node, ctk_css_node_get_state (widget_node));
1725 g_signal_connect_object (priv->decoration_node, "style-changed", G_CALLBACK (node_style_changed_cb)((GCallback) (node_style_changed_cb)), window, 0);
1726 g_object_unref (priv->decoration_node);
1727
1728 ctk_css_node_add_class (widget_node, g_quark_from_static_string (CTK_STYLE_CLASS_BACKGROUND"background"));
1729
1730 priv->scale = ctk_widget_get_scale_factor (widget);
1731
1732#ifdef CDK_WINDOWING_X11
1733 ctk_drag_dest_set (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
,
1734 CTK_DEST_DEFAULT_MOTION | CTK_DEST_DEFAULT_DROP,
1735 dnd_dest_targets, G_N_ELEMENTS (dnd_dest_targets)(sizeof (dnd_dest_targets) / sizeof ((dnd_dest_targets)[0])),
1736 CDK_ACTION_MOVE);
1737#endif
1738}
1739
1740static void
1741ctk_window_constructed (GObject *object)
1742{
1743 CtkWindow *window = CTK_WINDOW (object)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_window_get_type ()))))))
;
1744 CtkWindowPrivate *priv = window->priv;
1745 gboolean is_plug;
1746
1747 G_OBJECT_CLASS (ctk_window_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), (((GType) ((20) << (2))
))))))
->constructed (object);
1748
1749#ifdef CDK_WINDOWING_X11
1750 is_plug = CTK_IS_PLUG (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((ctk_plug_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
;
1751#else
1752 is_plug = FALSE(0);
1753#endif
1754
1755 if (priv->type == CTK_WINDOW_TOPLEVEL && !is_plug)
1756 {
1757 priv->multipress_gesture = ctk_gesture_multi_press_new (CTK_WIDGET (object)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_widget_get_type ()))))))
);
1758 ctk_gesture_single_set_button (CTK_GESTURE_SINGLE (priv->multipress_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((priv->multipress_gesture)), ((ctk_gesture_single_get_type
()))))))
, 0);
1759 ctk_event_controller_set_propagation_phase (CTK_EVENT_CONTROLLER (priv->multipress_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->multipress_gesture)), ((ctk_event_controller_get_type
()))))))
,
1760 CTK_PHASE_NONE);
1761 g_signal_connect (priv->multipress_gesture, "pressed",g_signal_connect_data ((priv->multipress_gesture), ("pressed"
), (((GCallback) (multipress_gesture_pressed_cb))), (object),
((void*)0), (GConnectFlags) 0)
1762 G_CALLBACK (multipress_gesture_pressed_cb), object)g_signal_connect_data ((priv->multipress_gesture), ("pressed"
), (((GCallback) (multipress_gesture_pressed_cb))), (object),
((void*)0), (GConnectFlags) 0)
;
1763
1764 priv->drag_gesture = ctk_gesture_drag_new (CTK_WIDGET (object)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_widget_get_type ()))))))
);
1765 ctk_event_controller_set_propagation_phase (CTK_EVENT_CONTROLLER (priv->drag_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((priv->drag_gesture)), ((ctk_event_controller_get_type
()))))))
,
1766 CTK_PHASE_CAPTURE);
1767 g_signal_connect (priv->drag_gesture, "drag-begin",g_signal_connect_data ((priv->drag_gesture), ("drag-begin"
), (((GCallback) (drag_gesture_begin_cb))), (object), ((void*
)0), (GConnectFlags) 0)
1768 G_CALLBACK (drag_gesture_begin_cb), object)g_signal_connect_data ((priv->drag_gesture), ("drag-begin"
), (((GCallback) (drag_gesture_begin_cb))), (object), ((void*
)0), (GConnectFlags) 0)
;
1769 g_signal_connect (priv->drag_gesture, "drag-update",g_signal_connect_data ((priv->drag_gesture), ("drag-update"
), (((GCallback) (drag_gesture_update_cb))), (object), ((void
*)0), (GConnectFlags) 0)
1770 G_CALLBACK (drag_gesture_update_cb), object)g_signal_connect_data ((priv->drag_gesture), ("drag-update"
), (((GCallback) (drag_gesture_update_cb))), (object), ((void
*)0), (GConnectFlags) 0)
;
1771 }
1772}
1773
1774static void
1775ctk_window_set_property (GObject *object,
1776 guint prop_id,
1777 const GValue *value,
1778 GParamSpec *pspec)
1779{
1780 CtkWindow *window = CTK_WINDOW (object)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_window_get_type ()))))))
;
1781 CtkWindowPrivate *priv = window->priv;
1782
1783 switch (prop_id)
1784 {
1785 case PROP_TYPE:
1786 priv->type = g_value_get_enum (value);
1787 break;
1788 case PROP_TITLE:
1789 ctk_window_set_title (window, g_value_get_string (value));
1790 break;
1791 case PROP_ROLE:
1792 ctk_window_set_role (window, g_value_get_string (value));
1793 break;
1794 case PROP_STARTUP_ID:
1795 ctk_window_set_startup_id (window, g_value_get_string (value));
1796 break;
1797 case PROP_RESIZABLE:
1798 ctk_window_set_resizable (window, g_value_get_boolean (value));
1799 break;
1800 case PROP_MODAL:
1801 ctk_window_set_modal (window, g_value_get_boolean (value));
1802 break;
1803 case PROP_WIN_POS:
1804 ctk_window_set_position (window, g_value_get_enum (value));
1805 break;
1806 case PROP_DEFAULT_WIDTH:
1807 ctk_window_set_default_size_internal (window,
1808 TRUE(!(0)), g_value_get_int (value),
1809 FALSE(0), -1, FALSE(0));
1810 break;
1811 case PROP_DEFAULT_HEIGHT:
1812 ctk_window_set_default_size_internal (window,
1813 FALSE(0), -1,
1814 TRUE(!(0)), g_value_get_int (value), FALSE(0));
1815 break;
1816 case PROP_DESTROY_WITH_PARENT:
1817 ctk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1818 break;
1819 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1820 ctk_window_set_hide_titlebar_when_maximized (window, g_value_get_boolean (value));
1821 break;
1822 case PROP_ICON:
1823 ctk_window_set_icon (window,
1824 g_value_get_object (value));
1825 break;
1826 case PROP_ICON_NAME:
1827 ctk_window_set_icon_name (window, g_value_get_string (value));
1828 break;
1829 case PROP_SCREEN:
1830 ctk_window_set_screen (window, g_value_get_object (value));
1831 break;
1832 case PROP_TYPE_HINT:
1833 ctk_window_set_type_hint (window,
1834 g_value_get_enum (value));
1835 break;
1836 case PROP_SKIP_TASKBAR_HINT:
1837 ctk_window_set_skip_taskbar_hint (window,
1838 g_value_get_boolean (value));
1839 break;
1840 case PROP_SKIP_PAGER_HINT:
1841 ctk_window_set_skip_pager_hint (window,
1842 g_value_get_boolean (value));
1843 break;
1844 case PROP_URGENCY_HINT:
1845 ctk_window_set_urgency_hint (window,
1846 g_value_get_boolean (value));
1847 break;
1848 case PROP_ACCEPT_FOCUS:
1849 ctk_window_set_accept_focus (window,
1850 g_value_get_boolean (value));
1851 break;
1852 case PROP_FOCUS_ON_MAP:
1853 ctk_window_set_focus_on_map (window,
1854 g_value_get_boolean (value));
1855 break;
1856 case PROP_DECORATED:
1857 ctk_window_set_decorated (window, g_value_get_boolean (value));
1858 break;
1859 case PROP_DELETABLE:
1860 ctk_window_set_deletable (window, g_value_get_boolean (value));
1861 break;
1862 case PROP_GRAVITY:
1863 ctk_window_set_gravity (window, g_value_get_enum (value));
1864 break;
1865 case PROP_TRANSIENT_FOR:
1866 ctk_window_set_transient_for (window, g_value_get_object (value));
1867 break;
1868 case PROP_ATTACHED_TO:
1869 ctk_window_set_attached_to (window, g_value_get_object (value));
1870 break;
1871 case PROP_HAS_RESIZE_GRIP:
1872 /* Do nothing. */
1873 break;
1874 case PROP_APPLICATION:
1875 ctk_window_set_application (window, g_value_get_object (value));
1876 break;
1877 case PROP_MNEMONICS_VISIBLE:
1878 ctk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1879 break;
1880 case PROP_FOCUS_VISIBLE:
1881 ctk_window_set_focus_visible (window, g_value_get_boolean (value));
1882 break;
1883 default:
1884 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkwindow.c", 1884, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
1885 break;
1886 }
1887}
1888
1889static void
1890ctk_window_get_property (GObject *object,
1891 guint prop_id,
1892 GValue *value,
1893 GParamSpec *pspec)
1894{
1895 CtkWindow *window = CTK_WINDOW (object)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_window_get_type ()))))))
;
1896 CtkWindowPrivate *priv = window->priv;
1897
1898 switch (prop_id)
1899 {
1900 CtkWindowGeometryInfo *info;
1901 case PROP_TYPE:
1902 g_value_set_enum (value, priv->type);
1903 break;
1904 case PROP_ROLE:
1905 g_value_set_string (value, priv->wm_role);
1906 break;
1907 case PROP_TITLE:
1908 g_value_set_string (value, priv->title);
1909 break;
1910 case PROP_RESIZABLE:
1911 g_value_set_boolean (value, priv->resizable);
1912 break;
1913 case PROP_MODAL:
1914 g_value_set_boolean (value, priv->modal);
1915 break;
1916 case PROP_WIN_POS:
1917 g_value_set_enum (value, priv->position);
1918 break;
1919 case PROP_DEFAULT_WIDTH:
1920 info = ctk_window_get_geometry_info (window, FALSE(0));
1921 if (!info)
1922 g_value_set_int (value, -1);
1923 else
1924 g_value_set_int (value, info->default_width);
1925 break;
1926 case PROP_DEFAULT_HEIGHT:
1927 info = ctk_window_get_geometry_info (window, FALSE(0));
1928 if (!info)
1929 g_value_set_int (value, -1);
1930 else
1931 g_value_set_int (value, info->default_height);
1932 break;
1933 case PROP_DESTROY_WITH_PARENT:
1934 g_value_set_boolean (value, priv->destroy_with_parent);
1935 break;
1936 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1937 g_value_set_boolean (value, priv->hide_titlebar_when_maximized);
1938 break;
1939 case PROP_ICON:
1940 g_value_set_object (value, ctk_window_get_icon (window));
1941 break;
1942 case PROP_ICON_NAME:
1943 g_value_set_string (value, ctk_window_get_icon_name (window));
1944 break;
1945 case PROP_SCREEN:
1946 g_value_set_object (value, priv->screen);
1947 break;
1948 case PROP_IS_ACTIVE:
1949 g_value_set_boolean (value, priv->is_active);
1950 break;
1951 case PROP_HAS_TOPLEVEL_FOCUS:
1952 g_value_set_boolean (value, priv->has_toplevel_focus);
1953 break;
1954 case PROP_TYPE_HINT:
1955 g_value_set_enum (value, priv->type_hint);
1956 break;
1957 case PROP_SKIP_TASKBAR_HINT:
1958 g_value_set_boolean (value,
1959 ctk_window_get_skip_taskbar_hint (window));
1960 break;
1961 case PROP_SKIP_PAGER_HINT:
1962 g_value_set_boolean (value,
1963 ctk_window_get_skip_pager_hint (window));
1964 break;
1965 case PROP_URGENCY_HINT:
1966 g_value_set_boolean (value,
1967 ctk_window_get_urgency_hint (window));
1968 break;
1969 case PROP_ACCEPT_FOCUS:
1970 g_value_set_boolean (value,
1971 ctk_window_get_accept_focus (window));
1972 break;
1973 case PROP_FOCUS_ON_MAP:
1974 g_value_set_boolean (value,
1975 ctk_window_get_focus_on_map (window));
1976 break;
1977 case PROP_DECORATED:
1978 g_value_set_boolean (value, ctk_window_get_decorated (window));
1979 break;
1980 case PROP_DELETABLE:
1981 g_value_set_boolean (value, ctk_window_get_deletable (window));
1982 break;
1983 case PROP_GRAVITY:
1984 g_value_set_enum (value, ctk_window_get_gravity (window));
1985 break;
1986 case PROP_TRANSIENT_FOR:
1987 g_value_set_object (value, ctk_window_get_transient_for (window));
1988 break;
1989 case PROP_ATTACHED_TO:
1990 g_value_set_object (value, ctk_window_get_attached_to (window));
1991 break;
1992 case PROP_HAS_RESIZE_GRIP:
1993 g_value_set_boolean (value, FALSE(0));
1994 break;
1995 case PROP_RESIZE_GRIP_VISIBLE:
1996 g_value_set_boolean (value, FALSE(0));
1997 break;
1998 case PROP_APPLICATION:
1999 g_value_set_object (value, ctk_window_get_application (window));
2000 break;
2001 case PROP_MNEMONICS_VISIBLE:
2002 g_value_set_boolean (value, priv->mnemonics_visible);
2003 break;
2004 case PROP_FOCUS_VISIBLE:
2005 g_value_set_boolean (value, priv->focus_visible);
2006 break;
2007 case PROP_IS_MAXIMIZED:
2008 g_value_set_boolean (value, ctk_window_is_maximized (window));
2009 break;
2010 default:
2011 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "ctkwindow.c", 2011, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2012 break;
2013 }
2014}
2015
2016static void
2017ctk_window_buildable_interface_init (CtkBuildableIface *iface)
2018{
2019 parent_buildable_iface = g_type_interface_peek_parent (iface);
2020 iface->set_buildable_property = ctk_window_buildable_set_buildable_property;
2021 iface->parser_finished = ctk_window_buildable_parser_finished;
2022 iface->custom_tag_start = ctk_window_buildable_custom_tag_start;
2023 iface->custom_finished = ctk_window_buildable_custom_finished;
2024 iface->add_child = ctk_window_buildable_add_child;
2025}
2026
2027static void
2028ctk_window_buildable_add_child (CtkBuildable *buildable,
2029 CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)),
2030 GObject *child,
2031 const gchar *type)
2032{
2033 if (type && strcmp (type, "titlebar") == 0)
2034 ctk_window_set_titlebar (CTK_WINDOW (buildable)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_window_get_type ()))))))
, CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_widget_get_type ()))))))
);
2035 else if (!type)
2036 ctk_container_add (CTK_CONTAINER (buildable)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_container_get_type ()))))))
, CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_widget_get_type ()))))))
);
2037 else
2038 CTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type)g_warning ("'%s' is not a valid child type of '%s'", type, g_type_name
((((((GTypeClass*) (((GTypeInstance*) (buildable))->g_class
))->g_type)))))
;
2039}
2040
2041static void
2042ctk_window_buildable_set_buildable_property (CtkBuildable *buildable,
2043 CtkBuilder *builder,
2044 const gchar *name,
2045 const GValue *value)
2046{
2047 CtkWindow *window = CTK_WINDOW (buildable)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_window_get_type ()))))))
;
2048 CtkWindowPrivate *priv = window->priv;
2049
2050 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
2051 priv->builder_visible = TRUE(!(0));
2052 else
2053 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
2054}
2055
2056typedef struct {
2057 gchar *name;
2058 gint line;
2059 gint col;
2060} ItemData;
2061
2062static void
2063item_data_free (gpointer data)
2064{
2065 ItemData *item_data = data;
2066
2067 g_free (item_data->name);
2068 g_free (item_data);
2069}
2070
2071static void
2072item_list_free (gpointer data)
2073{
2074 GSList *list = data;
2075
2076 g_slist_free_full (list, item_data_free);
2077}
2078
2079static void
2080ctk_window_buildable_parser_finished (CtkBuildable *buildable,
2081 CtkBuilder *builder)
2082{
2083 CtkWindow *window = CTK_WINDOW (buildable)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_window_get_type ()))))))
;
2084 CtkWindowPrivate *priv = window->priv;
2085 GObject *object;
2086 GSList *accels, *l;
2087
2088 if (priv->builder_visible)
2089 ctk_widget_show (CTK_WIDGET (buildable)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_widget_get_type ()))))))
);
2090
2091 accels = g_object_get_qdata (G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
, quark_ctk_buildable_accels);
2092 for (l = accels; l; l = l->next)
2093 {
2094 ItemData *data = l->data;
2095
2096 object = _ctk_builder_lookup_object (builder, data->name, data->line, data->col);
2097 if (!object)
2098 continue;
2099 ctk_window_add_accel_group (CTK_WINDOW (buildable)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_window_get_type ()))))))
, CTK_ACCEL_GROUP (object)((((CtkAccelGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_accel_group_get_type ()))))))
);
2100 }
2101
2102 g_object_set_qdata (G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
, quark_ctk_buildable_accels, NULL((void*)0));
2103
2104 parent_buildable_iface->parser_finished (buildable, builder);
2105}
2106
2107typedef struct {
2108 GObject *object;
2109 CtkBuilder *builder;
2110 GSList *items;
2111} GSListSubParserData;
2112
2113static void
2114window_start_element (GMarkupParseContext *context,
2115 const gchar *element_name,
2116 const gchar **names,
2117 const gchar **values,
2118 gpointer user_data,
2119 GError **error)
2120{
2121 GSListSubParserData *data = (GSListSubParserData*)user_data;
2122
2123 if (strcmp (element_name, "group") == 0)
2124 {
2125 const gchar *name;
2126 ItemData *item_data;
2127
2128 if (!_ctk_builder_check_parent (data->builder, context, "accel-groups", error))
2129 return;
2130
2131 if (!g_markup_collect_attributes (element_name, names, values, error,
2132 G_MARKUP_COLLECT_STRING, "name", &name,
2133 G_MARKUP_COLLECT_INVALID))
2134 {
2135 _ctk_builder_prefix_error (data->builder, context, error);
2136 return;
2137 }
2138
2139 item_data = g_new (ItemData, 1)((ItemData *) g_malloc_n ((1), sizeof (ItemData)));
2140 item_data->name = g_strdup (name)g_strdup_inline (name);
2141 g_markup_parse_context_get_position (context, &item_data->line, &item_data->col);
2142 data->items = g_slist_prepend (data->items, item_data);
2143 }
2144 else if (strcmp (element_name, "accel-groups") == 0)
2145 {
2146 if (!_ctk_builder_check_parent (data->builder, context, "object", error))
2147 return;
2148
2149 if (!g_markup_collect_attributes (element_name, names, values, error,
2150 G_MARKUP_COLLECT_INVALID, NULL((void*)0), NULL((void*)0),
2151 G_MARKUP_COLLECT_INVALID))
2152 _ctk_builder_prefix_error (data->builder, context, error);
2153 }
2154 else
2155 {
2156 _ctk_builder_error_unhandled_tag (data->builder, context,
2157 "CtkWindow", element_name,
2158 error);
2159 }
2160}
2161
2162static const GMarkupParser window_parser =
2163 {
2164 .start_element = window_start_element
2165 };
2166
2167typedef struct {
2168 GObject *object;
2169 CtkBuilder *builder;
2170 gchar *name;
2171 gint line;
2172 gint col;
2173} NameSubParserData;
2174
2175static void
2176focus_start_element (GMarkupParseContext *context,
2177 const gchar *element_name,
2178 const gchar **names,
2179 const gchar **values,
2180 gpointer user_data,
2181 GError **error)
2182{
2183 NameSubParserData *data = (NameSubParserData*)user_data;
2184
2185 if (strcmp (element_name, "initial-focus") == 0)
2186 {
2187 const gchar *name;
2188
2189 if (!_ctk_builder_check_parent (data->builder, context, "object", error))
2190 return;
2191
2192 if (!g_markup_collect_attributes (element_name, names, values, error,
2193 G_MARKUP_COLLECT_STRING, "name", &name,
2194 G_MARKUP_COLLECT_INVALID))
2195 {
2196 _ctk_builder_prefix_error (data->builder, context, error);
2197 return;
2198 }
2199
2200 data->name = g_strdup (name)g_strdup_inline (name);
2201 g_markup_parse_context_get_position (context, &data->line, &data->col);
2202 }
2203 else
2204 {
2205 _ctk_builder_error_unhandled_tag (data->builder, context,
2206 "CtkWindow", element_name,
2207 error);
2208 }
2209}
2210
2211static const GMarkupParser focus_parser =
2212{
2213 .start_element = focus_start_element
2214};
2215
2216static gboolean
2217ctk_window_buildable_custom_tag_start (CtkBuildable *buildable,
2218 CtkBuilder *builder,
2219 GObject *child,
2220 const gchar *tagname,
2221 GMarkupParser *parser,
2222 gpointer *parser_data)
2223{
2224 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
2225 tagname, parser, parser_data))
2226 return TRUE(!(0));
2227
2228 if (strcmp (tagname, "accel-groups") == 0)
2229 {
2230 GSListSubParserData *data;
2231
2232 data = g_slice_new0 (GSListSubParserData)((GSListSubParserData*) g_slice_alloc0 (sizeof (GSListSubParserData
)))
;
2233 data->items = NULL((void*)0);
2234 data->object = G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
;
2235 data->builder = builder;
2236
2237 *parser = window_parser;
2238 *parser_data = data;
2239
2240 return TRUE(!(0));
2241 }
2242
2243 if (strcmp (tagname, "initial-focus") == 0)
2244 {
2245 NameSubParserData *data;
2246
2247 data = g_slice_new0 (NameSubParserData)((NameSubParserData*) g_slice_alloc0 (sizeof (NameSubParserData
)))
;
2248 data->name = NULL((void*)0);
2249 data->object = G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
;
2250 data->builder = builder;
2251
2252 *parser = focus_parser;
2253 *parser_data = data;
2254
2255 return TRUE(!(0));
2256 }
2257
2258 return FALSE(0);
2259}
2260
2261static void
2262ctk_window_buildable_custom_finished (CtkBuildable *buildable,
2263 CtkBuilder *builder,
2264 GObject *child,
2265 const gchar *tagname,
2266 gpointer user_data)
2267{
2268 parent_buildable_iface->custom_finished (buildable, builder, child,
2269 tagname, user_data);
2270
2271 if (strcmp (tagname, "accel-groups") == 0)
2272 {
2273 GSListSubParserData *data = (GSListSubParserData*)user_data;
2274
2275 g_object_set_qdata_full (G_OBJECT (buildable)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), (((GType) ((20) << (2))))))))
, quark_ctk_buildable_accels,
2276 data->items, (GDestroyNotify) item_list_free);
2277
2278 g_slice_free (GSListSubParserData, data)do { if (1) g_slice_free1 (sizeof (GSListSubParserData), (data
)); else (void) ((GSListSubParserData*) 0 == (data)); } while
(0)
;
2279 }
2280
2281 if (strcmp (tagname, "initial-focus") == 0)
2282 {
2283 NameSubParserData *data = (NameSubParserData*)user_data;
2284
2285 if (data->name)
2286 {
2287 GObject *object;
2288
2289 object = _ctk_builder_lookup_object (builder, data->name, data->line, data->col);
2290 if (object)
2291 ctk_window_set_focus (CTK_WINDOW (buildable)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((buildable)), ((ctk_window_get_type ()))))))
, CTK_WIDGET (object)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_widget_get_type ()))))))
);
2292 g_free (data->name);
2293 }
2294
2295 g_slice_free (NameSubParserData, data)do { if (1) g_slice_free1 (sizeof (NameSubParserData), (data)
); else (void) ((NameSubParserData*) 0 == (data)); } while (0
)
;
2296 }
2297}
2298
2299/**
2300 * ctk_window_new:
2301 * @type: type of window
2302 *
2303 * Creates a new #CtkWindow, which is a toplevel window that can
2304 * contain other widgets. Nearly always, the type of the window should
2305 * be #CTK_WINDOW_TOPLEVEL. If you’re implementing something like a
2306 * popup menu from scratch (which is a bad idea, just use #CtkMenu),
2307 * you might use #CTK_WINDOW_POPUP. #CTK_WINDOW_POPUP is not for
2308 * dialogs, though in some other toolkits dialogs are called “popups”.
2309 * In CTK+, #CTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
2310 * On X11, popup windows are not controlled by the
2311 * [window manager][ctk-X11-arch].
2312 *
2313 * If you simply want an undecorated window (no window borders), use
2314 * ctk_window_set_decorated(), don’t use #CTK_WINDOW_POPUP.
2315 *
2316 * All top-level windows created by ctk_window_new() are stored in
2317 * an internal top-level window list. This list can be obtained from
2318 * ctk_window_list_toplevels(). Due to Ctk+ keeping a reference to
2319 * the window internally, ctk_window_new() does not return a reference
2320 * to the caller.
2321 *
2322 * To delete a #CtkWindow, call ctk_widget_destroy().
2323 *
2324 * Returns: a new #CtkWindow.
2325 **/
2326CtkWidget*
2327ctk_window_new (CtkWindowType type)
2328{
2329 CtkWindow *window;
2330
2331 g_return_val_if_fail (type >= CTK_WINDOW_TOPLEVEL && type <= CTK_WINDOW_POPUP, NULL)do { if ((type >= CTK_WINDOW_TOPLEVEL && type <=
CTK_WINDOW_POPUP)) { } else { g_return_if_fail_warning ("Ctk"
, ((const char*) (__func__)), "type >= CTK_WINDOW_TOPLEVEL && type <= CTK_WINDOW_POPUP"
); return (((void*)0)); } } while (0)
;
2332
2333 window = g_object_new (CTK_TYPE_WINDOW(ctk_window_get_type ()), "type", type, NULL((void*)0));
2334
2335 return CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
2336}
2337
2338static void
2339ctk_window_set_title_internal (CtkWindow *window,
2340 const gchar *title,
2341 gboolean update_titlebar)
2342{
2343 CtkWindowPrivate *priv;
2344 CtkWidget *widget;
2345 char *new_title;
2346
2347 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2348
2349 priv = window->priv;
2350 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
2351
2352 new_title = g_strdup (title)g_strdup_inline (title);
2353 g_free (priv->title);
2354 priv->title = new_title;
2355
2356 if (new_title == NULL((void*)0))
2357 new_title = "";
2358
2359 if (_ctk_widget_get_realized (widget))
2360 cdk_window_set_title (_ctk_widget_get_window (widget), new_title);
2361
2362 if (update_titlebar && CTK_IS_HEADER_BAR (priv->title_box)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->title_box)); GType __t = ((ctk_header_bar_get_type (
))); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
2363 ctk_header_bar_set_title (CTK_HEADER_BAR (priv->title_box)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->title_box)), ((ctk_header_bar_get_type ()))))))
, new_title);
2364
2365 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_TITLE]);
2366}
2367
2368/**
2369 * ctk_window_set_title:
2370 * @window: a #CtkWindow
2371 * @title: title of the window
2372 *
2373 * Sets the title of the #CtkWindow. The title of a window will be
2374 * displayed in its title bar; on the X Window System, the title bar
2375 * is rendered by the [window manager][ctk-X11-arch],
2376 * so exactly how the title appears to users may vary
2377 * according to a user’s exact configuration. The title should help a
2378 * user distinguish this window from other windows they may have
2379 * open. A good title might include the application name and current
2380 * document filename, for example.
2381 *
2382 **/
2383void
2384ctk_window_set_title (CtkWindow *window,
2385 const gchar *title)
2386{
2387 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2388
2389 ctk_window_set_title_internal (window, title, TRUE(!(0)));
2390}
2391
2392/**
2393 * ctk_window_get_title:
2394 * @window: a #CtkWindow
2395 *
2396 * Retrieves the title of the window. See ctk_window_set_title().
2397 *
2398 * Returns: (nullable): the title of the window, or %NULL if none has
2399 * been set explicitly. The returned string is owned by the widget
2400 * and must not be modified or freed.
2401 **/
2402const gchar *
2403ctk_window_get_title (CtkWindow *window)
2404{
2405 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
2406
2407 return window->priv->title;
2408}
2409
2410/**
2411 * ctk_window_set_wmclass:
2412 * @window: a #CtkWindow
2413 * @wmclass_name: window name hint
2414 * @wmclass_class: window class hint
2415 *
2416 * Don’t use this function. It sets the X Window System “class” and
2417 * “name” hints for a window. According to the ICCCM, you should
2418 * always set these to the same value for all windows in an
2419 * application, and CTK+ sets them to that value by default, so calling
2420 * this function is sort of pointless. However, you may want to call
2421 * ctk_window_set_role() on each window in your application, for the
2422 * benefit of the session manager. Setting the role allows the window
2423 * manager to restore window positions when loading a saved session.
2424 *
2425 * Deprecated: 3.22
2426 **/
2427void
2428ctk_window_set_wmclass (CtkWindow *window,
2429 const gchar *wmclass_name,
2430 const gchar *wmclass_class)
2431{
2432 CtkWindowPrivate *priv;
2433
2434 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2435
2436 priv = window->priv;
2437
2438 g_free (priv->wmclass_name);
2439 priv->wmclass_name = g_strdup (wmclass_name)g_strdup_inline (wmclass_name);
2440
2441 g_free (priv->wmclass_class);
2442 priv->wmclass_class = g_strdup (wmclass_class)g_strdup_inline (wmclass_class);
2443
2444 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
2445 g_warning ("ctk_window_set_wmclass: shouldn't set wmclass after window is realized!");
2446}
2447
2448/**
2449 * ctk_window_set_role:
2450 * @window: a #CtkWindow
2451 * @role: unique identifier for the window to be used when restoring a session
2452 *
2453 * This function is only useful on X11, not with other CTK+ targets.
2454 *
2455 * In combination with the window title, the window role allows a
2456 * [window manager][ctk-X11-arch] to identify "the
2457 * same" window when an application is restarted. So for example you
2458 * might set the “toolbox” role on your app’s toolbox window, so that
2459 * when the user restarts their session, the window manager can put
2460 * the toolbox back in the same place.
2461 *
2462 * If a window already has a unique title, you don’t need to set the
2463 * role, since the WM can use the title to identify the window when
2464 * restoring the session.
2465 *
2466 **/
2467void
2468ctk_window_set_role (CtkWindow *window,
2469 const gchar *role)
2470{
2471 CtkWindowPrivate *priv;
2472 CtkWidget *widget;
2473 char *new_role;
2474
2475 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2476
2477 priv = window->priv;
2478 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
2479
2480 new_role = g_strdup (role)g_strdup_inline (role);
2481 g_free (priv->wm_role);
2482 priv->wm_role = new_role;
2483
2484 if (_ctk_widget_get_realized (widget))
2485 cdk_window_set_role (_ctk_widget_get_window (widget), priv->wm_role);
2486
2487 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ROLE]);
2488}
2489
2490/**
2491 * ctk_window_set_startup_id:
2492 * @window: a #CtkWindow
2493 * @startup_id: a string with startup-notification identifier
2494 *
2495 * Startup notification identifiers are used by desktop environment to
2496 * track application startup, to provide user feedback and other
2497 * features. This function changes the corresponding property on the
2498 * underlying CdkWindow. Normally, startup identifier is managed
2499 * automatically and you should only use this function in special cases
2500 * like transferring focus from other processes. You should use this
2501 * function before calling ctk_window_present() or any equivalent
2502 * function generating a window map event.
2503 *
2504 * This function is only useful on X11, not with other CTK+ targets.
2505 *
2506 * Since: 2.12
2507 **/
2508void
2509ctk_window_set_startup_id (CtkWindow *window,
2510 const gchar *startup_id)
2511{
2512 CtkWindowPrivate *priv;
2513 CtkWidget *widget;
2514
2515 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2516
2517 priv = window->priv;
2518 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
2519
2520 g_free (priv->startup_id);
2521 priv->startup_id = g_strdup (startup_id)g_strdup_inline (startup_id);
2522
2523 if (_ctk_widget_get_realized (widget))
2524 {
2525 CdkWindow *cdk_window;
2526 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
2527
2528 cdk_window = _ctk_widget_get_window (widget);
2529
2530#ifdef CDK_WINDOWING_X11
2531 if (timestamp != CDK_CURRENT_TIME0L && CDK_IS_X11_WINDOW(cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
2532 cdk_x11_window_set_user_time (cdk_window, timestamp);
2533#endif
2534
2535 /* Here we differentiate real and "fake" startup notification IDs,
2536 * constructed on purpose just to pass interaction timestamp
2537 */
2538 if (startup_id_is_fake (priv->startup_id))
2539 ctk_window_present_with_time (window, timestamp);
2540 else
2541 {
2542 cdk_window_set_startup_id (cdk_window,
2543 priv->startup_id);
2544
2545 /* If window is mapped, terminate the startup-notification too */
2546 if (_ctk_widget_get_mapped (widget) &&
2547 !disable_startup_notification)
2548 cdk_notify_startup_complete_with_id (priv->startup_id);
2549 }
2550 }
2551
2552 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_STARTUP_ID]);
2553}
2554
2555/**
2556 * ctk_window_get_role:
2557 * @window: a #CtkWindow
2558 *
2559 * Returns the role of the window. See ctk_window_set_role() for
2560 * further explanation.
2561 *
2562 * Returns: (nullable): the role of the window if set, or %NULL. The
2563 * returned is owned by the widget and must not be modified or freed.
2564 **/
2565const gchar *
2566ctk_window_get_role (CtkWindow *window)
2567{
2568 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
2569
2570 return window->priv->wm_role;
2571}
2572
2573/**
2574 * ctk_window_set_focus:
2575 * @window: a #CtkWindow
2576 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
2577 * any focus widget for the toplevel window.
2578 *
2579 * If @focus is not the current focus widget, and is focusable, sets
2580 * it as the focus widget for the window. If @focus is %NULL, unsets
2581 * the focus widget for this window. To set the focus to a particular
2582 * widget in the toplevel, it is usually more convenient to use
2583 * ctk_widget_grab_focus() instead of this function.
2584 **/
2585void
2586ctk_window_set_focus (CtkWindow *window,
2587 CtkWidget *focus)
2588{
2589 CtkWindowPrivate *priv;
2590 CtkWidget *parent;
2591
2592 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2593
2594 priv = window->priv;
2595
2596 if (focus)
2597 {
2598 g_return_if_fail (CTK_IS_WIDGET (focus))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((focus)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (focus)"); return; } } while (0)
;
2599 g_return_if_fail (ctk_widget_get_can_focus (focus))do { if ((ctk_widget_get_can_focus (focus))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "ctk_widget_get_can_focus (focus)"
); return; } } while (0)
;
2600 }
2601
2602 if (focus)
2603 {
2604 if (!ctk_widget_get_visible (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
2605 priv->initial_focus = focus;
2606 else
2607 ctk_widget_grab_focus (focus);
2608 }
2609 else
2610 {
2611 /* Clear the existing focus chain, so that when we focus into
2612 * the window again, we start at the beginnning.
2613 */
2614 CtkWidget *widget = priv->focus_widget;
2615 if (widget)
2616 {
2617 while ((parent = _ctk_widget_get_parent (widget)))
2618 {
2619 widget = parent;
2620 ctk_container_set_focus_child (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
, NULL((void*)0));
2621 }
2622 }
2623
2624 _ctk_window_internal_set_focus (window, NULL((void*)0));
2625 }
2626}
2627
2628void
2629_ctk_window_internal_set_focus (CtkWindow *window,
2630 CtkWidget *focus)
2631{
2632 CtkWindowPrivate *priv;
2633
2634 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2635
2636 priv = window->priv;
2637
2638 priv->initial_focus = NULL((void*)0);
2639 if ((priv->focus_widget != focus) ||
2640 (focus && !ctk_widget_has_focus (focus)))
2641 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
2642}
2643
2644/**
2645 * ctk_window_set_default:
2646 * @window: a #CtkWindow
2647 * @default_widget: (allow-none): widget to be the default, or %NULL
2648 * to unset the default widget for the toplevel
2649 *
2650 * The default widget is the widget that’s activated when the user
2651 * presses Enter in a dialog (for example). This function sets or
2652 * unsets the default widget for a #CtkWindow. When setting (rather
2653 * than unsetting) the default widget it’s generally easier to call
2654 * ctk_widget_grab_default() on the widget. Before making a widget
2655 * the default widget, you must call ctk_widget_set_can_default() on
2656 * the widget you’d like to make the default.
2657 */
2658void
2659ctk_window_set_default (CtkWindow *window,
2660 CtkWidget *default_widget)
2661{
2662 CtkWindowPrivate *priv;
2663
2664 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2665
2666 priv = window->priv;
2667
2668 if (default_widget)
2669 g_return_if_fail (ctk_widget_get_can_default (default_widget))do { if ((ctk_widget_get_can_default (default_widget))) { } else
{ g_return_if_fail_warning ("Ctk", ((const char*) (__func__)
), "ctk_widget_get_can_default (default_widget)"); return; } }
while (0)
;
2670
2671 if (priv->default_widget != default_widget)
2672 {
2673 CtkWidget *old_default_widget = NULL((void*)0);
2674
2675 if (default_widget)
2676 g_object_ref (default_widget)((__typeof__ (default_widget)) (g_object_ref) (default_widget
))
;
2677
2678 if (priv->default_widget)
2679 {
2680 old_default_widget = priv->default_widget;
2681
2682 if (priv->focus_widget != priv->default_widget ||
2683 !ctk_widget_get_receives_default (priv->default_widget))
2684 _ctk_widget_set_has_default (priv->default_widget, FALSE(0));
2685
2686 ctk_widget_queue_draw (priv->default_widget);
2687 }
2688
2689 priv->default_widget = default_widget;
2690
2691 if (priv->default_widget)
2692 {
2693 if (priv->focus_widget == NULL((void*)0) ||
2694 !ctk_widget_get_receives_default (priv->focus_widget))
2695 _ctk_widget_set_has_default (priv->default_widget, TRUE(!(0)));
2696
2697 ctk_widget_queue_draw (priv->default_widget);
2698 }
2699
2700 if (old_default_widget)
2701 g_object_notify (G_OBJECT (old_default_widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((old_default_widget)), (((GType) ((20) << (2)))))))
)
, "has-default");
2702
2703 if (default_widget)
2704 {
2705 g_object_notify (G_OBJECT (default_widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((default_widget)), (((GType) ((20) << (2))))))))
, "has-default");
2706 g_object_unref (default_widget);
2707 }
2708 }
2709}
2710
2711/**
2712 * ctk_window_get_default_widget:
2713 * @window: a #CtkWindow
2714 *
2715 * Returns the default widget for @window. See
2716 * ctk_window_set_default() for more details.
2717 *
2718 * Returns: (nullable) (transfer none): the default widget, or %NULL
2719 * if there is none.
2720 *
2721 * Since: 2.14
2722 **/
2723CtkWidget *
2724ctk_window_get_default_widget (CtkWindow *window)
2725{
2726 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
2727
2728 return window->priv->default_widget;
2729}
2730
2731static gboolean
2732handle_keys_changed (gpointer data)
2733{
2734 CtkWindow *window = CTK_WINDOW (data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_window_get_type ()))))))
;
2735 CtkWindowPrivate *priv = window->priv;
2736
2737 if (priv->keys_changed_handler)
2738 {
2739 g_source_remove (priv->keys_changed_handler);
2740 priv->keys_changed_handler = 0;
2741 }
2742
2743 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
2744
2745 return FALSE(0);
2746}
2747
2748void
2749_ctk_window_notify_keys_changed (CtkWindow *window)
2750{
2751 CtkWindowPrivate *priv = window->priv;
2752
2753 if (!priv->keys_changed_handler)
2754 {
2755 priv->keys_changed_handler = cdk_threads_add_idle (handle_keys_changed, window);
2756 g_source_set_name_by_id (priv->keys_changed_handler, "[ctk+] handle_keys_changed");
2757 }
2758}
2759
2760/**
2761 * ctk_window_add_accel_group:
2762 * @window: window to attach accelerator group to
2763 * @accel_group: a #CtkAccelGroup
2764 *
2765 * Associate @accel_group with @window, such that calling
2766 * ctk_accel_groups_activate() on @window will activate accelerators
2767 * in @accel_group.
2768 **/
2769void
2770ctk_window_add_accel_group (CtkWindow *window,
2771 CtkAccelGroup *accel_group)
2772{
2773 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2774 g_return_if_fail (CTK_IS_ACCEL_GROUP (accel_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((accel_group)); GType __t = ((ctk_accel_group_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_ACCEL_GROUP (accel_group)"); return
; } } while (0)
;
2775
2776 _ctk_accel_group_attach (accel_group, G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
);
2777 g_signal_connect_object (accel_group, "accel-changed",
2778 G_CALLBACK (_ctk_window_notify_keys_changed)((GCallback) (_ctk_window_notify_keys_changed)),
2779 window, G_CONNECT_SWAPPED);
2780 _ctk_window_notify_keys_changed (window);
2781}
2782
2783/**
2784 * ctk_window_remove_accel_group:
2785 * @window: a #CtkWindow
2786 * @accel_group: a #CtkAccelGroup
2787 *
2788 * Reverses the effects of ctk_window_add_accel_group().
2789 **/
2790void
2791ctk_window_remove_accel_group (CtkWindow *window,
2792 CtkAccelGroup *accel_group)
2793{
2794 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2795 g_return_if_fail (CTK_IS_ACCEL_GROUP (accel_group))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((accel_group)); GType __t = ((ctk_accel_group_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_ACCEL_GROUP (accel_group)"); return
; } } while (0)
;
2796
2797 g_signal_handlers_disconnect_by_func (accel_group,g_signal_handlers_disconnect_matched ((accel_group), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (_ctk_window_notify_keys_changed), (window))
2798 _ctk_window_notify_keys_changed,g_signal_handlers_disconnect_matched ((accel_group), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (_ctk_window_notify_keys_changed), (window))
2799 window)g_signal_handlers_disconnect_matched ((accel_group), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (_ctk_window_notify_keys_changed), (window))
;
2800 _ctk_accel_group_detach (accel_group, G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
);
2801 _ctk_window_notify_keys_changed (window);
2802}
2803
2804static CtkMnemonicHash *
2805ctk_window_get_mnemonic_hash (CtkWindow *window,
2806 gboolean create)
2807{
2808 CtkWindowPrivate *private = window->priv;
2809
2810 if (!private->mnemonic_hash && create)
2811 private->mnemonic_hash = _ctk_mnemonic_hash_new ();
2812
2813 return private->mnemonic_hash;
2814}
2815
2816/**
2817 * ctk_window_add_mnemonic:
2818 * @window: a #CtkWindow
2819 * @keyval: the mnemonic
2820 * @target: the widget that gets activated by the mnemonic
2821 *
2822 * Adds a mnemonic to this window.
2823 */
2824void
2825ctk_window_add_mnemonic (CtkWindow *window,
2826 guint keyval,
2827 CtkWidget *target)
2828{
2829 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2830 g_return_if_fail (CTK_IS_WIDGET (target))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (target)"); return; } } while (0)
;
2831
2832 _ctk_mnemonic_hash_add (ctk_window_get_mnemonic_hash (window, TRUE(!(0))),
2833 keyval, target);
2834 _ctk_window_notify_keys_changed (window);
2835}
2836
2837/**
2838 * ctk_window_remove_mnemonic:
2839 * @window: a #CtkWindow
2840 * @keyval: the mnemonic
2841 * @target: the widget that gets activated by the mnemonic
2842 *
2843 * Removes a mnemonic from this window.
2844 */
2845void
2846ctk_window_remove_mnemonic (CtkWindow *window,
2847 guint keyval,
2848 CtkWidget *target)
2849{
2850 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2851 g_return_if_fail (CTK_IS_WIDGET (target))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((target)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (target)"); return; } } while (0)
;
2852
2853 _ctk_mnemonic_hash_remove (ctk_window_get_mnemonic_hash (window, TRUE(!(0))),
2854 keyval, target);
2855 _ctk_window_notify_keys_changed (window);
2856}
2857
2858/**
2859 * ctk_window_mnemonic_activate:
2860 * @window: a #CtkWindow
2861 * @keyval: the mnemonic
2862 * @modifier: the modifiers
2863 *
2864 * Activates the targets associated with the mnemonic.
2865 *
2866 * Returns: %TRUE if the activation is done.
2867 */
2868gboolean
2869ctk_window_mnemonic_activate (CtkWindow *window,
2870 guint keyval,
2871 CdkModifierType modifier)
2872{
2873 CtkWindowPrivate *priv;
2874
2875 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
2876
2877 priv = window->priv;
2878
2879 if (priv->mnemonic_modifier == (modifier & ctk_accelerator_get_default_mod_mask ()))
2880 {
2881 CtkMnemonicHash *mnemonic_hash = ctk_window_get_mnemonic_hash (window, FALSE(0));
2882 if (mnemonic_hash)
2883 return _ctk_mnemonic_hash_activate (mnemonic_hash, keyval);
2884 }
2885
2886 return FALSE(0);
2887}
2888
2889/**
2890 * ctk_window_set_mnemonic_modifier:
2891 * @window: a #CtkWindow
2892 * @modifier: the modifier mask used to activate
2893 * mnemonics on this window.
2894 *
2895 * Sets the mnemonic modifier for this window.
2896 **/
2897void
2898ctk_window_set_mnemonic_modifier (CtkWindow *window,
2899 CdkModifierType modifier)
2900{
2901 CtkWindowPrivate *priv;
2902
2903 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2904 g_return_if_fail ((modifier & ~CDK_MODIFIER_MASK) == 0)do { if (((modifier & ~CDK_MODIFIER_MASK) == 0)) { } else
{ g_return_if_fail_warning ("Ctk", ((const char*) (__func__)
), "(modifier & ~CDK_MODIFIER_MASK) == 0"); return; } } while
(0)
;
2905
2906 priv = window->priv;
2907
2908 priv->mnemonic_modifier = modifier;
2909 _ctk_window_notify_keys_changed (window);
2910}
2911
2912/**
2913 * ctk_window_get_mnemonic_modifier:
2914 * @window: a #CtkWindow
2915 *
2916 * Returns the mnemonic modifier for this window. See
2917 * ctk_window_set_mnemonic_modifier().
2918 *
2919 * Returns: the modifier mask used to activate
2920 * mnemonics on this window.
2921 **/
2922CdkModifierType
2923ctk_window_get_mnemonic_modifier (CtkWindow *window)
2924{
2925 g_return_val_if_fail (CTK_IS_WINDOW (window), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (0); } } while (0)
;
2926
2927 return window->priv->mnemonic_modifier;
2928}
2929
2930/**
2931 * ctk_window_set_position:
2932 * @window: a #CtkWindow.
2933 * @position: a position constraint.
2934 *
2935 * Sets a position constraint for this window. If the old or new
2936 * constraint is %CTK_WIN_POS_CENTER_ALWAYS, this will also cause
2937 * the window to be repositioned to satisfy the new constraint.
2938 **/
2939void
2940ctk_window_set_position (CtkWindow *window,
2941 CtkWindowPosition position)
2942{
2943 CtkWindowPrivate *priv;
2944
2945 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
2946
2947 priv = window->priv;
2948
2949 if (position == CTK_WIN_POS_CENTER_ALWAYS ||
2950 priv->position == CTK_WIN_POS_CENTER_ALWAYS)
2951 {
2952 CtkWindowGeometryInfo *info;
2953
2954 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
2955
2956 /* this flag causes us to re-request the CENTER_ALWAYS
2957 * constraint in ctk_window_move_resize(), see
2958 * comment in that function.
2959 */
2960 info->position_constraints_changed = TRUE(!(0));
2961
2962 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
2963 }
2964
2965 if (priv->position != position)
2966 {
2967 priv->position = position;
2968
2969 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_WIN_POS]);
2970 }
2971}
2972
2973/**
2974 * ctk_window_activate_focus:
2975 * @window: a #CtkWindow
2976 *
2977 * Activates the current focused widget within the window.
2978 *
2979 * Returns: %TRUE if a widget got activated.
2980 **/
2981gboolean
2982ctk_window_activate_focus (CtkWindow *window)
2983{
2984 CtkWindowPrivate *priv;
2985
2986 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
2987
2988 priv = window->priv;
2989
2990 if (priv->focus_widget && ctk_widget_is_sensitive (priv->focus_widget))
2991 return ctk_widget_activate (priv->focus_widget);
2992
2993 return FALSE(0);
2994}
2995
2996/**
2997 * ctk_window_get_focus:
2998 * @window: a #CtkWindow
2999 *
3000 * Retrieves the current focused widget within the window.
3001 * Note that this is the widget that would have the focus
3002 * if the toplevel window focused; if the toplevel window
3003 * is not focused then `ctk_widget_has_focus (widget)` will
3004 * not be %TRUE for the widget.
3005 *
3006 * Returns: (nullable) (transfer none): the currently focused widget,
3007 * or %NULL if there is none.
3008 **/
3009CtkWidget *
3010ctk_window_get_focus (CtkWindow *window)
3011{
3012 CtkWindowPrivate *priv;
3013
3014 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
3015
3016 priv = window->priv;
3017
3018 if (priv->initial_focus)
3019 return priv->initial_focus;
3020 else
3021 return priv->focus_widget;
3022}
3023
3024/**
3025 * ctk_window_activate_default:
3026 * @window: a #CtkWindow
3027 *
3028 * Activates the default widget for the window, unless the current
3029 * focused widget has been configured to receive the default action
3030 * (see ctk_widget_set_receives_default()), in which case the
3031 * focused widget is activated.
3032 *
3033 * Returns: %TRUE if a widget got activated.
3034 **/
3035gboolean
3036ctk_window_activate_default (CtkWindow *window)
3037{
3038 CtkWindowPrivate *priv;
3039
3040 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3041
3042 priv = window->priv;
3043
3044 if (priv->default_widget && ctk_widget_is_sensitive (priv->default_widget) &&
3045 (!priv->focus_widget || !ctk_widget_get_receives_default (priv->focus_widget)))
3046 return ctk_widget_activate (priv->default_widget);
3047 else if (priv->focus_widget && ctk_widget_is_sensitive (priv->focus_widget))
3048 return ctk_widget_activate (priv->focus_widget);
3049
3050 return FALSE(0);
3051}
3052
3053/**
3054 * ctk_window_set_modal:
3055 * @window: a #CtkWindow
3056 * @modal: whether the window is modal
3057 *
3058 * Sets a window modal or non-modal. Modal windows prevent interaction
3059 * with other windows in the same application. To keep modal dialogs
3060 * on top of main application windows, use
3061 * ctk_window_set_transient_for() to make the dialog transient for the
3062 * parent; most [window managers][ctk-X11-arch]
3063 * will then disallow lowering the dialog below the parent.
3064 *
3065 *
3066 **/
3067void
3068ctk_window_set_modal (CtkWindow *window,
3069 gboolean modal)
3070{
3071 CtkWindowPrivate *priv;
3072 CtkWidget *widget;
3073
3074 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3075
3076 priv = window->priv;
3077
3078 modal = modal != FALSE(0);
3079 if (priv->modal == modal)
3080 return;
3081
3082 priv->modal = modal;
3083 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
3084
3085 /* adjust desired modality state */
3086 if (_ctk_widget_get_realized (widget))
3087 cdk_window_set_modal_hint (_ctk_widget_get_window (widget), priv->modal);
3088
3089 if (ctk_widget_get_visible (widget))
3090 {
3091 if (priv->modal)
3092 ctk_grab_add (widget);
3093 else
3094 ctk_grab_remove (widget);
3095 }
3096
3097 update_window_buttons (window);
3098
3099 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_MODAL]);
3100}
3101
3102/**
3103 * ctk_window_get_modal:
3104 * @window: a #CtkWindow
3105 *
3106 * Returns whether the window is modal. See ctk_window_set_modal().
3107 *
3108 * Returns: %TRUE if the window is set to be modal and
3109 * establishes a grab when shown
3110 **/
3111gboolean
3112ctk_window_get_modal (CtkWindow *window)
3113{
3114 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3115
3116 return window->priv->modal;
3117}
3118
3119/**
3120 * ctk_window_list_toplevels:
3121 *
3122 * Returns a list of all existing toplevel windows. The widgets
3123 * in the list are not individually referenced. If you want
3124 * to iterate through the list and perform actions involving
3125 * callbacks that might destroy the widgets, you must call
3126 * `g_list_foreach (result, (GFunc)g_object_ref, NULL)` first, and
3127 * then unref all the widgets afterwards.
3128 *
3129 * Returns: (element-type CtkWidget) (transfer container): list of toplevel widgets
3130 **/
3131GList*
3132ctk_window_list_toplevels (void)
3133{
3134 GList *list = NULL((void*)0);
3135 GSList *slist;
3136
3137 for (slist = toplevel_list; slist; slist = slist->next)
3138 list = g_list_prepend (list, slist->data);
3139
3140 return list;
3141}
3142
3143static void
3144remove_attach_widget (CtkWindow *window)
3145{
3146 CtkWindowPrivate *priv = window->priv;
3147
3148 if (priv->attach_widget)
3149 {
3150 _ctk_widget_remove_attached_window (priv->attach_widget, window);
3151
3152 priv->attach_widget = NULL((void*)0);
3153 }
3154}
3155
3156static void
3157ctk_window_dispose (GObject *object)
3158{
3159 CtkWindow *window = CTK_WINDOW (object)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_window_get_type ()))))))
;
3160 CtkWindowPrivate *priv = window->priv;
3161
3162 ctk_window_set_focus (window, NULL((void*)0));
3163 ctk_window_set_default (window, NULL((void*)0));
3164 remove_attach_widget (window);
3165
3166 G_OBJECT_CLASS (ctk_window_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), (((GType) ((20) << (2))
))))))
->dispose (object);
3167 unset_titlebar (window);
3168
3169 while (priv->popovers)
3170 {
3171 CtkWindowPopover *popover = priv->popovers->data;
3172 priv->popovers = g_list_delete_link (priv->popovers, priv->popovers);
3173 popover_destroy (popover);
3174 }
3175
3176}
3177
3178static void
3179parent_destroyed_callback (CtkWindow *parent G_GNUC_UNUSED__attribute__ ((__unused__)),
3180 CtkWindow *child)
3181{
3182 ctk_widget_destroy (CTK_WIDGET (child)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((child)), ((ctk_widget_get_type ()))))))
);
3183}
3184
3185static void
3186connect_parent_destroyed (CtkWindow *window)
3187{
3188 CtkWindowPrivate *priv = window->priv;
3189
3190 if (priv->transient_parent)
3191 {
3192 g_signal_connect (priv->transient_parent,g_signal_connect_data ((priv->transient_parent), ("destroy"
), (((GCallback) (parent_destroyed_callback))), (window), ((void
*)0), (GConnectFlags) 0)
3193 "destroy",g_signal_connect_data ((priv->transient_parent), ("destroy"
), (((GCallback) (parent_destroyed_callback))), (window), ((void
*)0), (GConnectFlags) 0)
3194 G_CALLBACK (parent_destroyed_callback),g_signal_connect_data ((priv->transient_parent), ("destroy"
), (((GCallback) (parent_destroyed_callback))), (window), ((void
*)0), (GConnectFlags) 0)
3195 window)g_signal_connect_data ((priv->transient_parent), ("destroy"
), (((GCallback) (parent_destroyed_callback))), (window), ((void
*)0), (GConnectFlags) 0)
;
3196 }
3197}
3198
3199static void
3200disconnect_parent_destroyed (CtkWindow *window)
3201{
3202 CtkWindowPrivate *priv = window->priv;
3203
3204 if (priv->transient_parent)
3205 {
3206 g_signal_handlers_disconnect_by_func (priv->transient_parent,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (parent_destroyed_callback), (window))
3207 parent_destroyed_callback,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (parent_destroyed_callback), (window))
3208 window)g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (parent_destroyed_callback), (window))
;
3209 }
3210}
3211
3212static void
3213ctk_window_transient_parent_realized (CtkWidget *parent,
3214 CtkWidget *window)
3215{
3216 if (_ctk_widget_get_realized (window))
3217 cdk_window_set_transient_for (_ctk_widget_get_window (window),
3218 _ctk_widget_get_window (parent));
3219}
3220
3221static void
3222ctk_window_transient_parent_unrealized (CtkWidget *parent G_GNUC_UNUSED__attribute__ ((__unused__)),
3223 CtkWidget *window)
3224{
3225 if (_ctk_widget_get_realized (window))
3226 cdk_property_delete (_ctk_widget_get_window (window),
3227 cdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
3228}
3229
3230static void
3231ctk_window_transient_parent_screen_changed (CtkWindow *parent,
3232 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
3233 CtkWindow *window)
3234{
3235 ctk_window_set_screen (window, parent->priv->screen);
3236}
3237
3238static void
3239ctk_window_unset_transient_for (CtkWindow *window)
3240{
3241 CtkWindowPrivate *priv = window->priv;
3242
3243 if (priv->transient_parent)
3244 {
3245 g_signal_handlers_disconnect_by_func (priv->transient_parent,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_realized), (
window))
3246 ctk_window_transient_parent_realized,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_realized), (
window))
3247 window)g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_realized), (
window))
;
3248 g_signal_handlers_disconnect_by_func (priv->transient_parent,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_unrealized)
, (window))
3249 ctk_window_transient_parent_unrealized,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_unrealized)
, (window))
3250 window)g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_unrealized)
, (window))
;
3251 g_signal_handlers_disconnect_by_func (priv->transient_parent,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_screen_changed
), (window))
3252 ctk_window_transient_parent_screen_changed,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_screen_changed
), (window))
3253 window)g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_window_transient_parent_screen_changed
), (window))
;
3254 g_signal_handlers_disconnect_by_func (priv->transient_parent,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_widget_destroyed), (&priv->transient_parent
))
3255 ctk_widget_destroyed,g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_widget_destroyed), (&priv->transient_parent
))
3256 &priv->transient_parent)g_signal_handlers_disconnect_matched ((priv->transient_parent
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (ctk_widget_destroyed), (&priv->transient_parent
))
;
3257
3258 if (priv->destroy_with_parent)
3259 disconnect_parent_destroyed (window);
3260
3261 priv->transient_parent = NULL((void*)0);
3262
3263 if (priv->transient_parent_group)
3264 {
3265 priv->transient_parent_group = FALSE(0);
3266 ctk_window_group_remove_window (priv->group,
3267 window);
3268 }
3269 }
3270}
3271
3272/**
3273 * ctk_window_set_transient_for:
3274 * @window: a #CtkWindow
3275 * @parent: (allow-none): parent window, or %NULL
3276 *
3277 * Dialog windows should be set transient for the main application
3278 * window they were spawned from. This allows
3279 * [window managers][ctk-X11-arch] to e.g. keep the
3280 * dialog on top of the main window, or center the dialog over the
3281 * main window. ctk_dialog_new_with_buttons() and other convenience
3282 * functions in CTK+ will sometimes call
3283 * ctk_window_set_transient_for() on your behalf.
3284 *
3285 * Passing %NULL for @parent unsets the current transient window.
3286 *
3287 * On Wayland, this function can also be used to attach a new
3288 * #CTK_WINDOW_POPUP to a #CTK_WINDOW_TOPLEVEL parent already mapped
3289 * on screen so that the #CTK_WINDOW_POPUP will be created as a
3290 * subsurface-based window #CDK_WINDOW_SUBSURFACE which can be
3291 * positioned at will relatively to the #CTK_WINDOW_TOPLEVEL surface.
3292 *
3293 * On Windows, this function puts the child window on top of the parent,
3294 * much as the window manager would have done on X.
3295 */
3296void
3297ctk_window_set_transient_for (CtkWindow *window,
3298 CtkWindow *parent)
3299{
3300 CtkWindowPrivate *priv;
3301
3302 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3303 g_return_if_fail (parent == NULL || CTK_IS_WINDOW (parent))do { if ((parent == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((parent)); GType __t = ((ctk_window_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "parent == NULL || CTK_IS_WINDOW (parent)"
); return; } } while (0)
;
3304 g_return_if_fail (window != parent)do { if ((window != parent)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "window != parent"); return
; } } while (0)
;
3305
3306 priv = window->priv;
3307
3308 if (priv->transient_parent)
3309 {
3310 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
) &&
3311 _ctk_widget_get_realized (CTK_WIDGET (priv->transient_parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->transient_parent)), ((ctk_widget_get_type ())))
)))
) &&
3312 (!parent || !_ctk_widget_get_realized (CTK_WIDGET (parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_widget_get_type ()))))))
)))
3313 ctk_window_transient_parent_unrealized (CTK_WIDGET (priv->transient_parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->transient_parent)), ((ctk_widget_get_type ())))
)))
,
3314 CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3315
3316 ctk_window_unset_transient_for (window);
3317 }
3318
3319 priv->transient_parent = parent;
3320
3321 if (parent)
3322 {
3323 g_signal_connect (parent, "destroy",g_signal_connect_data ((parent), ("destroy"), (((GCallback) (
ctk_widget_destroyed))), (&priv->transient_parent), ((
void*)0), (GConnectFlags) 0)
3324 G_CALLBACK (ctk_widget_destroyed),g_signal_connect_data ((parent), ("destroy"), (((GCallback) (
ctk_widget_destroyed))), (&priv->transient_parent), ((
void*)0), (GConnectFlags) 0)
3325 &priv->transient_parent)g_signal_connect_data ((parent), ("destroy"), (((GCallback) (
ctk_widget_destroyed))), (&priv->transient_parent), ((
void*)0), (GConnectFlags) 0)
;
3326 g_signal_connect (parent, "realize",g_signal_connect_data ((parent), ("realize"), (((GCallback) (
ctk_window_transient_parent_realized))), (window), ((void*)0)
, (GConnectFlags) 0)
3327 G_CALLBACK (ctk_window_transient_parent_realized),g_signal_connect_data ((parent), ("realize"), (((GCallback) (
ctk_window_transient_parent_realized))), (window), ((void*)0)
, (GConnectFlags) 0)
3328 window)g_signal_connect_data ((parent), ("realize"), (((GCallback) (
ctk_window_transient_parent_realized))), (window), ((void*)0)
, (GConnectFlags) 0)
;
3329 g_signal_connect (parent, "unrealize",g_signal_connect_data ((parent), ("unrealize"), (((GCallback)
(ctk_window_transient_parent_unrealized))), (window), ((void
*)0), (GConnectFlags) 0)
3330 G_CALLBACK (ctk_window_transient_parent_unrealized),g_signal_connect_data ((parent), ("unrealize"), (((GCallback)
(ctk_window_transient_parent_unrealized))), (window), ((void
*)0), (GConnectFlags) 0)
3331 window)g_signal_connect_data ((parent), ("unrealize"), (((GCallback)
(ctk_window_transient_parent_unrealized))), (window), ((void
*)0), (GConnectFlags) 0)
;
3332 g_signal_connect (parent, "notify::screen",g_signal_connect_data ((parent), ("notify::screen"), (((GCallback
) (ctk_window_transient_parent_screen_changed))), (window), (
(void*)0), (GConnectFlags) 0)
3333 G_CALLBACK (ctk_window_transient_parent_screen_changed),g_signal_connect_data ((parent), ("notify::screen"), (((GCallback
) (ctk_window_transient_parent_screen_changed))), (window), (
(void*)0), (GConnectFlags) 0)
3334 window)g_signal_connect_data ((parent), ("notify::screen"), (((GCallback
) (ctk_window_transient_parent_screen_changed))), (window), (
(void*)0), (GConnectFlags) 0)
;
3335
3336 ctk_window_set_screen (window, parent->priv->screen);
3337
3338 if (priv->destroy_with_parent)
3339 connect_parent_destroyed (window);
3340
3341 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
) &&
3342 _ctk_widget_get_realized (CTK_WIDGET (parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_widget_get_type ()))))))
))
3343 ctk_window_transient_parent_realized (CTK_WIDGET (parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_widget_get_type ()))))))
,
3344 CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3345
3346 if (parent->priv->group)
3347 {
3348 ctk_window_group_add_window (parent->priv->group, window);
3349 priv->transient_parent_group = TRUE(!(0));
3350 }
3351 }
3352
3353 update_window_buttons (window);
3354
3355 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_TRANSIENT_FOR]);
3356}
3357
3358/**
3359 * ctk_window_get_transient_for:
3360 * @window: a #CtkWindow
3361 *
3362 * Fetches the transient parent for this window. See
3363 * ctk_window_set_transient_for().
3364 *
3365 * Returns: (nullable) (transfer none): the transient parent for this
3366 * window, or %NULL if no transient parent has been set.
3367 **/
3368CtkWindow *
3369ctk_window_get_transient_for (CtkWindow *window)
3370{
3371 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
3372
3373 return window->priv->transient_parent;
3374}
3375
3376/**
3377 * ctk_window_set_attached_to:
3378 * @window: a #CtkWindow
3379 * @attach_widget: (allow-none): a #CtkWidget, or %NULL
3380 *
3381 * Marks @window as attached to @attach_widget. This creates a logical binding
3382 * between the window and the widget it belongs to, which is used by CTK+ to
3383 * propagate information such as styling or accessibility to @window as if it
3384 * was a children of @attach_widget.
3385 *
3386 * Examples of places where specifying this relation is useful are for instance
3387 * a #CtkMenu created by a #CtkComboBox, a completion popup window
3388 * created by #CtkEntry or a typeahead search entry created by #CtkTreeView.
3389 *
3390 * Note that this function should not be confused with
3391 * ctk_window_set_transient_for(), which specifies a window manager relation
3392 * between two toplevels instead.
3393 *
3394 * Passing %NULL for @attach_widget detaches the window.
3395 *
3396 * Since: 3.4
3397 **/
3398void
3399ctk_window_set_attached_to (CtkWindow *window,
3400 CtkWidget *attach_widget)
3401{
3402 CtkStyleContext *context;
3403 CtkWindowPrivate *priv;
3404
3405 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3406 g_return_if_fail (CTK_WIDGET (window) != attach_widget)do { if ((((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
!= attach_widget)) { } else { g_return_if_fail_warning ("Ctk"
, ((const char*) (__func__)), "CTK_WIDGET (window) != attach_widget"
); return; } } while (0)
;
3407
3408 priv = window->priv;
3409
3410 if (priv->attach_widget == attach_widget)
3411 return;
3412
3413 remove_attach_widget (window);
3414
3415 priv->attach_widget = attach_widget;
3416
3417 if (priv->attach_widget)
3418 {
3419 _ctk_widget_add_attached_window (priv->attach_widget, window);
3420 }
3421
3422 /* Update the style, as the widget path might change. */
3423 context = ctk_widget_get_style_context (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3424 if (priv->attach_widget)
3425 ctk_style_context_set_parent (context, ctk_widget_get_style_context (priv->attach_widget));
3426 else
3427 ctk_style_context_set_parent (context, NULL((void*)0));
3428
3429 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ATTACHED_TO]);
3430}
3431
3432/**
3433 * ctk_window_get_attached_to:
3434 * @window: a #CtkWindow
3435 *
3436 * Fetches the attach widget for this window. See
3437 * ctk_window_set_attached_to().
3438 *
3439 * Returns: (nullable) (transfer none): the widget where the window
3440 * is attached, or %NULL if the window is not attached to any widget.
3441 *
3442 * Since: 3.4
3443 **/
3444CtkWidget *
3445ctk_window_get_attached_to (CtkWindow *window)
3446{
3447 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
3448
3449 return window->priv->attach_widget;
3450}
3451
3452/**
3453 * ctk_window_set_opacity:
3454 * @window: a #CtkWindow
3455 * @opacity: desired opacity, between 0 and 1
3456 *
3457 * Request the windowing system to make @window partially transparent,
3458 * with opacity 0 being fully transparent and 1 fully opaque. (Values
3459 * of the opacity parameter are clamped to the [0,1] range.) On X11
3460 * this has any effect only on X screens with a compositing manager
3461 * running. See ctk_widget_is_composited(). On Windows it should work
3462 * always.
3463 *
3464 * Note that setting a window’s opacity after the window has been
3465 * shown causes it to flicker once on Windows.
3466 *
3467 * Since: 2.12
3468 * Deprecated: 3.8: Use ctk_widget_set_opacity instead.
3469 **/
3470void
3471ctk_window_set_opacity (CtkWindow *window,
3472 gdouble opacity)
3473{
3474 ctk_widget_set_opacity (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
, opacity);
3475}
3476
3477/**
3478 * ctk_window_get_opacity:
3479 * @window: a #CtkWindow
3480 *
3481 * Fetches the requested opacity for this window. See
3482 * ctk_window_set_opacity().
3483 *
3484 * Returns: the requested opacity for this window.
3485 *
3486 * Since: 2.12
3487 * Deprecated: 3.8: Use ctk_widget_get_opacity instead.
3488 **/
3489gdouble
3490ctk_window_get_opacity (CtkWindow *window)
3491{
3492 g_return_val_if_fail (CTK_IS_WINDOW (window), 0.0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (0.0); } } while (0)
;
3493
3494 return ctk_widget_get_opacity (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3495}
3496
3497/**
3498 * ctk_window_get_application:
3499 * @window: a #CtkWindow
3500 *
3501 * Gets the #CtkApplication associated with the window (if any).
3502 *
3503 * Returns: (nullable) (transfer none): a #CtkApplication, or %NULL
3504 *
3505 * Since: 3.0
3506 **/
3507CtkApplication *
3508ctk_window_get_application (CtkWindow *window)
3509{
3510 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
3511
3512 return window->priv->application;
3513}
3514
3515static void
3516ctk_window_release_application (CtkWindow *window)
3517{
3518 if (window->priv->application)
3519 {
3520 CtkApplication *application;
3521
3522 /* steal reference into temp variable */
3523 application = window->priv->application;
3524 window->priv->application = NULL((void*)0);
3525
3526 ctk_application_remove_window (application, window);
3527 g_object_unref (application);
3528 }
3529}
3530
3531/**
3532 * ctk_window_set_application:
3533 * @window: a #CtkWindow
3534 * @application: (allow-none): a #CtkApplication, or %NULL to unset
3535 *
3536 * Sets or unsets the #CtkApplication associated with the window.
3537 *
3538 * The application will be kept alive for at least as long as it has any windows
3539 * associated with it (see g_application_hold() for a way to keep it alive
3540 * without windows).
3541 *
3542 * Normally, the connection between the application and the window will remain
3543 * until the window is destroyed, but you can explicitly remove it by setting
3544 * the @application to %NULL.
3545 *
3546 * This is equivalent to calling ctk_application_remove_window() and/or
3547 * ctk_application_add_window() on the old/new applications as relevant.
3548 *
3549 * Since: 3.0
3550 **/
3551void
3552ctk_window_set_application (CtkWindow *window,
3553 CtkApplication *application)
3554{
3555 CtkWindowPrivate *priv;
3556
3557 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3558
3559 priv = window->priv;
3560 if (priv->application != application)
3561 {
3562 ctk_window_release_application (window);
3563
3564 priv->application = application;
3565
3566 if (priv->application != NULL((void*)0))
3567 {
3568 g_object_ref (priv->application)((__typeof__ (priv->application)) (g_object_ref) (priv->
application))
;
3569
3570 ctk_application_add_window (priv->application, window);
3571 }
3572
3573 _ctk_widget_update_parent_muxer (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3574
3575 _ctk_window_notify_keys_changed (window);
3576
3577 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_APPLICATION]);
3578 }
3579}
3580
3581/**
3582 * ctk_window_set_type_hint:
3583 * @window: a #CtkWindow
3584 * @hint: the window type
3585 *
3586 * By setting the type hint for the window, you allow the window
3587 * manager to decorate and handle the window in a way which is
3588 * suitable to the function of the window in your application.
3589 *
3590 * This function should be called before the window becomes visible.
3591 *
3592 * ctk_dialog_new_with_buttons() and other convenience functions in CTK+
3593 * will sometimes call ctk_window_set_type_hint() on your behalf.
3594 *
3595 **/
3596void
3597ctk_window_set_type_hint (CtkWindow *window,
3598 CdkWindowTypeHint hint)
3599{
3600 CtkWindowPrivate *priv;
3601 CdkWindow *cdk_window;
3602
3603 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3604
3605 priv = window->priv;
3606
3607 if (priv->type_hint == hint)
3608 return;
3609
3610 priv->type_hint = hint;
3611
3612 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3613 if (cdk_window)
3614 cdk_window_set_type_hint (cdk_window, hint);
3615
3616 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_TYPE_HINT]);
3617
3618 update_window_buttons (window);
3619}
3620
3621/**
3622 * ctk_window_get_type_hint:
3623 * @window: a #CtkWindow
3624 *
3625 * Gets the type hint for this window. See ctk_window_set_type_hint().
3626 *
3627 * Returns: the type hint for @window.
3628 **/
3629CdkWindowTypeHint
3630ctk_window_get_type_hint (CtkWindow *window)
3631{
3632 g_return_val_if_fail (CTK_IS_WINDOW (window), CDK_WINDOW_TYPE_HINT_NORMAL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (CDK_WINDOW_TYPE_HINT_NORMAL
); } } while (0)
;
3633
3634 return window->priv->type_hint;
3635}
3636
3637/**
3638 * ctk_window_set_skip_taskbar_hint:
3639 * @window: a #CtkWindow
3640 * @setting: %TRUE to keep this window from appearing in the task bar
3641 *
3642 * Windows may set a hint asking the desktop environment not to display
3643 * the window in the task bar. This function sets this hint.
3644 *
3645 * Since: 2.2
3646 **/
3647void
3648ctk_window_set_skip_taskbar_hint (CtkWindow *window,
3649 gboolean setting)
3650{
3651 CtkWindowPrivate *priv;
3652
3653 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3654
3655 priv = window->priv;
3656
3657 setting = setting != FALSE(0);
3658
3659 if (priv->skips_taskbar != setting)
3660 {
3661 priv->skips_taskbar = setting;
3662 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
3663 cdk_window_set_skip_taskbar_hint (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
3664 priv->skips_taskbar);
3665 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_SKIP_TASKBAR_HINT]);
3666 }
3667}
3668
3669/**
3670 * ctk_window_get_skip_taskbar_hint:
3671 * @window: a #CtkWindow
3672 *
3673 * Gets the value set by ctk_window_set_skip_taskbar_hint()
3674 *
3675 * Returns: %TRUE if window shouldn’t be in taskbar
3676 *
3677 * Since: 2.2
3678 **/
3679gboolean
3680ctk_window_get_skip_taskbar_hint (CtkWindow *window)
3681{
3682 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3683
3684 return window->priv->skips_taskbar;
3685}
3686
3687/**
3688 * ctk_window_set_skip_pager_hint:
3689 * @window: a #CtkWindow
3690 * @setting: %TRUE to keep this window from appearing in the pager
3691 *
3692 * Windows may set a hint asking the desktop environment not to display
3693 * the window in the pager. This function sets this hint.
3694 * (A "pager" is any desktop navigation tool such as a workspace
3695 * switcher that displays a thumbnail representation of the windows
3696 * on the screen.)
3697 *
3698 * Since: 2.2
3699 **/
3700void
3701ctk_window_set_skip_pager_hint (CtkWindow *window,
3702 gboolean setting)
3703{
3704 CtkWindowPrivate *priv;
3705
3706 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3707
3708 priv = window->priv;
3709
3710 setting = setting != FALSE(0);
3711
3712 if (priv->skips_pager != setting)
3713 {
3714 priv->skips_pager = setting;
3715 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
3716 cdk_window_set_skip_pager_hint (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
3717 priv->skips_pager);
3718 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_SKIP_PAGER_HINT]);
3719 }
3720}
3721
3722/**
3723 * ctk_window_get_skip_pager_hint:
3724 * @window: a #CtkWindow
3725 *
3726 * Gets the value set by ctk_window_set_skip_pager_hint().
3727 *
3728 * Returns: %TRUE if window shouldn’t be in pager
3729 *
3730 * Since: 2.2
3731 **/
3732gboolean
3733ctk_window_get_skip_pager_hint (CtkWindow *window)
3734{
3735 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3736
3737 return window->priv->skips_pager;
3738}
3739
3740/**
3741 * ctk_window_set_urgency_hint:
3742 * @window: a #CtkWindow
3743 * @setting: %TRUE to mark this window as urgent
3744 *
3745 * Windows may set a hint asking the desktop environment to draw
3746 * the users attention to the window. This function sets this hint.
3747 *
3748 * Since: 2.8
3749 **/
3750void
3751ctk_window_set_urgency_hint (CtkWindow *window,
3752 gboolean setting)
3753{
3754 CtkWindowPrivate *priv;
3755
3756 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3757
3758 priv = window->priv;
3759
3760 setting = setting != FALSE(0);
3761
3762 if (priv->urgent != setting)
3763 {
3764 priv->urgent = setting;
3765 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
3766 cdk_window_set_urgency_hint (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
3767 priv->urgent);
3768 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_URGENCY_HINT]);
3769 }
3770}
3771
3772/**
3773 * ctk_window_get_urgency_hint:
3774 * @window: a #CtkWindow
3775 *
3776 * Gets the value set by ctk_window_set_urgency_hint()
3777 *
3778 * Returns: %TRUE if window is urgent
3779 *
3780 * Since: 2.8
3781 **/
3782gboolean
3783ctk_window_get_urgency_hint (CtkWindow *window)
3784{
3785 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3786
3787 return window->priv->urgent;
3788}
3789
3790/**
3791 * ctk_window_set_accept_focus:
3792 * @window: a #CtkWindow
3793 * @setting: %TRUE to let this window receive input focus
3794 *
3795 * Windows may set a hint asking the desktop environment not to receive
3796 * the input focus. This function sets this hint.
3797 *
3798 * Since: 2.4
3799 **/
3800void
3801ctk_window_set_accept_focus (CtkWindow *window,
3802 gboolean setting)
3803{
3804 CtkWindowPrivate *priv;
3805
3806 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3807
3808 priv = window->priv;
3809
3810 setting = setting != FALSE(0);
3811
3812 if (priv->accept_focus != setting)
3813 {
3814 priv->accept_focus = setting;
3815 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
3816 cdk_window_set_accept_focus (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
3817 priv->accept_focus);
3818 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ACCEPT_FOCUS]);
3819 }
3820}
3821
3822/**
3823 * ctk_window_get_accept_focus:
3824 * @window: a #CtkWindow
3825 *
3826 * Gets the value set by ctk_window_set_accept_focus().
3827 *
3828 * Returns: %TRUE if window should receive the input focus
3829 *
3830 * Since: 2.4
3831 **/
3832gboolean
3833ctk_window_get_accept_focus (CtkWindow *window)
3834{
3835 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3836
3837 return window->priv->accept_focus;
3838}
3839
3840/**
3841 * ctk_window_set_focus_on_map:
3842 * @window: a #CtkWindow
3843 * @setting: %TRUE to let this window receive input focus on map
3844 *
3845 * Windows may set a hint asking the desktop environment not to receive
3846 * the input focus when the window is mapped. This function sets this
3847 * hint.
3848 *
3849 * Since: 2.6
3850 **/
3851void
3852ctk_window_set_focus_on_map (CtkWindow *window,
3853 gboolean setting)
3854{
3855 CtkWindowPrivate *priv;
3856
3857 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3858
3859 priv = window->priv;
3860
3861 setting = setting != FALSE(0);
3862
3863 if (priv->focus_on_map != setting)
3864 {
3865 priv->focus_on_map = setting;
3866 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
3867 cdk_window_set_focus_on_map (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
3868 priv->focus_on_map);
3869 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_FOCUS_ON_MAP]);
3870 }
3871}
3872
3873/**
3874 * ctk_window_get_focus_on_map:
3875 * @window: a #CtkWindow
3876 *
3877 * Gets the value set by ctk_window_set_focus_on_map().
3878 *
3879 * Returns: %TRUE if window should receive the input focus when
3880 * mapped.
3881 *
3882 * Since: 2.6
3883 **/
3884gboolean
3885ctk_window_get_focus_on_map (CtkWindow *window)
3886{
3887 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3888
3889 return window->priv->focus_on_map;
3890}
3891
3892/**
3893 * ctk_window_set_destroy_with_parent:
3894 * @window: a #CtkWindow
3895 * @setting: whether to destroy @window with its transient parent
3896 *
3897 * If @setting is %TRUE, then destroying the transient parent of @window
3898 * will also destroy @window itself. This is useful for dialogs that
3899 * shouldn’t persist beyond the lifetime of the main window they're
3900 * associated with, for example.
3901 **/
3902void
3903ctk_window_set_destroy_with_parent (CtkWindow *window,
3904 gboolean setting)
3905{
3906 CtkWindowPrivate *priv;
3907
3908 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3909
3910 priv = window->priv;
3911
3912 if (priv->destroy_with_parent == (setting != FALSE(0)))
3913 return;
3914
3915 if (priv->destroy_with_parent)
3916 {
3917 disconnect_parent_destroyed (window);
3918 }
3919 else
3920 {
3921 connect_parent_destroyed (window);
3922 }
3923
3924 priv->destroy_with_parent = setting;
3925
3926 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_DESTROY_WITH_PARENT]);
3927}
3928
3929/**
3930 * ctk_window_get_destroy_with_parent:
3931 * @window: a #CtkWindow
3932 *
3933 * Returns whether the window will be destroyed with its transient parent. See
3934 * ctk_window_set_destroy_with_parent ().
3935 *
3936 * Returns: %TRUE if the window will be destroyed with its transient parent.
3937 **/
3938gboolean
3939ctk_window_get_destroy_with_parent (CtkWindow *window)
3940{
3941 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
3942
3943 return window->priv->destroy_with_parent;
3944}
3945
3946static void
3947ctk_window_apply_hide_titlebar_when_maximized (CtkWindow *window)
3948{
3949#ifdef CDK_WINDOWING_X11
3950 CdkWindow *cdk_window;
3951 gboolean setting;
3952
3953 setting = window->priv->hide_titlebar_when_maximized;
3954 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
3955
3956 if (CDK_IS_X11_WINDOW (cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
3957 cdk_x11_window_set_hide_titlebar_when_maximized (cdk_window, setting);
3958#endif
3959}
3960
3961/**
3962 * ctk_window_set_hide_titlebar_when_maximized:
3963 * @window: a #CtkWindow
3964 * @setting: whether to hide the titlebar when @window is maximized
3965 *
3966 * If @setting is %TRUE, then @window will request that it’s titlebar
3967 * should be hidden when maximized.
3968 * This is useful for windows that don’t convey any information other
3969 * than the application name in the titlebar, to put the available
3970 * screen space to better use. If the underlying window system does not
3971 * support the request, the setting will not have any effect.
3972 *
3973 * Note that custom titlebars set with ctk_window_set_titlebar() are
3974 * not affected by this. The application is in full control of their
3975 * content and visibility anyway.
3976 *
3977 * Since: 3.4
3978 **/
3979void
3980ctk_window_set_hide_titlebar_when_maximized (CtkWindow *window,
3981 gboolean setting)
3982{
3983 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
3984
3985 if (window->priv->hide_titlebar_when_maximized == setting)
3986 return;
3987
3988 window->priv->hide_titlebar_when_maximized = setting;
3989 ctk_window_apply_hide_titlebar_when_maximized (window);
3990
3991 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED]);
3992}
3993
3994/**
3995 * ctk_window_get_hide_titlebar_when_maximized:
3996 * @window: a #CtkWindow
3997 *
3998 * Returns whether the window has requested to have its titlebar hidden
3999 * when maximized. See ctk_window_set_hide_titlebar_when_maximized ().
4000 *
4001 * Returns: %TRUE if the window has requested to have its titlebar
4002 * hidden when maximized
4003 *
4004 * Since: 3.4
4005 **/
4006gboolean
4007ctk_window_get_hide_titlebar_when_maximized (CtkWindow *window)
4008{
4009 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
4010
4011 return window->priv->hide_titlebar_when_maximized;
4012}
4013
4014static CtkWindowGeometryInfo*
4015ctk_window_get_geometry_info (CtkWindow *window,
4016 gboolean create)
4017{
4018 CtkWindowPrivate *priv = window->priv;
4019 CtkWindowGeometryInfo *info;
4020
4021 info = priv->geometry_info;
4022 if (!info && create)
4023 {
4024 info = g_new0 (CtkWindowGeometryInfo, 1)((CtkWindowGeometryInfo *) g_malloc0_n ((1), sizeof (CtkWindowGeometryInfo
)))
;
4025
4026 info->default_width = -1;
4027 info->default_height = -1;
4028 info->resize_width = -1;
4029 info->resize_height = -1;
4030 info->initial_x = 0;
4031 info->initial_y = 0;
4032 info->initial_pos_set = FALSE(0);
4033 info->default_is_geometry = FALSE(0);
4034 info->position_constraints_changed = FALSE(0);
4035 info->last.configure_request.x = 0;
4036 info->last.configure_request.y = 0;
4037 info->last.configure_request.width = -1;
4038 info->last.configure_request.height = -1;
4039 info->mask = 0;
4040 priv->geometry_info = info;
4041 }
4042
4043 return info;
4044}
4045
4046/**
4047 * ctk_window_set_geometry_hints:
4048 * @window: a #CtkWindow
4049 * @geometry_widget: (allow-none): widget the geometry hints used to be applied to
4050 * or %NULL. Since 3.20 this argument is ignored and CTK behaves as if %NULL was
4051 * set.
4052 * @geometry: (allow-none): struct containing geometry information or %NULL
4053 * @geom_mask: mask indicating which struct fields should be paid attention to
4054 *
4055 * This function sets up hints about how a window can be resized by
4056 * the user. You can set a minimum and maximum size; allowed resize
4057 * increments (e.g. for xterm, you can only resize by the size of a
4058 * character); aspect ratios; and more. See the #CdkGeometry struct.
4059 */
4060void
4061ctk_window_set_geometry_hints (CtkWindow *window,
4062 CtkWidget *geometry_widget,
4063 CdkGeometry *geometry,
4064 CdkWindowHints geom_mask)
4065{
4066 CtkWindowGeometryInfo *info;
4067
4068 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
1
Assuming '__inst' is non-null
2
Taking false branch
3
Assuming field 'g_class' is null
4
Assuming the condition is true
5
Taking true branch
4069 g_return_if_fail (geometry_widget == NULL || CTK_IS_WIDGET (geometry_widget))do { if ((geometry_widget == ((void*)0) || (((__extension__ (
{ GTypeInstance *__inst = (GTypeInstance*) ((geometry_widget)
); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (
!__inst) __r = (0); else if (__inst->g_class && __inst
->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a
(__inst, __t); __r; })))))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "geometry_widget == NULL || CTK_IS_WIDGET (geometry_widget)"
); return; } } while (0)
;
6
Loop condition is false. Exiting loop
7
Assuming 'geometry_widget' is equal to null
8
Loop condition is false. Exiting loop
4070
4071 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
4072
4073 if (geometry)
9
Assuming 'geometry' is null
10
Taking false branch
4074 info->geometry = *geometry;
4075
4076 /* We store gravity in priv->gravity not in the hints. */
4077 info->mask = geom_mask & ~(CDK_HINT_WIN_GRAVITY);
4078
4079 if (geometry_widget
10.1
'geometry_widget' is null
)
11
Taking false branch
4080 info->mask &= ~(CDK_HINT_BASE_SIZE | CDK_HINT_RESIZE_INC);
4081
4082 if (geom_mask & CDK_HINT_WIN_GRAVITY)
12
Assuming the condition is true
13
Taking true branch
4083 ctk_window_set_gravity (window, geometry->win_gravity);
14
Access to field 'win_gravity' results in a dereference of a null pointer (loaded from variable 'geometry')
4084
4085 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
4086}
4087
4088static void
4089unset_titlebar (CtkWindow *window)
4090{
4091 CtkWindowPrivate *priv = window->priv;
4092
4093 if (priv->title_box != NULL((void*)0))
4094 {
4095 g_signal_handlers_disconnect_by_func (priv->title_box,g_signal_handlers_disconnect_matched ((priv->title_box), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_titlebar_title_notify), (window))
4096 on_titlebar_title_notify,g_signal_handlers_disconnect_matched ((priv->title_box), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_titlebar_title_notify), (window))
4097 window)g_signal_handlers_disconnect_matched ((priv->title_box), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_titlebar_title_notify), (window))
;
4098 ctk_widget_unparent (priv->title_box);
4099 priv->title_box = NULL((void*)0);
4100 priv->titlebar = NULL((void*)0);
4101 }
4102}
4103
4104static gboolean
4105ctk_window_supports_client_shadow (CtkWindow *window)
4106{
4107 CdkDisplay *display;
4108 CdkScreen *screen;
4109 CdkVisual *visual;
4110
4111 screen = _ctk_window_get_screen (window);
4112 display = cdk_screen_get_display (screen);
4113
4114#ifdef CDK_WINDOWING_X11
4115 if (CDK_IS_X11_DISPLAY (display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(display)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
4116 {
4117 if (!cdk_screen_is_composited (screen))
4118 return FALSE(0);
4119
4120 if (!cdk_x11_screen_supports_net_wm_hint (screen, cdk_atom_intern_static_string ("_CTK_FRAME_EXTENTS")))
4121 return FALSE(0);
4122
4123 /* We need a visual with alpha */
4124 visual = cdk_screen_get_rgba_visual (screen);
4125 if (!visual)
4126 return FALSE(0);
4127 }
4128#endif
4129
4130#ifdef CDK_WINDOWING_WIN32
4131 if (CDK_IS_WIN32_DISPLAY (display))
4132 {
4133 if (!cdk_screen_is_composited (screen))
4134 return FALSE(0);
4135
4136 /* We need a visual with alpha */
4137 visual = cdk_screen_get_rgba_visual (screen);
4138 if (!visual)
4139 return FALSE(0);
4140 }
4141#endif
4142
4143 return TRUE(!(0));
4144}
4145
4146static void
4147ctk_window_enable_csd (CtkWindow *window)
4148{
4149 CtkWindowPrivate *priv = window->priv;
4150 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
4151 CdkVisual *visual;
4152
4153 /* We need a visual with alpha for client shadows */
4154 if (priv->use_client_shadow)
4155 {
4156 visual = cdk_screen_get_rgba_visual (ctk_widget_get_screen (widget));
4157 if (visual != NULL((void*)0))
4158 ctk_widget_set_visual (widget, visual);
4159
4160 ctk_style_context_add_class (ctk_widget_get_style_context (widget), CTK_STYLE_CLASS_CSD"csd");
4161 }
4162 else
4163 {
4164 ctk_style_context_add_class (ctk_widget_get_style_context (widget), "solid-csd");
4165 }
4166
4167 priv->client_decorated = TRUE(!(0));
4168}
4169
4170static void
4171on_titlebar_title_notify (CtkHeaderBar *titlebar,
4172 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
4173 CtkWindow *self)
4174{
4175 const gchar *title;
4176
4177 title = ctk_header_bar_get_title (titlebar);
4178 ctk_window_set_title_internal (self, title, FALSE(0));
4179}
4180
4181/**
4182 * ctk_window_set_titlebar:
4183 * @window: a #CtkWindow
4184 * @titlebar: (allow-none): the widget to use as titlebar
4185 *
4186 * Sets a custom titlebar for @window.
4187 *
4188 * A typical widget used here is #CtkHeaderBar, as it provides various features
4189 * expected of a titlebar while allowing the addition of child widgets to it.
4190 *
4191 * If you set a custom titlebar, CTK+ will do its best to convince
4192 * the window manager not to put its own titlebar on the window.
4193 * Depending on the system, this function may not work for a window
4194 * that is already visible, so you set the titlebar before calling
4195 * ctk_widget_show().
4196 *
4197 * Since: 3.10
4198 */
4199void
4200ctk_window_set_titlebar (CtkWindow *window,
4201 CtkWidget *titlebar)
4202{
4203 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
4204 CtkWindowPrivate *priv = window->priv;
4205 gboolean was_mapped;
4206
4207 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4208
4209 if ((!priv->title_box && titlebar) || (priv->title_box && !titlebar))
4210 {
4211 was_mapped = _ctk_widget_get_mapped (widget);
4212 if (_ctk_widget_get_realized (widget))
4213 {
4214 g_warning ("ctk_window_set_titlebar() called on a realized window");
4215 ctk_widget_unrealize (widget);
4216 }
4217 }
4218 else
4219 was_mapped = FALSE(0);
4220
4221 unset_titlebar (window);
4222
4223 if (titlebar == NULL((void*)0))
4224 {
4225 priv->client_decorated = FALSE(0);
4226 ctk_style_context_remove_class (ctk_widget_get_style_context (widget), CTK_STYLE_CLASS_CSD"csd");
4227
4228 goto out;
4229 }
4230
4231 priv->use_client_shadow = ctk_window_supports_client_shadow (window);
4232
4233 ctk_window_enable_csd (window);
4234 priv->title_box = titlebar;
4235 ctk_widget_set_parent (priv->title_box, widget);
4236 if (CTK_IS_HEADER_BAR (titlebar)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(titlebar)); GType __t = ((ctk_header_bar_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
4237 {
4238 g_signal_connect (titlebar, "notify::title",g_signal_connect_data ((titlebar), ("notify::title"), (((GCallback
) (on_titlebar_title_notify))), (window), ((void*)0), (GConnectFlags
) 0)
4239 G_CALLBACK (on_titlebar_title_notify), window)g_signal_connect_data ((titlebar), ("notify::title"), (((GCallback
) (on_titlebar_title_notify))), (window), ((void*)0), (GConnectFlags
) 0)
;
4240 on_titlebar_title_notify (CTK_HEADER_BAR (titlebar)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((titlebar)), ((ctk_header_bar_get_type ()))))))
, NULL((void*)0), window);
4241 }
4242
4243 ctk_style_context_add_class (ctk_widget_get_style_context (titlebar),
4244 CTK_STYLE_CLASS_TITLEBAR"titlebar");
4245
4246out:
4247 if (was_mapped)
4248 ctk_widget_map (widget);
4249}
4250
4251/**
4252 * ctk_window_get_titlebar:
4253 * @window: a #CtkWindow
4254 *
4255 * Returns the custom titlebar that has been set with
4256 * ctk_window_set_titlebar().
4257 *
4258 * Returns: (nullable) (transfer none): the custom titlebar, or %NULL
4259 *
4260 * Since: 3.16
4261 */
4262CtkWidget *
4263ctk_window_get_titlebar (CtkWindow *window)
4264{
4265 CtkWindowPrivate *priv = window->priv;
4266
4267 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
4268
4269 /* Don't return the internal titlebar */
4270 if (priv->title_box == priv->titlebar)
4271 return NULL((void*)0);
4272
4273 return priv->title_box;
4274}
4275
4276gboolean
4277_ctk_window_titlebar_shows_app_menu (CtkWindow *window)
4278{
4279 CtkWindowPrivate *priv = window->priv;
4280
4281 if (CTK_IS_HEADER_BAR (priv->title_box)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->title_box)); GType __t = ((ctk_header_bar_get_type (
))); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
4282 return _ctk_header_bar_shows_app_menu (CTK_HEADER_BAR (priv->title_box)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->title_box)), ((ctk_header_bar_get_type ()))))))
);
4283
4284 return FALSE(0);
4285}
4286
4287/**
4288 * ctk_window_set_decorated:
4289 * @window: a #CtkWindow
4290 * @setting: %TRUE to decorate the window
4291 *
4292 * By default, windows are decorated with a title bar, resize
4293 * controls, etc. Some [window managers][ctk-X11-arch]
4294 * allow CTK+ to disable these decorations, creating a
4295 * borderless window. If you set the decorated property to %FALSE
4296 * using this function, CTK+ will do its best to convince the window
4297 * manager not to decorate the window. Depending on the system, this
4298 * function may not have any effect when called on a window that is
4299 * already visible, so you should call it before calling ctk_widget_show().
4300 *
4301 * On Windows, this function always works, since there’s no window manager
4302 * policy involved.
4303 *
4304 **/
4305void
4306ctk_window_set_decorated (CtkWindow *window,
4307 gboolean setting)
4308{
4309 CtkWindowPrivate *priv;
4310 CdkWindow *cdk_window;
4311
4312 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4313
4314 priv = window->priv;
4315
4316 setting = setting != FALSE(0);
4317
4318 if (setting == priv->decorated)
4319 return;
4320
4321 priv->decorated = setting;
4322
4323 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
4324 if (cdk_window)
4325 {
4326 if (priv->decorated)
4327 {
4328 if (priv->client_decorated)
4329 cdk_window_set_decorations (cdk_window, 0);
4330 else
4331 cdk_window_set_decorations (cdk_window, CDK_DECOR_ALL);
4332 }
4333 else
4334 cdk_window_set_decorations (cdk_window, 0);
4335 }
4336
4337 update_window_buttons (window);
4338 ctk_widget_queue_resize (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
4339
4340 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_DECORATED]);
4341}
4342
4343/**
4344 * ctk_window_get_decorated:
4345 * @window: a #CtkWindow
4346 *
4347 * Returns whether the window has been set to have decorations
4348 * such as a title bar via ctk_window_set_decorated().
4349 *
4350 * Returns: %TRUE if the window has been set to have decorations
4351 **/
4352gboolean
4353ctk_window_get_decorated (CtkWindow *window)
4354{
4355 g_return_val_if_fail (CTK_IS_WINDOW (window), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((!(0))); } } while (0)
;
4356
4357 return window->priv->decorated;
4358}
4359
4360/**
4361 * ctk_window_set_deletable:
4362 * @window: a #CtkWindow
4363 * @setting: %TRUE to decorate the window as deletable
4364 *
4365 * By default, windows have a close button in the window frame. Some
4366 * [window managers][ctk-X11-arch] allow CTK+ to
4367 * disable this button. If you set the deletable property to %FALSE
4368 * using this function, CTK+ will do its best to convince the window
4369 * manager not to show a close button. Depending on the system, this
4370 * function may not have any effect when called on a window that is
4371 * already visible, so you should call it before calling ctk_widget_show().
4372 *
4373 * On Windows, this function always works, since there’s no window manager
4374 * policy involved.
4375 *
4376 * Since: 2.10
4377 */
4378void
4379ctk_window_set_deletable (CtkWindow *window,
4380 gboolean setting)
4381{
4382 CtkWindowPrivate *priv;
4383 CdkWindow *cdk_window;
4384
4385 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4386
4387 priv = window->priv;
4388
4389 setting = setting != FALSE(0);
4390
4391 if (setting == priv->deletable)
4392 return;
4393
4394 priv->deletable = setting;
4395
4396 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
4397 if (cdk_window)
4398 {
4399 if (priv->deletable)
4400 cdk_window_set_functions (cdk_window,
4401 CDK_FUNC_ALL);
4402 else
4403 cdk_window_set_functions (cdk_window,
4404 CDK_FUNC_ALL | CDK_FUNC_CLOSE);
4405 }
4406
4407 update_window_buttons (window);
4408
4409 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_DELETABLE]);
4410}
4411
4412/**
4413 * ctk_window_get_deletable:
4414 * @window: a #CtkWindow
4415 *
4416 * Returns whether the window has been set to have a close button
4417 * via ctk_window_set_deletable().
4418 *
4419 * Returns: %TRUE if the window has been set to have a close button
4420 *
4421 * Since: 2.10
4422 **/
4423gboolean
4424ctk_window_get_deletable (CtkWindow *window)
4425{
4426 g_return_val_if_fail (CTK_IS_WINDOW (window), TRUE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((!(0))); } } while (0)
;
4427
4428 return window->priv->deletable;
4429}
4430
4431static CtkWindowIconInfo*
4432get_icon_info (CtkWindow *window)
4433{
4434 return g_object_get_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, quark_ctk_window_icon_info);
4435}
4436
4437static void
4438free_icon_info (CtkWindowIconInfo *info)
4439{
4440 g_free (info->icon_name);
4441 g_slice_free (CtkWindowIconInfo, info)do { if (1) g_slice_free1 (sizeof (CtkWindowIconInfo), (info)
); else (void) ((CtkWindowIconInfo*) 0 == (info)); } while (0
)
;
4442}
4443
4444
4445static CtkWindowIconInfo*
4446ensure_icon_info (CtkWindow *window)
4447{
4448 CtkWindowIconInfo *info;
4449
4450 info = get_icon_info (window);
4451
4452 if (info == NULL((void*)0))
4453 {
4454 info = g_slice_new0 (CtkWindowIconInfo)((CtkWindowIconInfo*) g_slice_alloc0 (sizeof (CtkWindowIconInfo
)))
;
4455 g_object_set_qdata_full (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
,
4456 quark_ctk_window_icon_info,
4457 info,
4458 (GDestroyNotify)free_icon_info);
4459 }
4460
4461 return info;
4462}
4463
4464static GList *
4465icon_list_from_theme (CtkWindow *window,
4466 const gchar *name)
4467{
4468 GList *list;
4469
4470 CtkIconTheme *icon_theme;
4471 GdkPixbuf *icon;
4472 gint *sizes;
4473 gint i;
4474
4475 icon_theme = ctk_css_icon_theme_value_get_icon_theme
4476 (_ctk_style_context_peek_property (ctk_widget_get_style_context (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
4477 CTK_CSS_PROPERTY_ICON_THEME));
4478
4479 sizes = ctk_icon_theme_get_icon_sizes (icon_theme, name);
4480
4481 list = NULL((void*)0);
4482 for (i = 0; sizes[i]; i++)
4483 {
4484 /* FIXME
4485 * We need an EWMH extension to handle scalable icons
4486 * by passing their name to the WM. For now just use a
4487 * fixed size of 48.
4488 */
4489 if (sizes[i] == -1)
4490 icon = ctk_icon_theme_load_icon (icon_theme, name,
4491 48, 0, NULL((void*)0));
4492 else
4493 icon = ctk_icon_theme_load_icon (icon_theme, name,
4494 sizes[i], 0, NULL((void*)0));
4495 if (icon)
4496 list = g_list_append (list, icon);
4497 }
4498
4499 g_free (sizes);
4500
4501 return list;
4502}
4503
4504static void
4505ctk_window_realize_icon (CtkWindow *window)
4506{
4507 CtkWindowPrivate *priv = window->priv;
4508 CtkWidget *widget;
4509 CtkWindowIconInfo *info;
4510 CdkWindow *cdk_window;
4511 GList *icon_list;
4512
4513 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
4514 cdk_window = _ctk_widget_get_window (widget);
4515
4516 g_return_if_fail (cdk_window != NULL)do { if ((cdk_window != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "cdk_window != NULL"); return
; } } while (0)
;
4517
4518 /* no point setting an icon on override-redirect */
4519 if (priv->type == CTK_WINDOW_POPUP)
4520 return;
4521
4522 icon_list = NULL((void*)0);
4523
4524 info = ensure_icon_info (window);
4525
4526 if (info->realized)
4527 return;
4528
4529 info->using_default_icon = FALSE(0);
4530 info->using_parent_icon = FALSE(0);
4531 info->using_themed_icon = FALSE(0);
4532
4533 icon_list = info->icon_list;
4534
4535 /* Look up themed icon */
4536 if (icon_list == NULL((void*)0) && info->icon_name)
4537 {
4538 icon_list = icon_list_from_theme (window, info->icon_name);
4539 if (icon_list)
4540 info->using_themed_icon = TRUE(!(0));
4541 }
4542
4543 /* Inherit from transient parent */
4544 if (icon_list == NULL((void*)0) && priv->transient_parent)
4545 {
4546 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
4547 if (icon_list)
4548 info->using_parent_icon = TRUE(!(0));
4549 }
4550
4551 /* Inherit from default */
4552 if (icon_list == NULL((void*)0))
4553 {
4554 icon_list = default_icon_list;
4555 if (icon_list)
4556 info->using_default_icon = TRUE(!(0));
4557 }
4558
4559 /* Look up themed icon */
4560 if (icon_list == NULL((void*)0) && default_icon_name)
4561 {
4562 icon_list = icon_list_from_theme (window, default_icon_name);
4563 info->using_default_icon = TRUE(!(0));
4564 info->using_themed_icon = TRUE(!(0));
4565 }
4566
4567 info->realized = TRUE(!(0));
4568
4569 cdk_window_set_icon_list (cdk_window, icon_list);
4570 if (CTK_IS_HEADER_BAR (priv->title_box)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->title_box)); GType __t = ((ctk_header_bar_get_type (
))); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
4571 _ctk_header_bar_update_window_icon (CTK_HEADER_BAR (priv->title_box)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->title_box)), ((ctk_header_bar_get_type ()))))))
, window);
4572
4573 if (info->using_themed_icon)
4574 {
4575 g_list_free_full (icon_list, g_object_unref);
4576 }
4577}
4578
4579static GdkPixbuf *
4580icon_from_list (GList *list,
4581 gint size)
4582{
4583 GdkPixbuf *best;
4584 GdkPixbuf *pixbuf;
4585 GList *l;
4586
4587 best = NULL((void*)0);
4588 for (l = list; l; l = l->next)
4589 {
4590 pixbuf = list->data;
4591 if (gdk_pixbuf_get_width (pixbuf) <= size &&
4592 gdk_pixbuf_get_height (pixbuf) <= size)
4593 {
4594 best = g_object_ref (pixbuf)((__typeof__ (pixbuf)) (g_object_ref) (pixbuf));
4595 break;
4596 }
4597 }
4598
4599 if (best == NULL((void*)0))
4600 best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data)((((GdkPixbuf*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((list->data)), ((gdk_pixbuf_get_type ()))))))
, size, size, GDK_INTERP_BILINEAR);
4601
4602 return best;
4603}
4604
4605static GdkPixbuf *
4606icon_from_name (const gchar *name,
4607 gint size)
4608{
4609 return ctk_icon_theme_load_icon (ctk_icon_theme_get_default (),
4610 name, size,
4611 CTK_ICON_LOOKUP_FORCE_SIZE, NULL((void*)0));
4612}
4613
4614GdkPixbuf *
4615ctk_window_get_icon_for_size (CtkWindow *window,
4616 gint size)
4617{
4618 CtkWindowPrivate *priv = window->priv;
4619 CtkWindowIconInfo *info;
4620 const gchar *name;
4621
4622 info = ensure_icon_info (window);
4623
4624 if (info->icon_list != NULL((void*)0))
4625 return icon_from_list (info->icon_list, size);
4626
4627 name = ctk_window_get_icon_name (window);
4628 if (name != NULL((void*)0))
4629 return icon_from_name (name, size);
4630
4631 if (priv->transient_parent != NULL((void*)0))
4632 {
4633 info = ensure_icon_info (priv->transient_parent);
4634 if (info->icon_list)
4635 return icon_from_list (info->icon_list, size);
4636 }
4637
4638 if (default_icon_list != NULL((void*)0))
4639 return icon_from_list (default_icon_list, size);
4640
4641 if (default_icon_name != NULL((void*)0))
4642 return icon_from_name (default_icon_name, size);
4643
4644 return NULL((void*)0);
4645}
4646
4647static void
4648ctk_window_unrealize_icon (CtkWindow *window)
4649{
4650 CtkWindowIconInfo *info;
4651
4652 info = get_icon_info (window);
4653
4654 if (info == NULL((void*)0))
4655 return;
4656
4657 /* We don't clear the properties on the window, just figure the
4658 * window is going away.
4659 */
4660
4661 info->realized = FALSE(0);
4662
4663}
4664
4665/**
4666 * ctk_window_set_icon_list:
4667 * @window: a #CtkWindow
4668 * @list: (element-type GdkPixbuf): list of #GdkPixbuf
4669 *
4670 * Sets up the icon representing a #CtkWindow. The icon is used when
4671 * the window is minimized (also known as iconified). Some window
4672 * managers or desktop environments may also place it in the window
4673 * frame, or display it in other contexts. On others, the icon is not
4674 * used at all, so your mileage may vary.
4675 *
4676 * ctk_window_set_icon_list() allows you to pass in the same icon in
4677 * several hand-drawn sizes. The list should contain the natural sizes
4678 * your icon is available in; that is, don’t scale the image before
4679 * passing it to CTK+. Scaling is postponed until the last minute,
4680 * when the desired final size is known, to allow best quality.
4681 *
4682 * By passing several sizes, you may improve the final image quality
4683 * of the icon, by reducing or eliminating automatic image scaling.
4684 *
4685 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
4686 * larger images (64x64, 128x128) if you have them.
4687 *
4688 * See also ctk_window_set_default_icon_list() to set the icon
4689 * for all windows in your application in one go.
4690 *
4691 * Note that transient windows (those who have been set transient for another
4692 * window using ctk_window_set_transient_for()) will inherit their
4693 * icon from their transient parent. So there’s no need to explicitly
4694 * set the icon on transient windows.
4695 **/
4696void
4697ctk_window_set_icon_list (CtkWindow *window,
4698 GList *list)
4699{
4700 CtkWindowIconInfo *info;
4701
4702 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4703
4704 info = ensure_icon_info (window);
4705
4706 if (info->icon_list == list) /* check for NULL mostly */
4707 return;
4708
4709 g_list_foreach (list,
4710 (GFunc) g_object_ref, NULL((void*)0));
4711
4712 g_list_free_full (info->icon_list, g_object_unref);
4713
4714 info->icon_list = g_list_copy (list);
4715
4716 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ICON]);
4717
4718 ctk_window_unrealize_icon (window);
4719
4720 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
4721 ctk_window_realize_icon (window);
4722
4723 /* We could try to update our transient children, but I don't think
4724 * it's really worth it. If we did it, the best way would probably
4725 * be to have children connect to notify::icon-list
4726 */
4727}
4728
4729/**
4730 * ctk_window_get_icon_list:
4731 * @window: a #CtkWindow
4732 *
4733 * Retrieves the list of icons set by ctk_window_set_icon_list().
4734 * The list is copied, but the reference count on each
4735 * member won’t be incremented.
4736 *
4737 * Returns: (element-type GdkPixbuf) (transfer container): copy of window’s icon list
4738 **/
4739GList*
4740ctk_window_get_icon_list (CtkWindow *window)
4741{
4742 CtkWindowIconInfo *info;
4743
4744 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
4745
4746 info = get_icon_info (window);
4747
4748 if (info)
4749 return g_list_copy (info->icon_list);
4750 else
4751 return NULL((void*)0);
4752}
4753
4754/**
4755 * ctk_window_set_icon:
4756 * @window: a #CtkWindow
4757 * @icon: (allow-none): icon image, or %NULL
4758 *
4759 * Sets up the icon representing a #CtkWindow. This icon is used when
4760 * the window is minimized (also known as iconified). Some window
4761 * managers or desktop environments may also place it in the window
4762 * frame, or display it in other contexts. On others, the icon is not
4763 * used at all, so your mileage may vary.
4764 *
4765 * The icon should be provided in whatever size it was naturally
4766 * drawn; that is, don’t scale the image before passing it to
4767 * CTK+. Scaling is postponed until the last minute, when the desired
4768 * final size is known, to allow best quality.
4769 *
4770 * If you have your icon hand-drawn in multiple sizes, use
4771 * ctk_window_set_icon_list(). Then the best size will be used.
4772 *
4773 * This function is equivalent to calling ctk_window_set_icon_list()
4774 * with a 1-element list.
4775 *
4776 * See also ctk_window_set_default_icon_list() to set the icon
4777 * for all windows in your application in one go.
4778 **/
4779void
4780ctk_window_set_icon (CtkWindow *window,
4781 GdkPixbuf *icon)
4782{
4783 GList *list;
4784
4785 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4786 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon))do { if ((icon == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((icon)); GType __t = ((gdk_pixbuf_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "icon == NULL || GDK_IS_PIXBUF (icon)");
return; } } while (0)
;
4787
4788 list = NULL((void*)0);
4789
4790 if (icon)
4791 list = g_list_append (list, icon);
4792
4793 ctk_window_set_icon_list (window, list);
4794 g_list_free (list);
4795}
4796
4797
4798static void
4799update_themed_icon (CtkWindow *window)
4800{
4801 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ICON_NAME]);
4802
4803 ctk_window_unrealize_icon (window);
4804
4805 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
4806 ctk_window_realize_icon (window);
4807}
4808
4809/**
4810 * ctk_window_set_icon_name:
4811 * @window: a #CtkWindow
4812 * @name: (allow-none): the name of the themed icon
4813 *
4814 * Sets the icon for the window from a named themed icon.
4815 * See the docs for #CtkIconTheme for more details.
4816 * On some platforms, the window icon is not used at all.
4817 *
4818 * Note that this has nothing to do with the WM_ICON_NAME
4819 * property which is mentioned in the ICCCM.
4820 *
4821 * Since: 2.6
4822 */
4823void
4824ctk_window_set_icon_name (CtkWindow *window,
4825 const gchar *name)
4826{
4827 CtkWindowIconInfo *info;
4828 gchar *tmp;
4829
4830 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
4831
4832 info = ensure_icon_info (window);
4833
4834 if (g_strcmp0 (info->icon_name, name) == 0)
4835 return;
4836
4837 tmp = info->icon_name;
4838 info->icon_name = g_strdup (name)g_strdup_inline (name);
4839 g_free (tmp);
4840
4841 g_list_free_full (info->icon_list, g_object_unref);
4842 info->icon_list = NULL((void*)0);
4843
4844 update_themed_icon (window);
4845
4846 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_ICON_NAME]);
4847}
4848
4849/**
4850 * ctk_window_get_icon_name:
4851 * @window: a #CtkWindow
4852 *
4853 * Returns the name of the themed icon for the window,
4854 * see ctk_window_set_icon_name().
4855 *
4856 * Returns: (nullable): the icon name or %NULL if the window has
4857 * no themed icon
4858 *
4859 * Since: 2.6
4860 */
4861const gchar *
4862ctk_window_get_icon_name (CtkWindow *window)
4863{
4864 CtkWindowIconInfo *info;
4865
4866 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
4867
4868 info = ensure_icon_info (window);
4869
4870 return info->icon_name;
4871}
4872
4873/**
4874 * ctk_window_get_icon:
4875 * @window: a #CtkWindow
4876 *
4877 * Gets the value set by ctk_window_set_icon() (or if you've
4878 * called ctk_window_set_icon_list(), gets the first icon in
4879 * the icon list).
4880 *
4881 * Returns: (transfer none) (nullable): icon for window or %NULL if none
4882 **/
4883GdkPixbuf*
4884ctk_window_get_icon (CtkWindow *window)
4885{
4886 CtkWindowIconInfo *info;
4887
4888 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
4889
4890 info = get_icon_info (window);
4891 if (info && info->icon_list)
4892 return GDK_PIXBUF (info->icon_list->data)((((GdkPixbuf*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info->icon_list->data)), ((gdk_pixbuf_get_type ())
)))))
;
4893 else
4894 return NULL((void*)0);
4895}
4896
4897/* Load pixbuf, printing warning on failure if error == NULL
4898 */
4899static GdkPixbuf *
4900load_pixbuf_verbosely (const char *filename,
4901 GError **err)
4902{
4903 GError *local_err = NULL((void*)0);
4904 GdkPixbuf *pixbuf;
4905
4906 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
4907
4908 if (!pixbuf)
4909 {
4910 if (err)
4911 *err = local_err;
4912 else
4913 {
4914 g_warning ("Error loading icon from file '%s':\n\t%s",
4915 filename, local_err->message);
4916 g_error_free (local_err);
4917 }
4918 }
4919
4920 return pixbuf;
4921}
4922
4923/**
4924 * ctk_window_set_icon_from_file:
4925 * @window: a #CtkWindow
4926 * @filename: (type filename): location of icon file
4927 * @err: (allow-none): location to store error, or %NULL.
4928 *
4929 * Sets the icon for @window.
4930 * Warns on failure if @err is %NULL.
4931 *
4932 * This function is equivalent to calling ctk_window_set_icon()
4933 * with a pixbuf created by loading the image from @filename.
4934 *
4935 * Returns: %TRUE if setting the icon succeeded.
4936 *
4937 * Since: 2.2
4938 **/
4939gboolean
4940ctk_window_set_icon_from_file (CtkWindow *window,
4941 const gchar *filename,
4942 GError **err)
4943{
4944 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
4945
4946 if (pixbuf)
4947 {
4948 ctk_window_set_icon (window, pixbuf);
4949 g_object_unref (pixbuf);
4950
4951 return TRUE(!(0));
4952 }
4953 else
4954 return FALSE(0);
4955}
4956
4957/**
4958 * ctk_window_set_default_icon_list:
4959 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
4960 *
4961 * Sets an icon list to be used as fallback for windows that haven't
4962 * had ctk_window_set_icon_list() called on them to set up a
4963 * window-specific icon list. This function allows you to set up the
4964 * icon for all windows in your app at once.
4965 *
4966 * See ctk_window_set_icon_list() for more details.
4967 *
4968 **/
4969void
4970ctk_window_set_default_icon_list (GList *list)
4971{
4972 GList *toplevels;
4973 GList *tmp_list;
4974 if (list == default_icon_list)
4975 return;
4976
4977 /* Update serial so we don't used cached pixmaps/masks
4978 */
4979 default_icon_serial++;
4980
4981 g_list_foreach (list,
4982 (GFunc) g_object_ref, NULL((void*)0));
4983
4984 g_list_free_full (default_icon_list, g_object_unref);
4985
4986 default_icon_list = g_list_copy (list);
4987
4988 /* Update all toplevels */
4989 toplevels = ctk_window_list_toplevels ();
4990 tmp_list = toplevels;
4991 while (tmp_list != NULL((void*)0))
4992 {
4993 CtkWindowIconInfo *info;
4994 CtkWindow *w = tmp_list->data;
4995
4996 info = get_icon_info (w);
4997 if (info && info->using_default_icon)
4998 {
4999 ctk_window_unrealize_icon (w);
5000 if (_ctk_widget_get_realized (CTK_WIDGET (w)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_widget_get_type ()))))))
))
5001 ctk_window_realize_icon (w);
5002 }
5003
5004 tmp_list = tmp_list->next;
5005 }
5006 g_list_free (toplevels);
5007}
5008
5009/**
5010 * ctk_window_set_default_icon:
5011 * @icon: the icon
5012 *
5013 * Sets an icon to be used as fallback for windows that haven't
5014 * had ctk_window_set_icon() called on them from a pixbuf.
5015 *
5016 * Since: 2.4
5017 **/
5018void
5019ctk_window_set_default_icon (GdkPixbuf *icon)
5020{
5021 GList *list;
5022
5023 g_return_if_fail (GDK_IS_PIXBUF (icon))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((icon)); GType __t = ((gdk_pixbuf_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "GDK_IS_PIXBUF (icon)"); return; } } while (0)
;
5024
5025 list = g_list_prepend (NULL((void*)0), icon);
5026 ctk_window_set_default_icon_list (list);
5027 g_list_free (list);
5028}
5029
5030/**
5031 * ctk_window_set_default_icon_name:
5032 * @name: the name of the themed icon
5033 *
5034 * Sets an icon to be used as fallback for windows that haven't
5035 * had ctk_window_set_icon_list() called on them from a named
5036 * themed icon, see ctk_window_set_icon_name().
5037 *
5038 * Since: 2.6
5039 **/
5040void
5041ctk_window_set_default_icon_name (const gchar *name)
5042{
5043 GList *tmp_list;
5044 GList *toplevels;
5045
5046 /* Update serial so we don't used cached pixmaps/masks
5047 */
5048 default_icon_serial++;
5049
5050 g_free (default_icon_name);
5051 default_icon_name = g_strdup (name)g_strdup_inline (name);
5052
5053 g_list_free_full (default_icon_list, g_object_unref);
5054 default_icon_list = NULL((void*)0);
5055
5056 /* Update all toplevels */
5057 toplevels = ctk_window_list_toplevels ();
5058 tmp_list = toplevels;
5059 while (tmp_list != NULL((void*)0))
5060 {
5061 CtkWindowIconInfo *info;
5062 CtkWindow *w = tmp_list->data;
5063
5064 info = get_icon_info (w);
5065 if (info && info->using_default_icon && info->using_themed_icon)
5066 {
5067 ctk_window_unrealize_icon (w);
5068 if (_ctk_widget_get_realized (CTK_WIDGET (w)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_widget_get_type ()))))))
))
5069 ctk_window_realize_icon (w);
5070 }
5071
5072 tmp_list = tmp_list->next;
5073 }
5074 g_list_free (toplevels);
5075}
5076
5077/**
5078 * ctk_window_get_default_icon_name:
5079 *
5080 * Returns the fallback icon name for windows that has been set
5081 * with ctk_window_set_default_icon_name(). The returned
5082 * string is owned by CTK+ and should not be modified. It
5083 * is only valid until the next call to
5084 * ctk_window_set_default_icon_name().
5085 *
5086 * Returns: the fallback icon name for windows
5087 *
5088 * Since: 2.16
5089 */
5090const gchar *
5091ctk_window_get_default_icon_name (void)
5092{
5093 return default_icon_name;
5094}
5095
5096/**
5097 * ctk_window_set_default_icon_from_file:
5098 * @filename: (type filename): location of icon file
5099 * @err: (allow-none): location to store error, or %NULL.
5100 *
5101 * Sets an icon to be used as fallback for windows that haven't
5102 * had ctk_window_set_icon_list() called on them from a file
5103 * on disk. Warns on failure if @err is %NULL.
5104 *
5105 * Returns: %TRUE if setting the icon succeeded.
5106 *
5107 * Since: 2.2
5108 **/
5109gboolean
5110ctk_window_set_default_icon_from_file (const gchar *filename,
5111 GError **err)
5112{
5113 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
5114
5115 if (pixbuf)
5116 {
5117 ctk_window_set_default_icon (pixbuf);
5118 g_object_unref (pixbuf);
5119
5120 return TRUE(!(0));
5121 }
5122 else
5123 return FALSE(0);
5124}
5125
5126/**
5127 * ctk_window_get_default_icon_list:
5128 *
5129 * Gets the value set by ctk_window_set_default_icon_list().
5130 * The list is a copy and should be freed with g_list_free(),
5131 * but the pixbufs in the list have not had their reference count
5132 * incremented.
5133 *
5134 * Returns: (element-type GdkPixbuf) (transfer container): copy of default icon list
5135 **/
5136GList*
5137ctk_window_get_default_icon_list (void)
5138{
5139 return g_list_copy (default_icon_list);
5140}
5141
5142#define INCLUDE_CSD_SIZE 1
5143#define EXCLUDE_CSD_SIZE -1
5144
5145static void
5146ctk_window_update_csd_size (CtkWindow *window,
5147 gint *width,
5148 gint *height,
5149 gint apply)
5150{
5151 CtkWindowPrivate *priv = window->priv;
5152 CtkBorder window_border = { 0 };
5153 gint w, h;
5154
5155 if (priv->type != CTK_WINDOW_TOPLEVEL)
5156 return;
5157
5158 if (!priv->decorated ||
5159 priv->fullscreen)
5160 return;
5161
5162 get_shadow_width (window, &window_border);
5163 w = *width + apply * (window_border.left + window_border.right);
5164 h = *height + apply * (window_border.top + window_border.bottom);
5165
5166 if (priv->title_box != NULL((void*)0) &&
5167 ctk_widget_get_visible (priv->title_box) &&
5168 ctk_widget_get_child_visible (priv->title_box))
5169 {
5170 gint minimum_height;
5171 gint natural_height;
5172
5173 ctk_widget_get_preferred_height (priv->title_box, &minimum_height, &natural_height);
5174 h += apply * natural_height;
5175 }
5176
5177 /* Make sure the size remains acceptable */
5178 if (w < 1)
5179 w = 1;
5180 if (h < 1)
5181 h = 1;
5182
5183 /* Only update given size if not negative */
5184 if (*width > -1)
5185 *width = w;
5186 if (*height > -1)
5187 *height = h;
5188}
5189
5190static void
5191ctk_window_set_default_size_internal (CtkWindow *window,
5192 gboolean change_width,
5193 gint width,
5194 gboolean change_height,
5195 gint height,
5196 gboolean is_geometry)
5197{
5198 CtkWindowGeometryInfo *info;
5199
5200 g_return_if_fail (change_width == FALSE || width >= -1)do { if ((change_width == (0) || width >= -1)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "change_width == FALSE || width >= -1"
); return; } } while (0)
;
5201 g_return_if_fail (change_height == FALSE || height >= -1)do { if ((change_height == (0) || height >= -1)) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"change_height == FALSE || height >= -1"); return; } } while
(0)
;
5202
5203 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
5204
5205 g_object_freeze_notify (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
);
5206
5207 info->default_is_geometry = is_geometry != FALSE(0);
5208
5209 if (change_width)
5210 {
5211 if (width == 0)
5212 width = 1;
5213
5214 if (width < 0)
5215 width = -1;
5216
5217 if (info->default_width != width)
5218 {
5219 info->default_width = width;
5220 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_DEFAULT_WIDTH]);
5221 }
5222 }
5223
5224 if (change_height)
5225 {
5226 if (height == 0)
5227 height = 1;
5228
5229 if (height < 0)
5230 height = -1;
5231
5232 if (info->default_height != height)
5233 {
5234 info->default_height = height;
5235 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_DEFAULT_HEIGHT]);
5236 }
5237 }
5238
5239 g_object_thaw_notify (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
);
5240
5241 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
5242}
5243
5244/**
5245 * ctk_window_set_default_size:
5246 * @window: a #CtkWindow
5247 * @width: width in pixels, or -1 to unset the default width
5248 * @height: height in pixels, or -1 to unset the default height
5249 *
5250 * Sets the default size of a window. If the window’s “natural” size
5251 * (its size request) is larger than the default, the default will be
5252 * ignored. More generally, if the default size does not obey the
5253 * geometry hints for the window (ctk_window_set_geometry_hints() can
5254 * be used to set these explicitly), the default size will be clamped
5255 * to the nearest permitted size.
5256 *
5257 * Unlike ctk_widget_set_size_request(), which sets a size request for
5258 * a widget and thus would keep users from shrinking the window, this
5259 * function only sets the initial size, just as if the user had
5260 * resized the window themselves. Users can still shrink the window
5261 * again as they normally would. Setting a default size of -1 means to
5262 * use the “natural” default size (the size request of the window).
5263 *
5264 * For more control over a window’s initial size and how resizing works,
5265 * investigate ctk_window_set_geometry_hints().
5266 *
5267 * For some uses, ctk_window_resize() is a more appropriate function.
5268 * ctk_window_resize() changes the current size of the window, rather
5269 * than the size to be used on initial display. ctk_window_resize() always
5270 * affects the window itself, not the geometry widget.
5271 *
5272 * The default size of a window only affects the first time a window is
5273 * shown; if a window is hidden and re-shown, it will remember the size
5274 * it had prior to hiding, rather than using the default size.
5275 *
5276 * Windows can’t actually be 0x0 in size, they must be at least 1x1, but
5277 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
5278 *
5279 * If you use this function to reestablish a previously saved window size,
5280 * note that the appropriate size to save is the one returned by
5281 * ctk_window_get_size(). Using the window allocation directly will not
5282 * work in all circumstances and can lead to growing or shrinking windows.
5283 */
5284void
5285ctk_window_set_default_size (CtkWindow *window,
5286 gint width,
5287 gint height)
5288{
5289 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5290 g_return_if_fail (width >= -1)do { if ((width >= -1)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "width >= -1"); return
; } } while (0)
;
5291 g_return_if_fail (height >= -1)do { if ((height >= -1)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "height >= -1"); return
; } } while (0)
;
5292
5293 ctk_window_set_default_size_internal (window, TRUE(!(0)), width, TRUE(!(0)), height, FALSE(0));
5294}
5295
5296/**
5297 * ctk_window_set_default_geometry:
5298 * @window: a #CtkWindow
5299 * @width: width in resize increments, or -1 to unset the default width
5300 * @height: height in resize increments, or -1 to unset the default height
5301 *
5302 * Like ctk_window_set_default_size(), but @width and @height are interpreted
5303 * in terms of the base size and increment set with
5304 * ctk_window_set_geometry_hints.
5305 *
5306 * Since: 3.0
5307 *
5308 * Deprecated: 3.20: This function does nothing. If you want to set a default
5309 * size, use ctk_window_set_default_size() instead.
5310 */
5311void
5312ctk_window_set_default_geometry (CtkWindow *window,
5313 gint width,
5314 gint height)
5315{
5316 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5317 g_return_if_fail (width >= -1)do { if ((width >= -1)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "width >= -1"); return
; } } while (0)
;
5318 g_return_if_fail (height >= -1)do { if ((height >= -1)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "height >= -1"); return
; } } while (0)
;
5319
5320 ctk_window_set_default_size_internal (window, TRUE(!(0)), width, TRUE(!(0)), height, TRUE(!(0)));
5321}
5322
5323/**
5324 * ctk_window_get_default_size:
5325 * @window: a #CtkWindow
5326 * @width: (out) (allow-none): location to store the default width, or %NULL
5327 * @height: (out) (allow-none): location to store the default height, or %NULL
5328 *
5329 * Gets the default size of the window. A value of -1 for the width or
5330 * height indicates that a default size has not been explicitly set
5331 * for that dimension, so the “natural” size of the window will be
5332 * used.
5333 *
5334 **/
5335void
5336ctk_window_get_default_size (CtkWindow *window,
5337 gint *width,
5338 gint *height)
5339{
5340 CtkWindowGeometryInfo *info;
5341
5342 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5343
5344 info = ctk_window_get_geometry_info (window, FALSE(0));
5345
5346 if (width)
5347 *width = info ? info->default_width : -1;
5348
5349 if (height)
5350 *height = info ? info->default_height : -1;
5351}
5352
5353/**
5354 * ctk_window_resize:
5355 * @window: a #CtkWindow
5356 * @width: width in pixels to resize the window to
5357 * @height: height in pixels to resize the window to
5358 *
5359 * Resizes the window as if the user had done so, obeying geometry
5360 * constraints. The default geometry constraint is that windows may
5361 * not be smaller than their size request; to override this
5362 * constraint, call ctk_widget_set_size_request() to set the window's
5363 * request to a smaller value.
5364 *
5365 * If ctk_window_resize() is called before showing a window for the
5366 * first time, it overrides any default size set with
5367 * ctk_window_set_default_size().
5368 *
5369 * Windows may not be resized smaller than 1 by 1 pixels.
5370 *
5371 * When using client side decorations, CTK+ will do its best to adjust
5372 * the given size so that the resulting window size matches the
5373 * requested size without the title bar, borders and shadows added for
5374 * the client side decorations, but there is no guarantee that the
5375 * result will be totally accurate because these widgets added for
5376 * client side decorations depend on the theme and may not be realized
5377 * or visible at the time ctk_window_resize() is issued.
5378 *
5379 * If the CtkWindow has a titlebar widget (see ctk_window_set_titlebar()), then
5380 * typically, ctk_window_resize() will compensate for the height of the titlebar
5381 * widget only if the height is known when the resulting CtkWindow configuration
5382 * is issued.
5383 * For example, if new widgets are added after the CtkWindow configuration
5384 * and cause the titlebar widget to grow in height, this will result in a
5385 * window content smaller that specified by ctk_window_resize() and not
5386 * a larger window.
5387 *
5388 **/
5389void
5390ctk_window_resize (CtkWindow *window,
5391 gint width,
5392 gint height)
5393{
5394 CtkWindowGeometryInfo *info;
5395
5396 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5397 g_return_if_fail (width > 0)do { if ((width > 0)) { } else { g_return_if_fail_warning (
"Ctk", ((const char*) (__func__)), "width > 0"); return; }
} while (0)
;
5398 g_return_if_fail (height > 0)do { if ((height > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "height > 0"); return
; } } while (0)
;
5399
5400 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
5401
5402 info->resize_width = width;
5403 info->resize_height = height;
5404
5405 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
5406}
5407
5408/**
5409 * ctk_window_resize_to_geometry:
5410 * @window: a #CtkWindow
5411 * @width: width in resize increments to resize the window to
5412 * @height: height in resize increments to resize the window to
5413 *
5414 * Like ctk_window_resize(), but @width and @height are interpreted
5415 * in terms of the base size and increment set with
5416 * ctk_window_set_geometry_hints.
5417 *
5418 * Since: 3.0
5419 *
5420 * Deprecated: 3.20: This function does nothing. Use
5421 * ctk_window_resize() and compute the geometry yourself.
5422 */
5423void
5424ctk_window_resize_to_geometry (CtkWindow *window,
5425 gint width,
5426 gint height)
5427{
5428 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5429 g_return_if_fail (width > 0)do { if ((width > 0)) { } else { g_return_if_fail_warning (
"Ctk", ((const char*) (__func__)), "width > 0"); return; }
} while (0)
;
5430 g_return_if_fail (height > 0)do { if ((height > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "height > 0"); return
; } } while (0)
;
5431}
5432
5433/**
5434 * ctk_window_get_size:
5435 * @window: a #CtkWindow
5436 * @width: (out) (nullable): return location for width, or %NULL
5437 * @height: (out) (nullable): return location for height, or %NULL
5438 *
5439 * Obtains the current size of @window.
5440 *
5441 * If @window is not visible on screen, this function return the size CTK+
5442 * will suggest to the [window manager][ctk-X11-arch] for the initial window
5443 * size (but this is not reliably the same as the size the window manager
5444 * will actually select). See: ctk_window_set_default_size().
5445 *
5446 * Depending on the windowing system and the window manager constraints,
5447 * the size returned by this function may not match the size set using
5448 * ctk_window_resize(); additionally, since ctk_window_resize() may be
5449 * implemented as an asynchronous operation, CTK+ cannot guarantee in any
5450 * way that this code:
5451 *
5452 * |[<!-- language="C" -->
5453 * // width and height are set elsewhere
5454 * ctk_window_resize (window, width, height);
5455 *
5456 * int new_width, new_height;
5457 * ctk_window_get_size (window, &new_width, &new_height);
5458 * ]|
5459 *
5460 * will result in `new_width` and `new_height` matching `width` and
5461 * `height`, respectively.
5462 *
5463 * This function will return the logical size of the #CtkWindow,
5464 * excluding the widgets used in client side decorations; there is,
5465 * however, no guarantee that the result will be completely accurate
5466 * because client side decoration may include widgets that depend on
5467 * the user preferences and that may not be visibile at the time you
5468 * call this function.
5469 *
5470 * The dimensions returned by this function are suitable for being
5471 * stored across sessions; use ctk_window_set_default_size() to
5472 * restore them when before showing the window.
5473 *
5474 * To avoid potential race conditions, you should only call this
5475 * function in response to a size change notification, for instance
5476 * inside a handler for the #CtkWidget::size-allocate signal, or
5477 * inside a handler for the #CtkWidget::configure-event signal:
5478 *
5479 * |[<!-- language="C" -->
5480 * static void
5481 * on_size_allocate (CtkWidget *widget, CtkAllocation *allocation)
5482 * {
5483 * int new_width, new_height;
5484 *
5485 * ctk_window_get_size (CTK_WINDOW (widget), &new_width, &new_height);
5486 *
5487 * ...
5488 * }
5489 * ]|
5490 *
5491 * Note that, if you connect to the #CtkWidget::size-allocate signal,
5492 * you should not use the dimensions of the #CtkAllocation passed to
5493 * the signal handler, as the allocation may contain client side
5494 * decorations added by CTK+, depending on the windowing system in
5495 * use.
5496 *
5497 * If you are getting a window size in order to position the window
5498 * on the screen, you should, instead, simply set the window’s semantic
5499 * type with ctk_window_set_type_hint(), which allows the window manager
5500 * to e.g. center dialogs. Also, if you set the transient parent of
5501 * dialogs with ctk_window_set_transient_for() window managers will
5502 * often center the dialog over its parent window. It's much preferred
5503 * to let the window manager handle these cases rather than doing it
5504 * yourself, because all apps will behave consistently and according to
5505 * user or system preferences, if the window manager handles it. Also,
5506 * the window manager can take into account the size of the window
5507 * decorations and border that it may add, and of which CTK+ has no
5508 * knowledge. Additionally, positioning windows in global screen coordinates
5509 * may not be allowed by the windowing system. For more information,
5510 * see: ctk_window_set_position().
5511 */
5512void
5513ctk_window_get_size (CtkWindow *window,
5514 gint *width,
5515 gint *height)
5516{
5517 gint w, h;
5518
5519 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5520
5521 if (width == NULL((void*)0) && height == NULL((void*)0))
5522 return;
5523
5524 if (_ctk_widget_get_mapped (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
5525 {
5526 w = cdk_window_get_width (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
5527 h = cdk_window_get_height (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
5528 }
5529 else
5530 {
5531 CdkRectangle configure_request;
5532
5533 ctk_window_compute_configure_request (window,
5534 &configure_request,
5535 NULL((void*)0), NULL((void*)0));
5536
5537 w = configure_request.width;
5538 h = configure_request.height;
5539 }
5540
5541 ctk_window_update_csd_size (window, &w, &h, EXCLUDE_CSD_SIZE);
5542
5543 if (width)
5544 *width = w;
5545 if (height)
5546 *height = h;
5547}
5548
5549static void
5550ctk_window_translate_csd_pos (CtkWindow *window,
5551 gint *root_x,
5552 gint *root_y,
5553 gint apply)
5554{
5555 CtkWindowPrivate *priv = window->priv;
5556
5557 if (priv->type != CTK_WINDOW_TOPLEVEL)
5558 return;
5559
5560 if (priv->decorated &&
5561 !priv->fullscreen)
5562 {
5563 CtkBorder window_border = { 0 };
5564 gint title_height = 0;
5565 gint dx;
5566 gint dy;
5567
5568 get_shadow_width (window, &window_border);
5569 if (priv->title_box != NULL((void*)0) &&
5570 ctk_widget_get_visible (priv->title_box) &&
5571 ctk_widget_get_child_visible (priv->title_box))
5572 {
5573 gint minimum_height;
5574
5575 ctk_widget_get_preferred_height (priv->title_box, &minimum_height, &title_height);
5576 }
5577
5578 switch (priv->gravity)
5579 {
5580 case CDK_GRAVITY_NORTH:
5581 case CDK_GRAVITY_CENTER:
5582 case CDK_GRAVITY_SOUTH:
5583 dx = (window_border.left + window_border.right) / 2;
5584 break;
5585
5586 case CDK_GRAVITY_NORTH_WEST:
5587 case CDK_GRAVITY_WEST:
5588 case CDK_GRAVITY_SOUTH_WEST:
5589 case CDK_GRAVITY_SOUTH_EAST:
5590 case CDK_GRAVITY_EAST:
5591 case CDK_GRAVITY_NORTH_EAST:
5592 dx = window_border.left;
5593 break;
5594
5595 default:
5596 dx = 0;
5597 break;
5598 }
5599
5600 switch (priv->gravity)
5601 {
5602 case CDK_GRAVITY_WEST:
5603 case CDK_GRAVITY_CENTER:
5604 case CDK_GRAVITY_EAST:
5605 dy = (window_border.top + title_height + window_border.bottom) / 2;
5606 break;
5607
5608 case CDK_GRAVITY_NORTH_WEST:
5609 case CDK_GRAVITY_NORTH:
5610 case CDK_GRAVITY_NORTH_EAST:
5611 dy = window_border.top;
5612 break;
5613
5614 case CDK_GRAVITY_SOUTH_WEST:
5615 case CDK_GRAVITY_SOUTH:
5616 case CDK_GRAVITY_SOUTH_EAST:
5617 dy = window_border.top + title_height;
5618 break;
5619
5620 default:
5621 dy = 0;
5622 break;
5623 }
5624
5625 if (root_x)
5626 *root_x = *root_x + (dx * apply);
5627 if (root_y)
5628 *root_y = *root_y + (dy * apply);
5629 }
5630}
5631
5632/**
5633 * ctk_window_move:
5634 * @window: a #CtkWindow
5635 * @x: X coordinate to move window to
5636 * @y: Y coordinate to move window to
5637 *
5638 * Asks the [window manager][ctk-X11-arch] to move
5639 * @window to the given position. Window managers are free to ignore
5640 * this; most window managers ignore requests for initial window
5641 * positions (instead using a user-defined placement algorithm) and
5642 * honor requests after the window has already been shown.
5643 *
5644 * Note: the position is the position of the gravity-determined
5645 * reference point for the window. The gravity determines two things:
5646 * first, the location of the reference point in root window
5647 * coordinates; and second, which point on the window is positioned at
5648 * the reference point.
5649 *
5650 * By default the gravity is #CDK_GRAVITY_NORTH_WEST, so the reference
5651 * point is simply the @x, @y supplied to ctk_window_move(). The
5652 * top-left corner of the window decorations (aka window frame or
5653 * border) will be placed at @x, @y. Therefore, to position a window
5654 * at the top left of the screen, you want to use the default gravity
5655 * (which is #CDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
5656 *
5657 * To position a window at the bottom right corner of the screen, you
5658 * would set #CDK_GRAVITY_SOUTH_EAST, which means that the reference
5659 * point is at @x + the window width and @y + the window height, and
5660 * the bottom-right corner of the window border will be placed at that
5661 * reference point. So, to place a window in the bottom right corner
5662 * you would first set gravity to south east, then write:
5663 * `ctk_window_move (window, cdk_screen_width () - window_width,
5664 * cdk_screen_height () - window_height)` (note that this
5665 * example does not take multi-head scenarios into account).
5666 *
5667 * The [Extended Window Manager Hints Specification](http://www.freedesktop.org/Standards/wm-spec)
5668 * has a nice table of gravities in the “implementation notes” section.
5669 *
5670 * The ctk_window_get_position() documentation may also be relevant.
5671 */
5672void
5673ctk_window_move (CtkWindow *window,
5674 gint x,
5675 gint y)
5676{
5677 CtkWindowGeometryInfo *info;
5678 CtkWidget *widget;
5679
5680 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5681
5682 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
5683
5684 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
5685 ctk_window_translate_csd_pos (window, &x, &y, EXCLUDE_CSD_SIZE);
5686
5687 if (_ctk_widget_get_mapped (widget))
5688 {
5689 CtkAllocation allocation;
5690
5691 _ctk_widget_get_allocation (widget, &allocation);
5692
5693 /* we have now sent a request with this position
5694 * with currently-active constraints, so toggle flag.
5695 */
5696 info->position_constraints_changed = FALSE(0);
5697
5698 /* we only constrain if mapped - if not mapped,
5699 * then ctk_window_compute_configure_request()
5700 * will apply the constraints later, and we
5701 * don't want to lose information about
5702 * what position the user set before then.
5703 * i.e. if you do a move() then turn off POS_CENTER
5704 * then show the window, your move() will work.
5705 */
5706 ctk_window_constrain_position (window,
5707 allocation.width, allocation.height,
5708 &x, &y);
5709
5710 /* Note that this request doesn't go through our standard request
5711 * framework, e.g. doesn't increment configure_request_count,
5712 * doesn't set info->last, etc.; that's because
5713 * we don't save the info needed to arrive at this same request
5714 * again.
5715 *
5716 * To ctk_window_move_resize(), this will end up looking exactly
5717 * the same as the position being changed by the window
5718 * manager.
5719 */
5720 cdk_window_move (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
), x, y);
5721 }
5722 else
5723 {
5724 /* Save this position to apply on mapping */
5725 ctk_widget_queue_resize (widget);
5726 info->initial_x = x;
5727 info->initial_y = y;
5728 info->initial_pos_set = TRUE(!(0));
5729 }
5730}
5731
5732/**
5733 * ctk_window_get_position:
5734 * @window: a #CtkWindow
5735 * @root_x: (out) (allow-none): return location for X coordinate of
5736 * gravity-determined reference point, or %NULL
5737 * @root_y: (out) (allow-none): return location for Y coordinate of
5738 * gravity-determined reference point, or %NULL
5739 *
5740 * This function returns the position you need to pass to
5741 * ctk_window_move() to keep @window in its current position.
5742 * This means that the meaning of the returned value varies with
5743 * window gravity. See ctk_window_move() for more details.
5744 *
5745 * The reliability of this function depends on the windowing system
5746 * currently in use. Some windowing systems, such as Wayland, do not
5747 * support a global coordinate system, and thus the position of the
5748 * window will always be (0, 0). Others, like X11, do not have a reliable
5749 * way to obtain the geometry of the decorations of a window if they are
5750 * provided by the window manager. Additionally, on X11, window manager
5751 * have been known to mismanage window gravity, which result in windows
5752 * moving even if you use the coordinates of the current position as
5753 * returned by this function.
5754 *
5755 * If you haven’t changed the window gravity, its gravity will be
5756 * #CDK_GRAVITY_NORTH_WEST. This means that ctk_window_get_position()
5757 * gets the position of the top-left corner of the window manager
5758 * frame for the window. ctk_window_move() sets the position of this
5759 * same top-left corner.
5760 *
5761 * If a window has gravity #CDK_GRAVITY_STATIC the window manager
5762 * frame is not relevant, and thus ctk_window_get_position() will
5763 * always produce accurate results. However you can’t use static
5764 * gravity to do things like place a window in a corner of the screen,
5765 * because static gravity ignores the window manager decorations.
5766 *
5767 * Ideally, this function should return appropriate values if the
5768 * window has client side decorations, assuming that the windowing
5769 * system supports global coordinates.
5770 *
5771 * In practice, saving the window position should not be left to
5772 * applications, as they lack enough knowledge of the windowing
5773 * system and the window manager state to effectively do so. The
5774 * appropriate way to implement saving the window position is to
5775 * use a platform-specific protocol, wherever that is available.
5776 */
5777void
5778ctk_window_get_position (CtkWindow *window,
5779 gint *root_x,
5780 gint *root_y)
5781{
5782 CtkWindowPrivate *priv;
5783 CtkWidget *widget;
5784 CdkWindow *cdk_window;
5785
5786 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5787
5788 priv = window->priv;
5789 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
5790 cdk_window = _ctk_widget_get_window (widget);
5791
5792 if (priv->gravity == CDK_GRAVITY_STATIC)
5793 {
5794 if (_ctk_widget_get_mapped (widget))
5795 {
5796 /* This does a server round-trip, which is sort of wrong;
5797 * but a server round-trip is inevitable for
5798 * cdk_window_get_frame_extents() in the usual
5799 * NorthWestGravity case below, so not sure what else to
5800 * do. We should likely be consistent about whether we get
5801 * the client-side info or the server-side info.
5802 */
5803 cdk_window_get_origin (cdk_window, root_x, root_y);
5804 }
5805 else
5806 {
5807 CdkRectangle configure_request;
5808
5809 ctk_window_compute_configure_request (window,
5810 &configure_request,
5811 NULL((void*)0), NULL((void*)0));
5812
5813 *root_x = configure_request.x;
5814 *root_y = configure_request.y;
5815 }
5816 ctk_window_translate_csd_pos (window, root_x, root_y, INCLUDE_CSD_SIZE);
5817 }
5818 else
5819 {
5820 CdkRectangle frame_extents;
5821
5822 gint x, y;
5823 gint w, h;
5824
5825 if (_ctk_widget_get_mapped (widget))
5826 {
5827 cdk_window_get_frame_extents (cdk_window, &frame_extents);
5828 x = frame_extents.x;
5829 y = frame_extents.y;
5830 ctk_window_get_size (window, &w, &h);
5831 /* ctk_window_get_size() will have already taken into account
5832 * the padding added by the CSD shadow and title bar, so we need
5833 * to revert it here, otherwise we'll end up counting it twice...
5834 */
5835 ctk_window_update_csd_size (window, &w, &h, INCLUDE_CSD_SIZE);
5836 }
5837 else
5838 {
5839 /* We just say the frame has 0 size on all sides.
5840 * Not sure what else to do.
5841 */
5842 ctk_window_compute_configure_request (window,
5843 &frame_extents,
5844 NULL((void*)0), NULL((void*)0));
5845 x = frame_extents.x;
5846 y = frame_extents.y;
5847 w = frame_extents.width;
5848 h = frame_extents.height;
5849 }
5850
5851 ctk_window_translate_csd_pos (window, &x, &y, INCLUDE_CSD_SIZE);
5852 switch (priv->gravity)
5853 {
5854 case CDK_GRAVITY_NORTH:
5855 case CDK_GRAVITY_CENTER:
5856 case CDK_GRAVITY_SOUTH:
5857 /* Find center of frame. */
5858 x += frame_extents.width / 2;
5859 /* Center client window on that point. */
5860 x -= w / 2;
5861 break;
5862
5863 case CDK_GRAVITY_SOUTH_EAST:
5864 case CDK_GRAVITY_EAST:
5865 case CDK_GRAVITY_NORTH_EAST:
5866 /* Find right edge of frame */
5867 x += frame_extents.width;
5868 /* Align left edge of client at that point. */
5869 x -= w;
5870 break;
5871 default:
5872 break;
5873 }
5874
5875 switch (priv->gravity)
5876 {
5877 case CDK_GRAVITY_WEST:
5878 case CDK_GRAVITY_CENTER:
5879 case CDK_GRAVITY_EAST:
5880 /* Find center of frame. */
5881 y += frame_extents.height / 2;
5882 /* Center client window there. */
5883 y -= h / 2;
5884 break;
5885 case CDK_GRAVITY_SOUTH_WEST:
5886 case CDK_GRAVITY_SOUTH:
5887 case CDK_GRAVITY_SOUTH_EAST:
5888 /* Find south edge of frame */
5889 y += frame_extents.height;
5890 /* Place bottom edge of client there */
5891 y -= h;
5892 break;
5893 default:
5894 break;
5895 }
5896
5897 if (root_x)
5898 *root_x = x;
5899 if (root_y)
5900 *root_y = y;
5901 }
5902}
5903
5904/**
5905 * ctk_window_reshow_with_initial_size:
5906 * @window: a #CtkWindow
5907 *
5908 * Hides @window, then reshows it, resetting the
5909 * default size and position of the window. Used
5910 * by GUI builders only.
5911 *
5912 * Deprecated: 3.10: GUI builders can call ctk_widget_hide(),
5913 * ctk_widget_unrealize() and then ctk_widget_show() on @window
5914 * themselves, if they still need this functionality.
5915 **/
5916void
5917ctk_window_reshow_with_initial_size (CtkWindow *window)
5918{
5919 CtkWidget *widget;
5920
5921 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
5922
5923 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
5924
5925 ctk_widget_hide (widget);
5926 ctk_widget_unrealize (widget);
5927 ctk_widget_show (widget);
5928}
5929
5930static void
5931ctk_window_destroy (CtkWidget *widget)
5932{
5933 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
5934 CtkWindowPrivate *priv = window->priv;
5935
5936 ctk_window_release_application (window);
5937
5938 toplevel_list = g_slist_remove (toplevel_list, window);
5939 ctk_window_update_debugging ();
5940
5941 if (priv->transient_parent)
5942 ctk_window_set_transient_for (window, NULL((void*)0));
5943
5944 remove_attach_widget (window);
5945
5946 /* frees the icons */
5947 ctk_window_set_icon_list (window, NULL((void*)0));
5948
5949 if (priv->has_user_ref_count)
5950 {
5951 priv->has_user_ref_count = FALSE(0);
5952 g_object_unref (window);
5953 }
5954
5955 if (priv->group)
5956 ctk_window_group_remove_window (priv->group, window);
5957
5958 ctk_window_free_key_hash (window);
5959
5960 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->destroy (widget);
5961}
5962
5963static void
5964ctk_window_finalize (GObject *object)
5965{
5966 CtkWindow *window = CTK_WINDOW (object)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((ctk_window_get_type ()))))))
;
5967 CtkWindowPrivate *priv = window->priv;
5968 CtkMnemonicHash *mnemonic_hash;
5969
5970 g_free (priv->title);
5971 g_free (priv->wmclass_name);
5972 g_free (priv->wmclass_class);
5973 g_free (priv->wm_role);
5974 ctk_window_release_application (window);
5975
5976 mnemonic_hash = ctk_window_get_mnemonic_hash (window, FALSE(0));
5977 if (mnemonic_hash)
5978 _ctk_mnemonic_hash_free (mnemonic_hash);
5979
5980 if (priv->geometry_info)
5981 {
5982 g_free (priv->geometry_info);
5983 }
5984
5985 if (priv->keys_changed_handler)
5986 {
5987 g_source_remove (priv->keys_changed_handler);
5988 priv->keys_changed_handler = 0;
5989 }
5990
5991 if (priv->delete_event_handler)
5992 {
5993 g_source_remove (priv->delete_event_handler);
5994 priv->delete_event_handler = 0;
5995 }
5996
5997 if (priv->screen)
5998 {
5999 g_signal_handlers_disconnect_by_func (priv->screen,g_signal_handlers_disconnect_matched ((priv->screen), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (ctk_window_on_composited_changed), (window))
6000 ctk_window_on_composited_changed, window)g_signal_handlers_disconnect_matched ((priv->screen), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (ctk_window_on_composited_changed), (window))
;
6001#ifdef CDK_WINDOWING_X11
6002 g_signal_handlers_disconnect_by_func (ctk_settings_get_for_screen (priv->screen),g_signal_handlers_disconnect_matched ((ctk_settings_get_for_screen
(priv->screen)), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA), 0, 0, ((void*)0), (ctk_window_on_theme_variant_changed
), (window))
6003 ctk_window_on_theme_variant_changed,g_signal_handlers_disconnect_matched ((ctk_settings_get_for_screen
(priv->screen)), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA), 0, 0, ((void*)0), (ctk_window_on_theme_variant_changed
), (window))
6004 window)g_signal_handlers_disconnect_matched ((ctk_settings_get_for_screen
(priv->screen)), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA), 0, 0, ((void*)0), (ctk_window_on_theme_variant_changed
), (window))
;
6005#endif
6006 }
6007
6008 g_free (priv->startup_id);
6009
6010 if (priv->mnemonics_display_timeout_id)
6011 {
6012 g_source_remove (priv->mnemonics_display_timeout_id);
6013 priv->mnemonics_display_timeout_id = 0;
6014 }
6015
6016 if (priv->multipress_gesture)
6017 g_object_unref (priv->multipress_gesture);
6018
6019 if (priv->drag_gesture)
6020 g_object_unref (priv->drag_gesture);
6021
6022 G_OBJECT_CLASS (ctk_window_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), (((GType) ((20) << (2))
))))))
->finalize (object);
6023}
6024
6025/* copied from cdkwindow-x11.c */
6026static const gchar *
6027get_default_title (void)
6028{
6029 const gchar *title;
6030
6031 title = g_get_application_name ();
6032 if (!title)
6033 title = g_get_prgname ();
6034 if (!title)
6035 title = "";
6036
6037 return title;
6038}
6039
6040static gboolean
6041update_csd_visibility (CtkWindow *window)
6042{
6043 CtkWindowPrivate *priv = window->priv;
6044 gboolean visible;
6045
6046 if (priv->title_box == NULL((void*)0))
6047 return FALSE(0);
6048
6049 visible = priv->decorated &&
6050 !priv->fullscreen &&
6051 !(priv->titlebar == priv->title_box &&
6052 priv->maximized &&
6053 priv->hide_titlebar_when_maximized);
6054 ctk_widget_set_child_visible (priv->title_box, visible);
6055
6056 return visible;
6057}
6058
6059static void
6060update_window_buttons (CtkWindow *window)
6061{
6062 CtkWindowPrivate *priv = window->priv;
6063
6064 if (!update_csd_visibility (window))
6065 return;
6066
6067 if (CTK_IS_HEADER_BAR (priv->title_box)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(priv->title_box)); GType __t = ((ctk_header_bar_get_type (
))); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
6068 _ctk_header_bar_update_window_buttons (CTK_HEADER_BAR (priv->title_box)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->title_box)), ((ctk_header_bar_get_type ()))))))
);
6069}
6070
6071static CtkWidget *
6072create_titlebar (CtkWindow *window)
6073{
6074 CtkWindowPrivate *priv = window->priv;
6075 CtkWidget *titlebar;
6076 CtkStyleContext *context;
6077
6078 titlebar = ctk_header_bar_new ();
6079 g_object_set (titlebar,
6080 "title", priv->title ? priv->title : get_default_title (),
6081 "has-subtitle", FALSE(0),
6082 "show-close-button", TRUE(!(0)),
6083 NULL((void*)0));
6084 context = ctk_widget_get_style_context (titlebar);
6085 ctk_style_context_add_class (context, CTK_STYLE_CLASS_TITLEBAR"titlebar");
6086 ctk_style_context_add_class (context, "default-decoration");
6087
6088 return titlebar;
6089}
6090
6091void
6092_ctk_window_request_csd (CtkWindow *window)
6093{
6094 CtkWindowPrivate *priv = window->priv;
6095
6096 priv->csd_requested = TRUE(!(0));
6097}
6098
6099static gboolean
6100ctk_window_should_use_csd (CtkWindow *window)
6101{
6102 CtkWindowPrivate *priv = window->priv;
6103 const gchar *csd_env;
6104
6105 if (priv->csd_requested)
6106 return TRUE(!(0));
6107
6108 if (!priv->decorated)
6109 return FALSE(0);
6110
6111 if (priv->type == CTK_WINDOW_POPUP)
6112 return FALSE(0);
6113
6114 csd_env = g_getenv ("CTK_CSD");
6115
6116#ifdef CDK_WINDOWING_BROADWAY
6117 if (CDK_IS_BROADWAY_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
))); GType __t = ((cdk_broadway_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
6118 return TRUE(!(0));
6119#endif
6120
6121#ifdef CDK_WINDOWING_WAYLAND
6122 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
))); GType __t = ((cdk_wayland_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
6123 {
6124 CdkDisplay *cdk_display = ctk_widget_get_display (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
6125 return !cdk_wayland_display_prefers_ssd (cdk_display);
6126 }
6127#endif
6128
6129#ifdef CDK_WINDOWING_WIN32
6130 if (g_strcmp0 (csd_env, "0") != 0 &&
6131 CDK_IS_WIN32_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
)))
6132 return TRUE(!(0));
6133#endif
6134
6135 return (g_strcmp0 (csd_env, "1") == 0);
6136}
6137
6138static void
6139create_decoration (CtkWidget *widget)
6140{
6141 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
6142 CtkWindowPrivate *priv = window->priv;
6143
6144 priv->use_client_shadow = ctk_window_supports_client_shadow (window);
6145 if (!priv->use_client_shadow)
6146 return;
6147
6148 ctk_window_enable_csd (window);
6149
6150 if (priv->type == CTK_WINDOW_POPUP)
6151 return;
6152
6153 if (priv->title_box == NULL((void*)0))
6154 {
6155 priv->titlebar = create_titlebar (window);
6156 ctk_widget_set_parent (priv->titlebar, widget);
6157 ctk_widget_show_all (priv->titlebar);
6158 priv->title_box = priv->titlebar;
6159 }
6160
6161 update_window_buttons (window);
6162}
6163
6164static void
6165ctk_window_show (CtkWidget *widget)
6166{
6167 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
6168 CtkWindowPrivate *priv = window->priv;
6169 CtkContainer *container = CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
;
6170 gboolean is_plug;
6171
6172 if (!_ctk_widget_is_toplevel (CTK_WIDGET (widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_widget_get_type ()))))))
))
6173 {
6174 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->show (widget);
6175 return;
6176 }
6177
6178 _ctk_widget_set_visible_flag (widget, TRUE(!(0)));
6179
6180 ctk_css_node_validate (ctk_widget_get_css_node (widget));
6181
6182 ctk_widget_realize (widget);
6183
6184 ctk_container_check_resize (container);
6185
6186 ctk_widget_map (widget);
6187
6188 /* Try to make sure that we have some focused widget
6189 */
6190#ifdef CDK_WINDOWING_X11
6191 is_plug = CDK_IS_X11_WINDOW (_ctk_widget_get_window (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(_ctk_widget_get_window (widget))); GType __t = ((cdk_x11_window_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
&&
6192 CTK_IS_PLUG (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((ctk_plug_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
;
6193#else
6194 is_plug = FALSE(0);
6195#endif
6196 if (!priv->focus_widget && !is_plug)
6197 {
6198 if (priv->initial_focus)
6199 ctk_window_set_focus (window, priv->initial_focus);
6200 else
6201 ctk_window_move_focus (widget, CTK_DIR_TAB_FORWARD);
6202 }
6203
6204 if (priv->modal)
6205 ctk_grab_add (widget);
6206}
6207
6208static void
6209ctk_window_hide (CtkWidget *widget)
6210{
6211 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
6212 CtkWindowPrivate *priv = window->priv;
6213
6214 if (!_ctk_widget_is_toplevel (CTK_WIDGET (widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_widget_get_type ()))))))
))
6215 {
6216 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->hide (widget);
6217 return;
6218 }
6219
6220 _ctk_widget_set_visible_flag (widget, FALSE(0));
6221 ctk_widget_unmap (widget);
6222
6223 if (priv->modal)
6224 ctk_grab_remove (widget);
6225}
6226
6227static void
6228popover_unmap (CtkWidget *widget,
6229 CtkWindowPopover *popover)
6230{
6231 if (popover->unmap_id)
6232 {
6233 g_signal_handler_disconnect (widget, popover->unmap_id);
6234 popover->unmap_id = 0;
6235 }
6236
6237 if (popover->window)
6238 {
6239 cdk_window_hide (popover->window);
6240 ctk_widget_unmap (popover->widget);
6241 }
6242}
6243
6244static void
6245popover_map (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
6246 CtkWindowPopover *popover)
6247{
6248 if (popover->window && ctk_widget_get_visible (popover->widget))
6249 {
6250 cdk_window_show_unraised (popover->window);
6251 ctk_widget_map (popover->widget);
6252 popover->unmap_id = g_signal_connect (popover->widget, "unmap",g_signal_connect_data ((popover->widget), ("unmap"), (((GCallback
) (popover_unmap))), (popover), ((void*)0), (GConnectFlags) 0
)
6253 G_CALLBACK (popover_unmap), popover)g_signal_connect_data ((popover->widget), ("unmap"), (((GCallback
) (popover_unmap))), (popover), ((void*)0), (GConnectFlags) 0
)
;
6254 }
6255}
6256
6257static void
6258ctk_window_map (CtkWidget *widget)
6259{
6260 CtkWidget *child;
6261 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
6262 CtkWindowPrivate *priv = window->priv;
6263 CdkWindow *cdk_window;
6264 GList *link;
6265 CdkDisplay *display;
6266
6267 if (!_ctk_widget_is_toplevel (widget))
6268 {
6269 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->map (widget);
6270 return;
6271 }
6272
6273 display = ctk_widget_get_display (widget);
6274 if (priv->initial_fullscreen_monitor > cdk_display_get_n_monitors (display))
6275 priv->initial_fullscreen_monitor = -1;
6276
6277 ctk_widget_set_mapped (widget, TRUE(!(0)));
6278
6279 child = ctk_bin_get_child (&(window->bin));
6280 if (child != NULL((void*)0) && ctk_widget_get_visible (child))
6281 ctk_widget_map (child);
6282
6283 if (priv->title_box != NULL((void*)0) &&
6284 ctk_widget_get_visible (priv->title_box) &&
6285 ctk_widget_get_child_visible (priv->title_box))
6286 ctk_widget_map (priv->title_box);
6287
6288 cdk_window = _ctk_widget_get_window (widget);
6289
6290 if (priv->maximize_initially)
6291 cdk_window_maximize (cdk_window);
6292 else
6293 cdk_window_unmaximize (cdk_window);
6294
6295 if (priv->stick_initially)
6296 cdk_window_stick (cdk_window);
6297 else
6298 cdk_window_unstick (cdk_window);
6299
6300 if (priv->iconify_initially)
6301 cdk_window_iconify (cdk_window);
6302 else
6303 cdk_window_deiconify (cdk_window);
6304
6305 if (priv->fullscreen_initially)
6306 {
6307 if (priv->initial_fullscreen_monitor < 0)
6308 cdk_window_fullscreen (cdk_window);
6309 else
6310 cdk_window_fullscreen_on_monitor (cdk_window,
6311 priv->initial_fullscreen_monitor);
6312 }
6313 else
6314 cdk_window_unfullscreen (cdk_window);
6315
6316 cdk_window_set_keep_above (cdk_window, priv->above_initially);
6317
6318 cdk_window_set_keep_below (cdk_window, priv->below_initially);
6319
6320 if (priv->type == CTK_WINDOW_TOPLEVEL)
6321 {
6322 ctk_window_set_theme_variant (window);
6323 ctk_window_apply_hide_titlebar_when_maximized (window);
6324 }
6325
6326 /* No longer use the default settings */
6327 priv->need_default_size = FALSE(0);
6328 priv->need_default_position = FALSE(0);
6329
6330 cdk_window_show (cdk_window);
6331
6332 if (!disable_startup_notification &&
6333 !CTK_IS_OFFSCREEN_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((ctk_offscreen_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
&&
6334 priv->type != CTK_WINDOW_POPUP)
6335 {
6336 /* Do we have a custom startup-notification id? */
6337 if (priv->startup_id != NULL((void*)0))
6338 {
6339 /* Make sure we have a "real" id */
6340 if (!startup_id_is_fake (priv->startup_id))
6341 cdk_notify_startup_complete_with_id (priv->startup_id);
6342
6343 g_free (priv->startup_id);
6344 priv->startup_id = NULL((void*)0);
6345 }
6346 else
6347 {
6348 cdk_notify_startup_complete ();
6349 }
6350 }
6351
6352 /* if mnemonics visible is not already set
6353 * (as in the case of popup menus), then hide mnemonics initially
6354 */
6355 if (!priv->mnemonics_visible_set)
6356 ctk_window_set_mnemonics_visible (window, FALSE(0));
6357
6358 /* inherit from transient parent, so that a dialog that is
6359 * opened via keynav shows focus initially
6360 */
6361 if (priv->transient_parent)
6362 ctk_window_set_focus_visible (window, ctk_window_get_focus_visible (priv->transient_parent));
6363 else
6364 ctk_window_set_focus_visible (window, FALSE(0));
6365
6366 if (priv->application)
6367 ctk_application_handle_window_map (priv->application, window);
6368
6369 link = priv->popovers;
6370
6371 while (link)
6372 {
6373 CtkWindowPopover *popover = link->data;
6374 link = link->next;
6375 popover_map (popover->widget, popover);
6376 }
6377}
6378
6379static gboolean
6380ctk_window_map_event (CtkWidget *widget,
6381 CdkEventAny *event G_GNUC_UNUSED__attribute__ ((__unused__)))
6382{
6383 if (!_ctk_widget_get_mapped (widget))
6384 {
6385 /* we should be be unmapped, but are getting a MapEvent, this may happen
6386 * to toplevel XWindows if mapping was intercepted by a window manager
6387 * and an unmap request occoured while the MapRequestEvent was still
6388 * being handled. we work around this situaiton here by re-requesting
6389 * the window being unmapped. more details can be found in:
6390 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
6391 */
6392 cdk_window_hide (_ctk_widget_get_window (widget));
6393 }
6394 return FALSE(0);
6395}
6396
6397static void
6398ctk_window_unmap (CtkWidget *widget)
6399{
6400 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
6401 CtkWindowPrivate *priv = window->priv;
6402 CtkWidget *child;
6403 CtkWindowGeometryInfo *info;
6404 CdkWindow *cdk_window;
6405 CdkWindowState state;
6406 GList *link;
6407
6408 if (!_ctk_widget_is_toplevel (CTK_WIDGET (widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_widget_get_type ()))))))
))
6409 {
6410 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->unmap (widget);
6411 return;
6412 }
6413
6414 link = priv->popovers;
6415
6416 while (link)
6417 {
6418 CtkWindowPopover *popover = link->data;
6419 link = link->next;
6420 popover_unmap (popover->widget, popover);
6421 }
6422
6423 cdk_window = _ctk_widget_get_window (widget);
6424
6425 ctk_widget_set_mapped (widget, FALSE(0));
6426 cdk_window_withdraw (cdk_window);
6427
6428 while (priv->configure_request_count > 0)
6429 {
6430 priv->configure_request_count--;
6431 CDK_PRIVATE_CALL (cdk_window_thaw_toplevel_updates)(cdk__private__ ()->cdk_window_thaw_toplevel_updates) (_ctk_widget_get_window (widget));
6432 }
6433 priv->configure_notify_received = FALSE(0);
6434
6435 /* on unmap, we reset the default positioning of the window,
6436 * so it's placed again, but we don't reset the default
6437 * size of the window, so it's remembered.
6438 */
6439 priv->need_default_position = TRUE(!(0));
6440
6441 priv->fixate_size = FALSE(0);
6442
6443 info = ctk_window_get_geometry_info (window, FALSE(0));
6444 if (info)
6445 {
6446 info->initial_pos_set = FALSE(0);
6447 info->position_constraints_changed = FALSE(0);
6448 }
6449
6450 state = cdk_window_get_state (cdk_window);
6451 priv->iconify_initially = (state & CDK_WINDOW_STATE_ICONIFIED) != 0;
6452 priv->maximize_initially = (state & CDK_WINDOW_STATE_MAXIMIZED) != 0;
6453 priv->stick_initially = (state & CDK_WINDOW_STATE_STICKY) != 0;
6454 priv->above_initially = (state & CDK_WINDOW_STATE_ABOVE) != 0;
6455 priv->below_initially = (state & CDK_WINDOW_STATE_BELOW) != 0;
6456
6457 if (priv->title_box != NULL((void*)0))
6458 ctk_widget_unmap (priv->title_box);
6459
6460 child = ctk_bin_get_child (&(window->bin));
6461 if (child != NULL((void*)0))
6462 ctk_widget_unmap (child);
6463}
6464
6465void
6466ctk_window_set_unlimited_guessed_size (CtkWindow *window,
6467 gboolean x,
6468 gboolean y)
6469{
6470 CtkWindowPrivate *priv = window->priv;
6471
6472 priv->unlimited_guessed_size_x = x;
6473 priv->unlimited_guessed_size_y = y;
6474}
6475
6476void
6477ctk_window_force_resize (CtkWindow *window)
6478{
6479 CtkWindowPrivate *priv = window->priv;
6480
6481 priv->force_resize = TRUE(!(0));
6482}
6483
6484void
6485ctk_window_fixate_size (CtkWindow *window)
6486{
6487 CtkWindowPrivate *priv = window->priv;
6488
6489 priv->fixate_size = TRUE(!(0));
6490}
6491
6492/* (Note: Replace "size" with "width" or "height". Also, the request
6493 * mode is honoured.)
6494 * For selecting the default window size, the following conditions
6495 * should hold (in order of importance):
6496 * - the size is not below the minimum size
6497 * Windows cannot be resized below their minimum size, so we must
6498 * ensure we don’t do that either.
6499 * - the size is not above the natural size
6500 * It seems weird to allocate more than this in an initial guess.
6501 * - the size does not exceed that of a maximized window
6502 * We want to see the whole window after all.
6503 * (Note that this may not be possible to achieve due to imperfect
6504 * information from the windowing system.)
6505 */
6506
6507static void
6508ctk_window_guess_default_size (CtkWindow *window,
6509 gint *width,
6510 gint *height)
6511{
6512 CtkWidget *widget;
6513 CdkDisplay *display;
6514 CdkWindow *cdkwindow;
6515 CdkMonitor *monitor;
6516 CdkRectangle workarea;
6517 int minimum, natural;
6518
6519 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
6520 display = ctk_widget_get_display (widget);
6521 cdkwindow = _ctk_widget_get_window (widget);
6522
6523 if (window->priv->fixate_size)
6524 {
6525 g_assert (cdkwindow)do { if (cdkwindow) ; else g_assertion_message_expr ("Ctk", "ctkwindow.c"
, 6525, ((const char*) (__func__)), "cdkwindow"); } while (0)
;
6526 ctk_window_get_remembered_size (window, width, height);
6527 return;
6528 }
6529
6530 if (cdkwindow)
6531 monitor = cdk_display_get_monitor_at_window (display, cdkwindow);
6532 else
6533 monitor = cdk_display_get_monitor (display, 0);
6534
6535 cdk_monitor_get_workarea (monitor, &workarea);
6536
6537 if (window->priv->unlimited_guessed_size_x)
6538 *width = INT_MAX2147483647;
6539 else
6540 *width = workarea.width;
6541
6542 if (window->priv->unlimited_guessed_size_y)
6543 *height = INT_MAX2147483647;
6544 else
6545 *height = workarea.height;
6546
6547 if (ctk_widget_get_request_mode (widget) == CTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
6548 {
6549 ctk_widget_get_preferred_height (widget, &minimum, &natural);
6550 *height = MAX (minimum, MIN (*height, natural))(((minimum) > ((((*height) < (natural)) ? (*height) : (
natural)))) ? (minimum) : ((((*height) < (natural)) ? (*height
) : (natural))))
;
6551
6552 ctk_widget_get_preferred_width_for_height (widget, *height, &minimum, &natural);
6553 *width = MAX (minimum, MIN (*width, natural))(((minimum) > ((((*width) < (natural)) ? (*width) : (natural
)))) ? (minimum) : ((((*width) < (natural)) ? (*width) : (
natural))))
;
6554 }
6555 else /* CTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
6556 {
6557 ctk_widget_get_preferred_width (widget, &minimum, &natural);
6558 *width = MAX (minimum, MIN (*width, natural))(((minimum) > ((((*width) < (natural)) ? (*width) : (natural
)))) ? (minimum) : ((((*width) < (natural)) ? (*width) : (
natural))))
;
6559
6560 ctk_widget_get_preferred_height_for_width (widget, *width, &minimum, &natural);
6561 *height = MAX (minimum, MIN (*height, natural))(((minimum) > ((((*height) < (natural)) ? (*height) : (
natural)))) ? (minimum) : ((((*height) < (natural)) ? (*height
) : (natural))))
;
6562 }
6563}
6564
6565static void
6566ctk_window_get_remembered_size (CtkWindow *window,
6567 int *width,
6568 int *height)
6569{
6570 CtkWindowGeometryInfo *info;
6571 CdkWindow *cdk_window;
6572
6573 *width = 0;
6574 *height = 0;
6575
6576 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
6577 if (cdk_window)
6578 {
6579 *width = cdk_window_get_width (cdk_window);
6580 *height = cdk_window_get_height (cdk_window);
6581 return;
6582 }
6583
6584 info = ctk_window_get_geometry_info (window, FALSE(0));
6585 if (info)
6586 {
6587 /* MAX() works even if the last request is unset with -1 */
6588 *width = MAX (*width, info->last.configure_request.width)(((*width) > (info->last.configure_request.width)) ? (*
width) : (info->last.configure_request.width))
;
6589 *height = MAX (*height, info->last.configure_request.height)(((*height) > (info->last.configure_request.height)) ? (
*height) : (info->last.configure_request.height))
;
6590 }
6591}
6592
6593static void
6594popover_get_rect (CtkWindowPopover *popover,
6595 CtkWindow *window,
6596 cairo_rectangle_int_t *rect)
6597{
6598 CtkAllocation win_alloc;
6599 CtkRequisition req;
6600 CtkBorder win_border;
6601 gdouble min, max;
6602
6603 ctk_widget_get_preferred_size (popover->widget, NULL((void*)0), &req);
6604 _ctk_widget_get_allocation (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
, &win_alloc);
6605
6606 get_shadow_width (window, &win_border);
6607 win_alloc.x += win_border.left;
6608 win_alloc.y += win_border.top;
6609 win_alloc.width -= win_border.left + win_border.right;
6610 win_alloc.height -= win_border.top + win_border.bottom;
6611
6612 rect->width = req.width;
6613 rect->height = req.height;
6614
6615 if (popover->pos == CTK_POS_LEFT || popover->pos == CTK_POS_RIGHT)
6616 {
6617 if (req.height < win_alloc.height &&
6618 ctk_widget_get_vexpand (popover->widget))
6619 {
6620 rect->y = win_alloc.y;
6621 rect->height = win_alloc.height;
6622 }
6623 else
6624 {
6625 min = 0;
6626 max = win_alloc.y + win_alloc.height + win_border.bottom - req.height;
6627
6628 if (popover->clamp_allocation)
6629 {
6630 min += win_border.top;
6631 max -= win_border.bottom;
6632 }
6633
6634 rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) -(((popover->rect.y + (popover->rect.height / 2) - (req.
height / 2)) > (max)) ? (max) : (((popover->rect.y + (popover
->rect.height / 2) - (req.height / 2)) < (min)) ? (min)
: (popover->rect.y + (popover->rect.height / 2) - (req
.height / 2))))
6635 (req.height / 2), min, max)(((popover->rect.y + (popover->rect.height / 2) - (req.
height / 2)) > (max)) ? (max) : (((popover->rect.y + (popover
->rect.height / 2) - (req.height / 2)) < (min)) ? (min)
: (popover->rect.y + (popover->rect.height / 2) - (req
.height / 2))))
;
6636 }
6637
6638 if ((popover->pos == CTK_POS_LEFT) ==
6639 (ctk_widget_get_direction (popover->widget) == CTK_TEXT_DIR_LTR))
6640 {
6641 rect->x = popover->rect.x - req.width;
6642
6643 if (rect->x > win_alloc.x && ctk_widget_get_hexpand (popover->widget))
6644 {
6645 rect->x = win_alloc.x;
6646 rect->width = popover->rect.x;
6647 }
6648 }
6649 else
6650 {
6651 rect->x = popover->rect.x + popover->rect.width;
6652
6653 if (rect->x + rect->width < win_alloc.x + win_alloc.width &&
6654 ctk_widget_get_hexpand (popover->widget))
6655 rect->width = win_alloc.x + win_alloc.width - rect->x;
6656 }
6657 }
6658 else if (popover->pos == CTK_POS_TOP || popover->pos == CTK_POS_BOTTOM)
6659 {
6660 if (req.width < win_alloc.width &&
6661 ctk_widget_get_hexpand (popover->widget))
6662 {
6663 rect->x = win_alloc.x;
6664 rect->width = win_alloc.width;
6665 }
6666 else
6667 {
6668 min = 0;
6669 max = win_alloc.x + win_alloc.width + win_border.right - req.width;
6670
6671 if (popover->clamp_allocation)
6672 {
6673 min += win_border.left;
6674 max -= win_border.right;
6675 }
6676
6677 rect->x = CLAMP (popover->rect.x + (popover->rect.width / 2) -(((popover->rect.x + (popover->rect.width / 2) - (req.width
/ 2)) > (max)) ? (max) : (((popover->rect.x + (popover
->rect.width / 2) - (req.width / 2)) < (min)) ? (min) :
(popover->rect.x + (popover->rect.width / 2) - (req.width
/ 2))))
6678 (req.width / 2), min, max)(((popover->rect.x + (popover->rect.width / 2) - (req.width
/ 2)) > (max)) ? (max) : (((popover->rect.x + (popover
->rect.width / 2) - (req.width / 2)) < (min)) ? (min) :
(popover->rect.x + (popover->rect.width / 2) - (req.width
/ 2))))
;
6679 }
6680
6681 if (popover->pos == CTK_POS_TOP)
6682 {
6683 rect->y = popover->rect.y - req.height;
6684
6685 if (rect->y > win_alloc.y &&
6686 ctk_widget_get_vexpand (popover->widget))
6687 {
6688 rect->y = win_alloc.y;
6689 rect->height = popover->rect.y;
6690 }
6691 }
6692 else
6693 {
6694 rect->y = popover->rect.y + popover->rect.height;
6695
6696 if (rect->y + rect->height < win_alloc.y + win_alloc.height &&
6697 ctk_widget_get_vexpand (popover->widget))
6698 rect->height = win_alloc.y + win_alloc.height - rect->y;
6699 }
6700 }
6701}
6702
6703static void
6704popover_realize (CtkWidget *widget,
6705 CtkWindowPopover *popover,
6706 CtkWindow *window)
6707{
6708 cairo_rectangle_int_t rect;
6709 CdkWindow *parent_window;
6710 CdkWindowAttr attributes;
6711 gint attributes_mask;
6712
6713 if (popover->window)
6714 return;
6715
6716 popover_get_rect (popover, window, &rect);
6717
6718#ifdef CDK_WINDOWING_WAYLAND
6719 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
6720 {
6721 attributes.window_type = CDK_WINDOW_SUBSURFACE;
6722 parent_window = cdk_screen_get_root_window (_ctk_window_get_screen (window));
6723 }
6724 else
6725#endif
6726 {
6727 attributes.window_type = CDK_WINDOW_CHILD;
6728 parent_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
6729 }
6730
6731 attributes.wclass = CDK_INPUT_OUTPUT;
6732 attributes.x = rect.x;
6733 attributes.y = rect.y;
6734 attributes.width = rect.width;
6735 attributes.height = rect.height;
6736 attributes.visual = ctk_widget_get_visual (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
6737 attributes.event_mask = ctk_widget_get_events (popover->widget) |
6738 CDK_EXPOSURE_MASK;
6739 attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL;
6740
6741 popover->window = cdk_window_new (parent_window, &attributes, attributes_mask);
6742 ctk_widget_register_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
, popover->window);
6743
6744#ifdef CDK_WINDOWING_WAYLAND
6745 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
6746 cdk_window_set_transient_for (popover->window,
6747 _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
6748#endif
6749
6750 ctk_widget_set_parent_window (popover->widget, popover->window);
6751}
6752
6753static void
6754check_scale_changed (CtkWindow *window)
6755{
6756 CtkWindowPrivate *priv = window->priv;
6757 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
6758 int old_scale;
6759
6760 old_scale = priv->scale;
6761 priv->scale = ctk_widget_get_scale_factor (widget);
6762 if (old_scale != priv->scale)
6763 _ctk_widget_scale_changed (widget);
6764}
6765
6766static void
6767sum_borders (CtkBorder *one,
6768 CtkBorder *two)
6769{
6770 one->top += two->top;
6771 one->right += two->right;
6772 one->bottom += two->bottom;
6773 one->left += two->left;
6774}
6775
6776static void
6777max_borders (CtkBorder *one,
6778 CtkBorder *two)
6779{
6780 one->top = MAX (one->top, two->top)(((one->top) > (two->top)) ? (one->top) : (two->
top))
;
6781 one->right = MAX (one->right, two->right)(((one->right) > (two->right)) ? (one->right) : (
two->right))
;
6782 one->bottom = MAX (one->bottom, two->bottom)(((one->bottom) > (two->bottom)) ? (one->bottom) :
(two->bottom))
;
6783 one->left = MAX (one->left, two->left)(((one->left) > (two->left)) ? (one->left) : (two
->left))
;
6784}
6785
6786static void
6787subtract_borders (CtkBorder *one,
6788 CtkBorder *two)
6789{
6790 one->top -= two->top;
6791 one->right -= two->right;
6792 one->bottom -= two->bottom;
6793 one->left -= two->left;
6794}
6795
6796static void
6797get_shadow_width (CtkWindow *window,
6798 CtkBorder *shadow_width)
6799{
6800 CtkWindowPrivate *priv = window->priv;
6801 CtkBorder border = { 0 };
6802 CtkBorder d = { 0 };
6803 CtkBorder margin;
6804 CtkStyleContext *context;
6805 CtkStateFlags s;
6806 CtkCssValue *shadows;
6807
6808 *shadow_width = border;
6809
6810 if (!priv->decorated)
6811 return;
6812
6813 if (!priv->client_decorated &&
6814 !(ctk_window_should_use_csd (window) &&
6815 ctk_window_supports_client_shadow (window)))
6816 return;
6817
6818 if (priv->maximized ||
6819 priv->fullscreen)
6820 return;
6821
6822 if (!_ctk_widget_is_toplevel (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
6823 return;
6824
6825 context = _ctk_widget_get_style_context (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
6826
6827 ctk_style_context_save_to_node (context, priv->decoration_node);
6828 s = ctk_style_context_get_state (context);
6829
6830 /* Always sum border + padding */
6831 ctk_style_context_get_border (context, s, &border);
6832 ctk_style_context_get_padding (context, s, &d);
6833 sum_borders (&d, &border);
6834
6835 /* Calculate the size of the drop shadows ... */
6836 shadows = _ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BOX_SHADOW);
6837 _ctk_css_shadows_value_get_extents (shadows, &border);
6838
6839 if (priv->type != CTK_WINDOW_POPUP)
6840 {
6841 /* ... and compare it to the margin size, which we use for resize grips */
6842 ctk_style_context_get_margin (context, s, &margin);
6843 max_borders (&border, &margin);
6844 }
6845
6846 sum_borders (&d, &border);
6847 *shadow_width = d;
6848
6849 ctk_style_context_restore (context);
6850}
6851
6852static void
6853update_corner_windows (CtkWindow *window,
6854 CtkBorder border,
6855 CtkBorder window_border,
6856 gint width,
6857 gint height,
6858 gint handle_h,
6859 gint handle_v,
6860 gboolean resize_n,
6861 gboolean resize_e,
6862 gboolean resize_s,
6863 gboolean resize_w)
6864{
6865 CtkWindowPrivate *priv = window->priv;
6866 cairo_rectangle_int_t rect;
6867 cairo_region_t *region;
6868
6869 /* North-West */
6870 if (resize_n && resize_w)
6871 {
6872 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_NORTH_WEST],
6873 window_border.left - border.left, window_border.top - border.top,
6874 border.left + handle_h, border.top + handle_v);
6875
6876 rect.x = 0;
6877 rect.y = 0;
6878 rect.width = border.left + handle_h;
6879 rect.height = border.top + handle_v;
6880 region = cairo_region_create_rectangle (&rect);
6881 rect.x = border.left;
6882 rect.y = border.top;
6883 rect.width = handle_h;
6884 rect.height = handle_v;
6885 cairo_region_subtract_rectangle (region, &rect);
6886 cdk_window_shape_combine_region (priv->border_window[CDK_WINDOW_EDGE_NORTH_WEST],
6887 region, 0, 0);
6888 cairo_region_destroy (region);
6889
6890 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_NORTH_WEST]);
6891 }
6892 else
6893 {
6894 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_NORTH_WEST]);
6895 }
6896
6897
6898 /* North-East */
6899 if (resize_n && resize_e)
6900 {
6901 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_NORTH_EAST],
6902 window_border.left + width - handle_h, window_border.top - border.top,
6903 border.right + handle_h, border.top + handle_v);
6904
6905 rect.x = 0;
6906 rect.y = 0;
6907 rect.width = border.right + handle_h;
6908 rect.height = border.top + handle_v;
6909 region = cairo_region_create_rectangle (&rect);
6910 rect.x = 0;
6911 rect.y = border.top;
6912 rect.width = handle_h;
6913 rect.height = handle_v;
6914 cairo_region_subtract_rectangle (region, &rect);
6915 cdk_window_shape_combine_region (priv->border_window[CDK_WINDOW_EDGE_NORTH_EAST],
6916 region, 0, 0);
6917 cairo_region_destroy (region);
6918
6919 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_NORTH_EAST]);
6920 }
6921 else
6922 {
6923 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_NORTH_EAST]);
6924 }
6925
6926 /* South-West */
6927 if (resize_s && resize_w)
6928 {
6929 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_SOUTH_WEST],
6930 window_border.left - border.left, window_border.top + height - handle_v,
6931 border.left + handle_h, border.bottom + handle_v);
6932
6933 rect.x = 0;
6934 rect.y = 0;
6935 rect.width = border.left + handle_h;
6936 rect.height = border.bottom + handle_v;
6937 region = cairo_region_create_rectangle (&rect);
6938 rect.x = border.left;
6939 rect.y = 0;
6940 rect.width = handle_h;
6941 rect.height = handle_v;
6942 cairo_region_subtract_rectangle (region, &rect);
6943 cdk_window_shape_combine_region (priv->border_window[CDK_WINDOW_EDGE_SOUTH_WEST],
6944 region, 0, 0);
6945 cairo_region_destroy (region);
6946
6947 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_SOUTH_WEST]);
6948 }
6949 else
6950 {
6951 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_SOUTH_WEST]);
6952 }
6953
6954 /* South-East */
6955 if (resize_s && resize_e)
6956 {
6957 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_SOUTH_EAST],
6958 window_border.left + width - handle_h, window_border.top + height - handle_v,
6959 border.right + handle_h, border.bottom + handle_v);
6960
6961 rect.x = 0;
6962 rect.y = 0;
6963 rect.width = border.right + handle_h;
6964 rect.height = border.bottom + handle_v;
6965 region = cairo_region_create_rectangle (&rect);
6966 rect.x = 0;
6967 rect.y = 0;
6968 rect.width = handle_h;
6969 rect.height = handle_v;
6970 cairo_region_subtract_rectangle (region, &rect);
6971 cdk_window_shape_combine_region (priv->border_window[CDK_WINDOW_EDGE_SOUTH_EAST],
6972 region, 0, 0);
6973 cairo_region_destroy (region);
6974
6975 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_SOUTH_EAST]);
6976 }
6977 else
6978 {
6979 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_SOUTH_EAST]);
6980 }
6981}
6982
6983/* We're placing 8 input-only windows around
6984 * the window content as resize handles, as
6985 * follows:
6986 *
6987 * +-----------------------------------+
6988 * | +------+-----------------+------+ |
6989 * | | | | | |
6990 * | | +--+-----------------+--+ | |
6991 * | | | | | |
6992 * | +---+ +---+ |
6993 * | | | | | |
6994 * | | | | | |
6995 * | | | | | |
6996 * | +---+ +---+ |
6997 * | | | | | |
6998 * | | +--+-----------------+--+ | |
6999 * | | | | | |
7000 * | +------+-----------------+------+ |
7001 * +-----------------------------------+
7002 *
7003 * The corner windows are shaped to allow them
7004 * to extend into the edges. If the window is
7005 * not resizable in both dimensions, we hide
7006 * the corner windows and the edge windows in
7007 * the nonresizable dimension and make the
7008 * remaining edge window extend all the way.
7009 *
7010 * The border are where we place the resize handles
7011 * is also used to draw the window shadow, which may
7012 * extend out farther than the handles (or the other
7013 * way around).
7014 */
7015static void
7016update_border_windows (CtkWindow *window)
7017{
7018 CtkWidget *widget = (CtkWidget *)window;
7019 CtkWindowPrivate *priv = window->priv;
7020 gboolean resize_n, resize_e, resize_s, resize_w;
7021 gint handle, handle_h, handle_v;
7022 cairo_region_t *region;
7023 cairo_rectangle_int_t rect;
7024 gint width, height;
7025 gint x, w;
7026 gint y, h;
7027 CtkBorder border, tmp;
7028 CtkBorder window_border;
7029 CtkStyleContext *context;
7030
7031 if (!priv->client_decorated)
7032 return;
7033
7034 context = _ctk_widget_get_style_context (widget);
7035
7036 ctk_style_context_save_to_node (context, priv->decoration_node);
7037 ctk_style_context_get_margin (context, ctk_style_context_get_state (context), &border);
7038 ctk_style_context_get_border (context, ctk_style_context_get_state (context), &tmp);
7039 sum_borders (&border, &tmp);
7040 ctk_style_context_get_padding (context, ctk_style_context_get_state (context), &tmp);
7041 sum_borders (&border, &tmp);
7042 ctk_widget_style_get (widget,
7043 "decoration-resize-handle", &handle,
7044 NULL((void*)0));
7045 ctk_style_context_restore (context);
7046 get_shadow_width (window, &window_border);
7047
7048 if (priv->border_window[0] == NULL((void*)0))
7049 goto shape;
7050
7051 if (!priv->resizable ||
7052 priv->fullscreen ||
7053 priv->maximized)
7054 {
7055 resize_n = resize_s = resize_e = resize_w = FALSE(0);
7056 }
7057 else if (priv->tiled || priv->edge_constraints)
7058 {
7059 /* Per-edge information is preferred when both priv->tiled and
7060 * priv->edge_constraints are set.
7061 */
7062 if (priv->edge_constraints)
7063 {
7064 resize_n = priv->edge_constraints & CDK_WINDOW_STATE_TOP_RESIZABLE;
7065 resize_e = priv->edge_constraints & CDK_WINDOW_STATE_RIGHT_RESIZABLE;
7066 resize_s = priv->edge_constraints & CDK_WINDOW_STATE_BOTTOM_RESIZABLE;
7067 resize_w = priv->edge_constraints & CDK_WINDOW_STATE_LEFT_RESIZABLE;
7068 }
7069 else
7070 {
7071 resize_n = resize_s = resize_e = resize_w = FALSE(0);
7072 }
7073 }
7074 else
7075 {
7076 resize_n = resize_s = resize_e = resize_w = TRUE(!(0));
7077 if (priv->geometry_info)
7078 {
7079 CdkGeometry *geometry = &priv->geometry_info->geometry;
7080 CdkWindowHints flags = priv->geometry_info->mask;
7081
7082 if ((flags & CDK_HINT_MIN_SIZE) && (flags & CDK_HINT_MAX_SIZE))
7083 {
7084 resize_e = resize_w = geometry->min_width != geometry->max_width;
7085 resize_n = resize_s = geometry->min_height != geometry->max_height;
7086 }
7087 }
7088 }
7089
7090 width = ctk_widget_get_allocated_width (widget) - (window_border.left + window_border.right);
7091 height = ctk_widget_get_allocated_height (widget) - (window_border.top + window_border.bottom);
7092
7093 handle_h = MIN (handle, width / 2)(((handle) < (width / 2)) ? (handle) : (width / 2));
7094 handle_v = MIN (handle, height / 2)(((handle) < (height / 2)) ? (handle) : (height / 2));
7095
7096 /*
7097 * Taking the following abstract representation of the resizable
7098 * edges:
7099 *
7100 * +-------------------------------------------+
7101 * | NW | North | NE |
7102 * |----+---------------------------------+----|
7103 * | | x | |
7104 * | | | |
7105 * | W | Window contents | E |
7106 * | | | |
7107 * | | | |
7108 * |----+---------------------------------+----|
7109 * | SW | South | SE |
7110 * +-------------------------------------------+
7111 *
7112 * The idea behind the following math is if, say, the North edge is
7113 * resizable, East & West edges are moved down (i.e. y += North edge
7114 * size). If the South edge is resizable, only shrink East and West
7115 * heights. The same logic applies to the horizontal edges.
7116 *
7117 * The corner windows are only visible if both touching edges are
7118 * visible, for example, the NE window is visible if both N and E
7119 * edges are resizable.
7120 */
7121
7122 x = 0;
7123 y = 0;
7124 w = width + window_border.left + window_border.right;
7125 h = height + window_border.top + window_border.bottom;
7126
7127 if (resize_n)
7128 {
7129 y += window_border.top + handle_v;
7130 h -= window_border.top + handle_v;
7131 }
7132
7133 if (resize_w)
7134 {
7135 x += window_border.left + handle_h;
7136 w -= window_border.left + handle_h;
7137 }
7138
7139 if (resize_s)
7140 h -= window_border.bottom + handle_v;
7141
7142 if (resize_e)
7143 w -= window_border.right + handle_h;
7144
7145 /* North */
7146 if (resize_n)
7147 {
7148 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_NORTH],
7149 x, window_border.top - border.top,
7150 w, border.top);
7151
7152 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_NORTH]);
7153 }
7154 else
7155 {
7156 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_NORTH]);
7157 }
7158
7159 /* South */
7160 if (resize_s)
7161 {
7162 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_SOUTH],
7163 x, window_border.top + height,
7164 w, border.bottom);
7165
7166 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_SOUTH]);
7167 }
7168 else
7169 {
7170 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_SOUTH]);
7171 }
7172
7173 /* East */
7174 if (resize_e)
7175 {
7176 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_EAST],
7177 window_border.left + width, y,
7178 border.right, h);
7179
7180 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_EAST]);
7181 }
7182 else
7183 {
7184 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_EAST]);
7185 }
7186
7187 /* West */
7188 if (resize_w)
7189 {
7190 cdk_window_move_resize (priv->border_window[CDK_WINDOW_EDGE_WEST],
7191 window_border.left - border.left, y,
7192 border.left, h);
7193
7194 cdk_window_show_unraised (priv->border_window[CDK_WINDOW_EDGE_WEST]);
7195 }
7196 else
7197 {
7198 cdk_window_hide (priv->border_window[CDK_WINDOW_EDGE_WEST]);
7199 }
7200
7201 update_corner_windows (window, border, window_border, width, height, handle_h, handle_v,
7202 resize_n, resize_e, resize_s, resize_w);
7203
7204shape:
7205 /* we also update the input shape, which makes it so that clicks
7206 * outside the border windows go through
7207 */
7208
7209 if (priv->type != CTK_WINDOW_POPUP)
7210 subtract_borders (&window_border, &border);
7211
7212 rect.x = window_border.left;
7213 rect.y = window_border.top;
7214 rect.width = ctk_widget_get_allocated_width (widget) - window_border.left - window_border.right;
7215 rect.height = ctk_widget_get_allocated_height (widget) - window_border.top - window_border.bottom;
7216 region = cairo_region_create_rectangle (&rect);
7217 ctk_widget_set_csd_input_shape (widget, region);
7218 cairo_region_destroy (region);
7219}
7220
7221static void
7222update_shadow_width (CtkWindow *window,
7223 CtkBorder *border)
7224{
7225 CdkWindow *cdk_window;
7226
7227 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
7228
7229 if (cdk_window)
7230 cdk_window_set_shadow_width (cdk_window,
7231 border->left,
7232 border->right,
7233 border->top,
7234 border->bottom);
7235}
7236
7237static void
7238corner_rect (cairo_rectangle_int_t *rect,
7239 const CtkCssValue *value)
7240{
7241 rect->width = _ctk_css_corner_value_get_x (value, 100);
7242 rect->height = _ctk_css_corner_value_get_y (value, 100);
7243}
7244
7245static void
7246subtract_decoration_corners_from_region (cairo_region_t *region,
7247 cairo_rectangle_int_t *extents,
7248 CtkStyleContext *context,
7249 CtkWindow *window)
7250{
7251 CtkWindowPrivate *priv = window->priv;
7252 cairo_rectangle_int_t rect;
7253
7254 if (!priv->client_decorated ||
7255 !priv->decorated ||
7256 priv->fullscreen ||
7257 priv->maximized)
7258 return;
7259
7260 ctk_style_context_save_to_node (context, window->priv->decoration_node);
7261
7262 corner_rect (&rect, _ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS));
7263 rect.x = extents->x;
7264 rect.y = extents->y;
7265 cairo_region_subtract_rectangle (region, &rect);
7266
7267 corner_rect (&rect, _ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS));
7268 rect.x = extents->x + extents->width - rect.width;
7269 rect.y = extents->y;
7270 cairo_region_subtract_rectangle (region, &rect);
7271
7272 corner_rect (&rect, _ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS));
7273 rect.x = extents->x;
7274 rect.y = extents->y + extents->height - rect.height;
7275 cairo_region_subtract_rectangle (region, &rect);
7276
7277 corner_rect (&rect, _ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS));
7278 rect.x = extents->x + extents->width - rect.width;
7279 rect.y = extents->y + extents->height - rect.height;
7280 cairo_region_subtract_rectangle (region, &rect);
7281
7282 ctk_style_context_restore (context);
7283}
7284
7285static void
7286update_opaque_region (CtkWindow *window,
7287 const CtkBorder *border,
7288 const CtkAllocation *allocation)
7289{
7290 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
7291 cairo_region_t *opaque_region;
7292 CtkStyleContext *context;
7293 gboolean is_opaque = FALSE(0);
7294
7295 if (!_ctk_widget_get_realized (widget))
7296 return;
7297
7298 context = ctk_widget_get_style_context (widget);
7299
7300 if (!ctk_widget_get_app_paintable (widget))
7301 {
7302 const CdkRGBA *color;
7303 color = _ctk_css_rgba_value_get_rgba (_ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BACKGROUND_COLOR));
7304 is_opaque = (color->alpha >= 1.0);
7305 }
7306
7307 if (ctk_widget_get_opacity (widget) < 1.0)
7308 is_opaque = FALSE(0);
7309
7310 if (is_opaque)
7311 {
7312 cairo_rectangle_int_t rect;
7313
7314 rect.x = border->left;
7315 rect.y = border->top;
7316 rect.width = allocation->width - border->left - border->right;
7317 rect.height = allocation->height - border->top - border->bottom;
7318
7319 opaque_region = cairo_region_create_rectangle (&rect);
7320
7321 subtract_decoration_corners_from_region (opaque_region, &rect, context, window);
7322 }
7323 else
7324 {
7325 opaque_region = NULL((void*)0);
7326 }
7327
7328 cdk_window_set_opaque_region (_ctk_widget_get_window (widget), opaque_region);
7329
7330 cairo_region_destroy (opaque_region);
7331}
7332
7333static void
7334update_realized_window_properties (CtkWindow *window,
7335 CtkAllocation *child_allocation,
7336 CtkBorder *window_border)
7337{
7338 CtkWindowPrivate *priv = window->priv;
7339
7340 if (!_ctk_widget_is_toplevel (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
7341 return;
7342
7343 if (priv->client_decorated && priv->use_client_shadow)
7344 update_shadow_width (window, window_border);
7345
7346 update_opaque_region (window, window_border, child_allocation);
7347
7348 update_border_windows (window);
7349}
7350
7351static void
7352ctk_window_realize (CtkWidget *widget)
7353{
7354 CtkAllocation allocation;
7355 CtkAllocation child_allocation;
7356 CtkWindow *window;
7357 CdkWindow *parent_window;
7358 CdkWindow *cdk_window;
7359 CdkWindowAttr attributes;
7360 CtkBorder window_border;
7361 gint attributes_mask;
7362 CtkWindowPrivate *priv;
7363 gint i;
7364 GList *link;
7365
7366 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
7367 priv = window->priv;
7368
7369 if (!priv->client_decorated && ctk_window_should_use_csd (window))
7370 create_decoration (widget);
7371
7372 _ctk_widget_get_allocation (widget, &allocation);
7373
7374 if (ctk_widget_get_parent_window (widget))
7375 {
7376 ctk_container_set_default_resize_mode (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
, CTK_RESIZE_PARENT);
7377
7378 attributes.x = allocation.x;
7379 attributes.y = allocation.y;
7380 attributes.width = allocation.width;
7381 attributes.height = allocation.height;
7382 attributes.window_type = CDK_WINDOW_CHILD;
7383
7384 attributes.event_mask = ctk_widget_get_events (widget) | CDK_EXPOSURE_MASK | CDK_STRUCTURE_MASK;
7385
7386 attributes.visual = ctk_widget_get_visual (widget);
7387 attributes.wclass = CDK_INPUT_OUTPUT;
7388
7389 attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL;
7390
7391 cdk_window = cdk_window_new (ctk_widget_get_parent_window (widget),
7392 &attributes, attributes_mask);
7393 ctk_widget_set_window (widget, cdk_window);
7394 ctk_widget_register_window (widget, cdk_window);
7395 ctk_widget_set_realized (widget, TRUE(!(0)));
7396
7397 link = priv->popovers;
7398
7399 while (link)
7400 {
7401 CtkWindowPopover *popover = link->data;
7402 link = link->next;
7403 popover_realize (popover->widget, popover, window);
7404 }
7405
7406 return;
7407 }
7408
7409 ctk_container_set_default_resize_mode (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, CTK_RESIZE_QUEUE);
7410
7411 /* ensure widget tree is properly size allocated */
7412 if (allocation.x == -1 &&
7413 allocation.y == -1 &&
7414 allocation.width == 1 &&
7415 allocation.height == 1)
7416 {
7417 CdkRectangle request;
7418
7419 ctk_window_compute_configure_request (window, &request, NULL((void*)0), NULL((void*)0));
7420
7421 allocation.x = 0;
7422 allocation.y = 0;
7423 allocation.width = request.width;
7424 allocation.height = request.height;
7425 ctk_widget_size_allocate (widget, &allocation);
7426
7427 ctk_widget_queue_resize (widget);
7428
7429 g_return_if_fail (!_ctk_widget_get_realized (widget))do { if ((!_ctk_widget_get_realized (widget))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "!_ctk_widget_get_realized (widget)"
); return; } } while (0)
;
7430 }
7431
7432 if (priv->hardcoded_window)
7433 {
7434 cdk_window = priv->hardcoded_window;
7435 _ctk_widget_get_allocation (widget, &allocation);
7436 cdk_window_resize (cdk_window, allocation.width, allocation.height);
7437 }
7438 else
7439 {
7440 switch (priv->type)
7441 {
7442 case CTK_WINDOW_TOPLEVEL:
7443 attributes.window_type = CDK_WINDOW_TOPLEVEL;
7444 break;
7445 case CTK_WINDOW_POPUP:
7446 attributes.window_type = CDK_WINDOW_TEMP;
7447 break;
7448 default:
7449 g_warning (G_STRLOC"ctkwindow.c" ":" "7449"": Unknown window type %d!", priv->type);
7450 break;
7451 }
7452
7453#ifdef CDK_WINDOWING_WAYLAND
7454 if (priv->use_subsurface &&
7455 CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
7456 attributes.window_type = CDK_WINDOW_SUBSURFACE;
7457#endif
7458
7459 attributes.title = priv->title;
7460 attributes.wmclass_name = priv->wmclass_name;
7461 attributes.wmclass_class = priv->wmclass_class;
7462 attributes.wclass = CDK_INPUT_OUTPUT;
7463 attributes.visual = ctk_widget_get_visual (widget);
7464
7465 attributes_mask = 0;
7466 parent_window = cdk_screen_get_root_window (_ctk_window_get_screen (window));
7467
7468 _ctk_widget_get_allocation (widget, &allocation);
7469 attributes.width = allocation.width;
7470 attributes.height = allocation.height;
7471 attributes.event_mask = ctk_widget_get_events (widget);
7472 attributes.event_mask |= (CDK_EXPOSURE_MASK |
7473 CDK_BUTTON_PRESS_MASK |
7474 CDK_BUTTON_RELEASE_MASK |
7475 CDK_BUTTON_MOTION_MASK |
7476 CDK_KEY_PRESS_MASK |
7477 CDK_KEY_RELEASE_MASK |
7478 CDK_ENTER_NOTIFY_MASK |
7479 CDK_LEAVE_NOTIFY_MASK |
7480 CDK_FOCUS_CHANGE_MASK |
7481 CDK_STRUCTURE_MASK);
7482
7483 if (priv->decorated && priv->client_decorated)
7484 attributes.event_mask |= CDK_POINTER_MOTION_MASK;
7485
7486 attributes.type_hint = priv->type_hint;
7487
7488 attributes_mask |= CDK_WA_VISUAL | CDK_WA_TYPE_HINT;
7489 attributes_mask |= (priv->title ? CDK_WA_TITLE : 0);
7490 attributes_mask |= (priv->wmclass_name ? CDK_WA_WMCLASS : 0);
7491
7492 cdk_window = cdk_window_new (parent_window, &attributes, attributes_mask);
7493 }
7494
7495 ctk_widget_set_window (widget, cdk_window);
7496 ctk_widget_register_window (widget, cdk_window);
7497 ctk_widget_set_realized (widget, TRUE(!(0)));
7498
7499 attributes.x = allocation.x;
7500 attributes.y = allocation.y;
7501 attributes.width = allocation.width;
7502 attributes.height = allocation.height;
7503 attributes.window_type = CDK_WINDOW_CHILD;
7504
7505 attributes.event_mask = ctk_widget_get_events (widget) | CDK_EXPOSURE_MASK | CDK_STRUCTURE_MASK;
7506
7507 attributes.visual = ctk_widget_get_visual (widget);
7508 attributes.wclass = CDK_INPUT_OUTPUT;
7509
7510 attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL;
7511
7512 if (priv->client_decorated && priv->type == CTK_WINDOW_TOPLEVEL)
7513 {
7514 const gchar *cursor[8] = {
7515 "nw-resize", "n-resize", "ne-resize",
7516 "w-resize", "e-resize",
7517 "sw-resize", "s-resize", "se-resize"
7518 };
7519
7520 attributes.wclass = CDK_INPUT_ONLY;
7521 attributes.width = 1;
7522 attributes.height = 1;
7523 attributes.event_mask = CDK_BUTTON_PRESS_MASK;
7524 attributes_mask = CDK_WA_CURSOR;
7525
7526 for (i = 0; i < 8; i++)
7527 {
7528 attributes.cursor = cdk_cursor_new_from_name (ctk_widget_get_display (widget), cursor[i]);
7529 priv->border_window[i] = cdk_window_new (cdk_window, &attributes, attributes_mask);
7530 g_clear_object (&attributes.cursor)do { _Static_assert (sizeof *((&attributes.cursor)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&attributes.cursor))) _pp = ((&attributes.cursor)); __typeof__
(*((&attributes.cursor))) _ptr = *_pp; *_pp = ((void*)0)
; if (_ptr) (g_object_unref) (_ptr); } while (0)
;
7531
7532 cdk_window_show (priv->border_window[i]);
7533 ctk_widget_register_window (widget, priv->border_window[i]);
7534 }
7535 }
7536
7537 if (priv->transient_parent &&
7538 _ctk_widget_get_realized (CTK_WIDGET (priv->transient_parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->transient_parent)), ((ctk_widget_get_type ())))
)))
))
7539 cdk_window_set_transient_for (cdk_window,
7540 _ctk_widget_get_window (CTK_WIDGET (priv->transient_parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->transient_parent)), ((ctk_widget_get_type ())))
)))
));
7541
7542 if (priv->wm_role)
7543 cdk_window_set_role (cdk_window, priv->wm_role);
7544
7545 if (!priv->decorated || priv->client_decorated)
7546 cdk_window_set_decorations (cdk_window, 0);
7547
7548#ifdef CDK_WINDOWING_WAYLAND
7549 if (CDK_IS_WAYLAND_WINDOW (cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_wayland_window_get_type()));
gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
))))
)
7550 {
7551 if (priv->client_decorated)
7552 cdk_wayland_window_announce_csd (cdk_window);
7553 else
7554 cdk_wayland_window_announce_ssd (cdk_window);
7555 }
7556#endif
7557
7558 if (!priv->deletable)
7559 cdk_window_set_functions (cdk_window, CDK_FUNC_ALL | CDK_FUNC_CLOSE);
7560
7561 if (ctk_window_get_skip_pager_hint (window))
7562 cdk_window_set_skip_pager_hint (cdk_window, TRUE(!(0)));
7563
7564 if (ctk_window_get_skip_taskbar_hint (window))
7565 cdk_window_set_skip_taskbar_hint (cdk_window, TRUE(!(0)));
7566
7567 if (ctk_window_get_accept_focus (window))
7568 cdk_window_set_accept_focus (cdk_window, TRUE(!(0)));
7569 else
7570 cdk_window_set_accept_focus (cdk_window, FALSE(0));
7571
7572 if (ctk_window_get_focus_on_map (window))
7573 cdk_window_set_focus_on_map (cdk_window, TRUE(!(0)));
7574 else
7575 cdk_window_set_focus_on_map (cdk_window, FALSE(0));
7576
7577 if (priv->modal)
7578 cdk_window_set_modal_hint (cdk_window, TRUE(!(0)));
7579 else
7580 cdk_window_set_modal_hint (cdk_window, FALSE(0));
7581
7582 if (priv->startup_id)
7583 {
7584#ifdef CDK_WINDOWING_X11
7585 if (CDK_IS_X11_WINDOW (cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
7586 {
7587 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
7588 if (timestamp != CDK_CURRENT_TIME0L)
7589 cdk_x11_window_set_user_time (cdk_window, timestamp);
7590 }
7591#endif
7592 if (!startup_id_is_fake (priv->startup_id))
7593 cdk_window_set_startup_id (cdk_window, priv->startup_id);
7594 }
7595
7596#ifdef CDK_WINDOWING_X11
7597 if (priv->initial_timestamp != CDK_CURRENT_TIME0L)
7598 {
7599 if (CDK_IS_X11_WINDOW (cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
7600 cdk_x11_window_set_user_time (cdk_window, priv->initial_timestamp);
7601 }
7602#endif
7603
7604 child_allocation.x = 0;
7605 child_allocation.y = 0;
7606 child_allocation.width = allocation.width;
7607 child_allocation.height = allocation.height;
7608
7609 get_shadow_width (window, &window_border);
7610
7611 update_realized_window_properties (window, &child_allocation, &window_border);
7612
7613 if (priv->application)
7614 ctk_application_handle_window_realize (priv->application, window);
7615
7616 /* Icons */
7617 ctk_window_realize_icon (window);
7618
7619 link = priv->popovers;
7620
7621 while (link)
7622 {
7623 CtkWindowPopover *popover = link->data;
7624 link = link->next;
7625 popover_realize (popover->widget, popover, window);
7626 }
7627
7628 check_scale_changed (window);
7629}
7630
7631static void
7632popover_unrealize (CtkWidget *widget,
7633 CtkWindowPopover *popover,
7634 CtkWindow *window)
7635{
7636#ifdef CDK_WINDOWING_WAYLAND
7637 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
7638 cdk_window_set_transient_for (popover->window, NULL((void*)0));
7639#endif
7640
7641 ctk_widget_unregister_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
, popover->window);
7642 ctk_widget_unrealize (popover->widget);
7643 cdk_window_destroy (popover->window);
7644 popover->window = NULL((void*)0);
7645}
7646
7647static void
7648ctk_window_unrealize (CtkWidget *widget)
7649{
7650 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
7651 CtkWindowPrivate *priv = window->priv;
7652 CtkWindowGeometryInfo *info;
7653 GList *link;
7654 gint i;
7655
7656 /* On unrealize, we reset the size of the window such
7657 * that we will re-apply the default sizing stuff
7658 * next time we show the window.
7659 *
7660 * Default positioning is reset on unmap, instead of unrealize.
7661 */
7662 priv->need_default_size = TRUE(!(0));
7663 info = ctk_window_get_geometry_info (window, FALSE(0));
7664 if (info)
7665 {
7666 info->resize_width = -1;
7667 info->resize_height = -1;
7668 info->last.configure_request.x = 0;
7669 info->last.configure_request.y = 0;
7670 info->last.configure_request.width = -1;
7671 info->last.configure_request.height = -1;
7672 /* be sure we reset geom hints on re-realize */
7673 info->last.flags = 0;
7674 }
7675
7676 if (priv->popup_menu)
7677 {
7678 ctk_widget_destroy (priv->popup_menu);
7679 priv->popup_menu = NULL((void*)0);
7680 }
7681
7682 /* Icons */
7683 ctk_window_unrealize_icon (window);
7684
7685 if (priv->border_window[0] != NULL((void*)0))
7686 {
7687 for (i = 0; i < 8; i++)
7688 {
7689 ctk_widget_unregister_window (widget, priv->border_window[i]);
7690 cdk_window_destroy (priv->border_window[i]);
7691 priv->border_window[i] = NULL((void*)0);
7692 }
7693 }
7694
7695 link = priv->popovers;
7696
7697 while (link)
7698 {
7699 CtkWindowPopover *popover = link->data;
7700 link = link->next;
7701 popover_unrealize (popover->widget, popover, window);
7702 }
7703
7704 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->unrealize (widget);
7705
7706 priv->hardcoded_window = NULL((void*)0);
7707}
7708
7709static void
7710update_window_style_classes (CtkWindow *window)
7711{
7712 CtkWindowPrivate *priv = window->priv;
7713 CtkStyleContext *context;
7714
7715 context = ctk_widget_get_style_context (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
7716
7717 if (priv->tiled)
7718 ctk_style_context_add_class (context, "tiled");
7719 else
7720 ctk_style_context_remove_class (context, "tiled");
7721
7722 if (priv->edge_constraints != 0)
7723 {
7724 guint edge_constraints = priv->edge_constraints;
7725
7726 if (edge_constraints & CDK_WINDOW_STATE_TOP_TILED)
7727 ctk_style_context_add_class (context, "tiled-top");
7728 else
7729 ctk_style_context_remove_class (context, "tiled-top");
7730
7731 if (edge_constraints & CDK_WINDOW_STATE_RIGHT_TILED)
7732 ctk_style_context_add_class (context, "tiled-right");
7733 else
7734 ctk_style_context_remove_class (context, "tiled-right");
7735
7736 if (edge_constraints & CDK_WINDOW_STATE_BOTTOM_TILED)
7737 ctk_style_context_add_class (context, "tiled-bottom");
7738 else
7739 ctk_style_context_remove_class (context, "tiled-bottom");
7740
7741 if (edge_constraints & CDK_WINDOW_STATE_LEFT_TILED)
7742 ctk_style_context_add_class (context, "tiled-left");
7743 else
7744 ctk_style_context_remove_class (context, "tiled-left");
7745 }
7746
7747 if (priv->maximized)
7748 ctk_style_context_add_class (context, "maximized");
7749 else
7750 ctk_style_context_remove_class (context, "maximized");
7751
7752 if (priv->fullscreen)
7753 ctk_style_context_add_class (context, "fullscreen");
7754 else
7755 ctk_style_context_remove_class (context, "fullscreen");
7756}
7757
7758static void
7759popover_size_allocate (CtkWidget *widget,
7760 CtkWindowPopover *popover,
7761 CtkWindow *window)
7762{
7763 cairo_rectangle_int_t rect;
7764
7765 if (!popover->window)
7766 return;
7767
7768 if (CTK_IS_POPOVER (popover->widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(popover->widget)); GType __t = ((ctk_popover_get_type ())
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
7769 ctk_popover_update_position (CTK_POPOVER (popover->widget)((((CtkPopover*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((popover->widget)), ((ctk_popover_get_type ()))))))
);
7770
7771 popover_get_rect (popover, window, &rect);
7772 cdk_window_move_resize (popover->window, rect.x, rect.y,
7773 rect.width, rect.height);
7774 rect.x = rect.y = 0;
7775 ctk_widget_size_allocate (widget, &rect);
7776
7777 if (ctk_widget_is_drawable (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
) &&
7778 ctk_widget_is_visible (widget))
7779 {
7780 if (!cdk_window_is_visible (popover->window))
7781 cdk_window_show_unraised (popover->window);
7782 }
7783 else if (cdk_window_is_visible (popover->window))
7784 cdk_window_hide (popover->window);
7785}
7786
7787/* _ctk_window_set_allocation:
7788 * @window: a #CtkWindow
7789 * @allocation: the original allocation for the window
7790 * @allocation_out: @allocation taking decorations into
7791 * consideration
7792 *
7793 * This function is like ctk_widget_set_allocation()
7794 * but does the necessary extra work to update
7795 * the resize grip positioning, etc.
7796 *
7797 * Call this instead of ctk_widget_set_allocation()
7798 * when overriding ::size_allocate in a CtkWindow
7799 * subclass without chaining up.
7800 *
7801 * The @allocation parameter will be adjusted to
7802 * reflect any internal decorations that the window
7803 * may have. That revised allocation will then be
7804 * returned in the @allocation_out parameter.
7805 */
7806void
7807_ctk_window_set_allocation (CtkWindow *window,
7808 const CtkAllocation *allocation,
7809 CtkAllocation *allocation_out)
7810{
7811 CtkWidget *widget = (CtkWidget *)window;
7812 CtkWindowPrivate *priv = window->priv;
7813 CtkAllocation child_allocation;
7814 gint border_width;
7815 CtkBorder window_border = { 0 };
7816 GList *link;
7817
7818 g_assert (allocation != NULL)do { if (allocation != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkwindow.c", 7818, ((const char*) (__func__)), "allocation != NULL"
); } while (0)
;
7819 g_assert (allocation_out != NULL)do { if (allocation_out != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkwindow.c", 7819, ((const char*) (__func__)), "allocation_out != NULL"
); } while (0)
;
7820
7821 ctk_widget_set_allocation (widget, allocation);
7822
7823 child_allocation.x = 0;
7824 child_allocation.y = 0;
7825 child_allocation.width = allocation->width;
7826 child_allocation.height = allocation->height;
7827
7828 get_shadow_width (window, &window_border);
7829
7830 if (_ctk_widget_get_realized (widget))
7831 update_realized_window_properties (window, &child_allocation, &window_border);
7832
7833 priv->title_height = 0;
7834
7835 if (priv->title_box != NULL((void*)0) &&
7836 ctk_widget_get_visible (priv->title_box) &&
7837 ctk_widget_get_child_visible (priv->title_box) &&
7838 priv->decorated &&
7839 !priv->fullscreen)
7840 {
7841 CtkAllocation title_allocation;
7842
7843 title_allocation.x = window_border.left;
7844 title_allocation.y = window_border.top;
7845 title_allocation.width =
7846 MAX (1, (gint) allocation->width -(((1) > ((gint) allocation->width - window_border.left -
window_border.right)) ? (1) : ((gint) allocation->width -
window_border.left - window_border.right))
7847 window_border.left - window_border.right)(((1) > ((gint) allocation->width - window_border.left -
window_border.right)) ? (1) : ((gint) allocation->width -
window_border.left - window_border.right))
;
7848
7849 ctk_widget_get_preferred_height_for_width (priv->title_box,
7850 title_allocation.width,
7851 NULL((void*)0),
7852 &priv->title_height);
7853
7854 title_allocation.height = priv->title_height;
7855
7856 ctk_widget_size_allocate (priv->title_box, &title_allocation);
7857 }
7858
7859 if (priv->decorated &&
7860 !priv->fullscreen)
7861 {
7862 child_allocation.x += window_border.left;
7863 child_allocation.y += window_border.top + priv->title_height;
7864 child_allocation.width -= window_border.left + window_border.right;
7865 child_allocation.height -= window_border.top + window_border.bottom +
7866 priv->title_height;
7867 }
7868
7869 if (!_ctk_widget_is_toplevel (widget) && _ctk_widget_get_realized (widget))
7870 {
7871 cdk_window_move_resize (_ctk_widget_get_window (widget),
7872 allocation->x, allocation->y,
7873 allocation->width, allocation->height);
7874 }
7875
7876 border_width = ctk_container_get_border_width (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
);
7877 child_allocation.x += border_width;
7878 child_allocation.y += border_width;
7879 child_allocation.width = MAX (1, child_allocation.width - border_width * 2)(((1) > (child_allocation.width - border_width * 2)) ? (1)
: (child_allocation.width - border_width * 2))
;
7880 child_allocation.height = MAX (1, child_allocation.height - border_width * 2)(((1) > (child_allocation.height - border_width * 2)) ? (1
) : (child_allocation.height - border_width * 2))
;
7881
7882 *allocation_out = child_allocation;
7883
7884 link = priv->popovers;
7885 while (link)
7886 {
7887 CtkWindowPopover *popover = link->data;
7888 link = link->next;
7889 popover_size_allocate (popover->widget, popover, window);
7890 }
7891
7892}
7893
7894static void
7895ctk_window_restack_popovers (CtkWindow *window)
7896{
7897 CtkWindowPrivate *priv = window->priv;
7898 GList *link = priv->popovers;
7899
7900 while (link)
7901 {
7902 CtkWindowPopover *popover = link->data;
7903 link = link->next;
7904
7905 if (popover->window)
7906 cdk_window_raise (popover->window);
7907 }
7908}
7909
7910static void
7911ctk_window_size_allocate (CtkWidget *widget,
7912 CtkAllocation *allocation)
7913{
7914 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
7915 CtkWidget *child;
7916 CtkAllocation child_allocation;
7917
7918 _ctk_window_set_allocation (window, allocation, &child_allocation);
7919
7920 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
7921 if (child && ctk_widget_get_visible (child))
7922 ctk_widget_size_allocate (child, &child_allocation);
7923
7924 ctk_window_restack_popovers (window);
7925}
7926
7927static gint
7928ctk_window_configure_event (CtkWidget *widget,
7929 CdkEventConfigure *event)
7930{
7931 CtkAllocation allocation;
7932 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
7933 CtkWindowPrivate *priv = window->priv;
7934
7935 check_scale_changed (window);
7936
7937 if (!_ctk_widget_is_toplevel (widget))
7938 return FALSE(0);
7939
7940 if (_ctk_widget_get_window (widget) != event->window)
7941 return TRUE(!(0));
7942
7943 /* If this is a gratuitous ConfigureNotify that's already
7944 * the same as our allocation, then we can fizzle it out.
7945 * This is the case for dragging windows around.
7946 *
7947 * We can't do this for a ConfigureRequest, since it might
7948 * have been a queued resize from child widgets, and so we
7949 * need to reallocate our children in case *they* changed.
7950 */
7951 _ctk_widget_get_allocation (widget, &allocation);
7952 if (priv->configure_request_count == 0 &&
7953 (allocation.width == event->width &&
7954 allocation.height == event->height))
7955 {
7956 return TRUE(!(0));
7957 }
7958
7959 /* priv->configure_request_count incremented for each
7960 * configure request, and decremented to a min of 0 for
7961 * each configure notify.
7962 *
7963 * All it means is that we know we will get at least
7964 * priv->configure_request_count more configure notifies.
7965 * We could get more configure notifies than that; some
7966 * of the configure notifies we get may be unrelated to
7967 * the configure requests. But we will get at least
7968 * priv->configure_request_count notifies.
7969 */
7970
7971 if (priv->configure_request_count > 0)
7972 {
7973 priv->configure_request_count -= 1;
7974
7975 CDK_PRIVATE_CALL (cdk_window_thaw_toplevel_updates)(cdk__private__ ()->cdk_window_thaw_toplevel_updates) (_ctk_widget_get_window (widget));
7976 }
7977
7978 /*
7979 * If we do need to resize, we do that by:
7980 * - setting configure_notify_received to TRUE
7981 * for use in ctk_window_move_resize()
7982 * - queueing a resize, leading to invocation of
7983 * ctk_window_move_resize() in an idle handler
7984 *
7985 */
7986
7987 priv->configure_notify_received = TRUE(!(0));
7988
7989 ctk_widget_queue_allocate (widget);
7990 ctk_container_queue_resize_handler (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
);
7991
7992 return TRUE(!(0));
7993}
7994
7995static void
7996update_edge_constraints (CtkWindow *window,
7997 CdkEventWindowState *event)
7998{
7999 CtkWindowPrivate *priv = window->priv;
8000 CdkWindowState state = event->new_window_state;
8001
8002 priv->edge_constraints = (state & CDK_WINDOW_STATE_TOP_TILED) |
8003 (state & CDK_WINDOW_STATE_TOP_RESIZABLE) |
8004 (state & CDK_WINDOW_STATE_RIGHT_TILED) |
8005 (state & CDK_WINDOW_STATE_RIGHT_RESIZABLE) |
8006 (state & CDK_WINDOW_STATE_BOTTOM_TILED) |
8007 (state & CDK_WINDOW_STATE_BOTTOM_RESIZABLE) |
8008 (state & CDK_WINDOW_STATE_LEFT_TILED) |
8009 (state & CDK_WINDOW_STATE_LEFT_RESIZABLE);
8010
8011 priv->tiled = (state & CDK_WINDOW_STATE_TILED) ? 1 : 0;
8012}
8013
8014static gboolean
8015ctk_window_state_event (CtkWidget *widget,
8016 CdkEventWindowState *event)
8017{
8018 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8019 CtkWindowPrivate *priv = window->priv;
8020
8021 if (event->changed_mask & CDK_WINDOW_STATE_FOCUSED)
8022 ensure_state_flag_backdrop (widget);
8023
8024 if (event->changed_mask & CDK_WINDOW_STATE_FULLSCREEN)
8025 {
8026 priv->fullscreen =
8027 (event->new_window_state & CDK_WINDOW_STATE_FULLSCREEN) ? 1 : 0;
8028 }
8029
8030 if (event->changed_mask & CDK_WINDOW_STATE_MAXIMIZED)
8031 {
8032 priv->maximized =
8033 (event->new_window_state & CDK_WINDOW_STATE_MAXIMIZED) ? 1 : 0;
8034 g_object_notify_by_pspec (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), (((GType) ((20) << (2))))))))
, window_props[PROP_IS_MAXIMIZED]);
8035 }
8036
8037 update_edge_constraints (window, event);
8038
8039 if (event->changed_mask & (CDK_WINDOW_STATE_FULLSCREEN |
8040 CDK_WINDOW_STATE_MAXIMIZED |
8041 CDK_WINDOW_STATE_TILED |
8042 CDK_WINDOW_STATE_TOP_TILED |
8043 CDK_WINDOW_STATE_RIGHT_TILED |
8044 CDK_WINDOW_STATE_BOTTOM_TILED |
8045 CDK_WINDOW_STATE_LEFT_TILED))
8046 {
8047 update_window_style_classes (window);
8048 update_window_buttons (window);
8049 ctk_widget_queue_resize (widget);
8050 }
8051
8052 return FALSE(0);
8053}
8054
8055/**
8056 * ctk_window_set_has_resize_grip:
8057 * @window: a #CtkWindow
8058 * @value: %TRUE to allow a resize grip
8059 *
8060 * Sets whether @window has a corner resize grip.
8061 *
8062 * Note that the resize grip is only shown if the window
8063 * is actually resizable and not maximized. Use
8064 * ctk_window_resize_grip_is_visible() to find out if the
8065 * resize grip is currently shown.
8066 *
8067 * Since: 3.0
8068 *
8069 * Deprecated: 3.14: Resize grips have been removed.
8070 */
8071void
8072ctk_window_set_has_resize_grip (CtkWindow *window,
8073 gboolean value G_GNUC_UNUSED__attribute__ ((__unused__)))
8074{
8075 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
8076}
8077
8078/**
8079 * ctk_window_resize_grip_is_visible:
8080 * @window: a #CtkWindow
8081 *
8082 * Determines whether a resize grip is visible for the specified window.
8083 *
8084 * Returns: %TRUE if a resize grip exists and is visible
8085 *
8086 * Since: 3.0
8087 *
8088 * Deprecated: 3.14: Resize grips have been removed.
8089 */
8090gboolean
8091ctk_window_resize_grip_is_visible (CtkWindow *window)
8092{
8093 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
8094
8095 return FALSE(0);
8096}
8097
8098/**
8099 * ctk_window_get_has_resize_grip:
8100 * @window: a #CtkWindow
8101 *
8102 * Determines whether the window may have a resize grip.
8103 *
8104 * Returns: %TRUE if the window has a resize grip
8105 *
8106 * Since: 3.0
8107 *
8108 * Deprecated: 3.14: Resize grips have been removed.
8109 */
8110gboolean
8111ctk_window_get_has_resize_grip (CtkWindow *window)
8112
8113{
8114 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
8115
8116 return FALSE(0);
8117}
8118
8119/**
8120 * ctk_window_get_resize_grip_area:
8121 * @window: a #CtkWindow
8122 * @rect: (out): a pointer to a #CdkRectangle which we should store
8123 * the resize grip area
8124 *
8125 * If a window has a resize grip, this will retrieve the grip
8126 * position, width and height into the specified #CdkRectangle.
8127 *
8128 * Returns: %TRUE if the resize grip’s area was retrieved
8129 *
8130 * Since: 3.0
8131 *
8132 * Deprecated: 3.14: Resize grips have been removed.
8133 */
8134gboolean
8135ctk_window_get_resize_grip_area (CtkWindow *window,
8136 CdkRectangle *rect G_GNUC_UNUSED__attribute__ ((__unused__)))
8137{
8138 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
8139
8140 return FALSE(0);
8141}
8142
8143/* the accel_key and accel_mods fields of the key have to be setup
8144 * upon calling this function. it’ll then return whether that key
8145 * is at all used as accelerator, and if so will OR in the
8146 * accel_flags member of the key.
8147 */
8148gboolean
8149_ctk_window_query_nonaccels (CtkWindow *window,
8150 guint accel_key,
8151 CdkModifierType accel_mods)
8152{
8153 CtkWindowPrivate *priv;
8154
8155 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
8156
8157 priv = window->priv;
8158
8159 /* movement keys are considered locked accels */
8160 if (!accel_mods)
8161 {
8162 static const guint bindings[] = {
8163 CDK_KEY_space0x020, CDK_KEY_KP_Space0xff80, CDK_KEY_Return0xff0d, CDK_KEY_ISO_Enter0xfe34, CDK_KEY_KP_Enter0xff8d, CDK_KEY_Up0xff52, CDK_KEY_KP_Up0xff97, CDK_KEY_Down0xff54, CDK_KEY_KP_Down0xff99,
8164 CDK_KEY_Left0xff51, CDK_KEY_KP_Left0xff96, CDK_KEY_Right0xff53, CDK_KEY_KP_Right0xff98, CDK_KEY_Tab0xff09, CDK_KEY_KP_Tab0xff89, CDK_KEY_ISO_Left_Tab0xfe20,
8165 };
8166 guint i;
8167
8168 for (i = 0; i < G_N_ELEMENTS (bindings)(sizeof (bindings) / sizeof ((bindings)[0])); i++)
8169 if (bindings[i] == accel_key)
8170 return TRUE(!(0));
8171 }
8172
8173 /* mnemonics are considered locked accels */
8174 if (accel_mods == priv->mnemonic_modifier)
8175 {
8176 CtkMnemonicHash *mnemonic_hash = ctk_window_get_mnemonic_hash (window, FALSE(0));
8177 if (mnemonic_hash && _ctk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
8178 return TRUE(!(0));
8179 }
8180
8181 return FALSE(0);
8182}
8183
8184/**
8185 * ctk_window_propagate_key_event:
8186 * @window: a #CtkWindow
8187 * @event: a #CdkEventKey
8188 *
8189 * Propagate a key press or release event to the focus widget and
8190 * up the focus container chain until a widget handles @event.
8191 * This is normally called by the default ::key_press_event and
8192 * ::key_release_event handlers for toplevel windows,
8193 * however in some cases it may be useful to call this directly when
8194 * overriding the standard key handling for a toplevel window.
8195 *
8196 * Returns: %TRUE if a widget in the focus chain handled the event.
8197 *
8198 * Since: 2.4
8199 */
8200gboolean
8201ctk_window_propagate_key_event (CtkWindow *window,
8202 CdkEventKey *event)
8203{
8204 CtkWindowPrivate *priv = window->priv;
8205 gboolean handled = FALSE(0);
8206 CtkWidget *widget, *focus;
8207
8208 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
8209
8210 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
8211
8212 focus = priv->focus_widget;
8213 if (focus)
8214 g_object_ref (focus)((__typeof__ (focus)) (g_object_ref) (focus));
8215
8216 while (!handled &&
8217 focus && focus != widget &&
8218 ctk_widget_get_toplevel (focus) == widget)
8219 {
8220 CtkWidget *parent;
8221
8222 if (ctk_widget_is_sensitive (focus))
8223 {
8224 handled = ctk_widget_event (focus, (CdkEvent*) event);
8225 if (handled)
8226 break;
8227 }
8228
8229 parent = _ctk_widget_get_parent (focus);
8230 if (parent)
8231 g_object_ref (parent)((__typeof__ (parent)) (g_object_ref) (parent));
8232
8233 g_object_unref (focus);
8234
8235 focus = parent;
8236 }
8237
8238 if (focus)
8239 g_object_unref (focus);
8240
8241 return handled;
8242}
8243
8244static gint
8245ctk_window_key_press_event (CtkWidget *widget,
8246 CdkEventKey *event)
8247{
8248 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8249 gboolean handled = FALSE(0);
8250
8251 /* handle mnemonics and accelerators */
8252 if (!handled)
8253 handled = ctk_window_activate_key (window, event);
8254
8255 /* handle focus widget key events */
8256 if (!handled)
8257 handled = ctk_window_propagate_key_event (window, event);
8258
8259 /* Chain up, invokes binding set */
8260 if (!handled)
8261 handled = CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->key_press_event (widget, event);
8262
8263 return handled;
8264}
8265
8266static gint
8267ctk_window_key_release_event (CtkWidget *widget,
8268 CdkEventKey *event)
8269{
8270 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8271 gboolean handled = FALSE(0);
8272
8273 /* handle focus widget key events */
8274 if (!handled)
8275 handled = ctk_window_propagate_key_event (window, event);
8276
8277 /* Chain up, invokes binding set */
8278 if (!handled)
8279 handled = CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->key_release_event (widget, event);
8280
8281 return handled;
8282}
8283
8284static CtkWindowRegion
8285get_active_region_type (CtkWindow *window, CdkEventAny *event, gint x, gint y)
8286{
8287 CtkWindowPrivate *priv = window->priv;
8288 CtkAllocation allocation;
8289 gint i;
8290
8291 for (i = 0; i < 8; i++)
8292 {
8293 if (event->window == priv->border_window[i])
8294 return i;
8295 }
8296
8297 if (priv->title_box != NULL((void*)0) &&
8298 ctk_widget_get_visible (priv->title_box) &&
8299 ctk_widget_get_child_visible (priv->title_box))
8300 {
8301 _ctk_widget_get_allocation (priv->title_box, &allocation);
8302 if (allocation.x <= x && allocation.x + allocation.width > x &&
8303 allocation.y <= y && allocation.y + allocation.height > y)
8304 return CTK_WINDOW_REGION_TITLE;
8305 }
8306
8307 return CTK_WINDOW_REGION_CONTENT;
8308}
8309
8310static gboolean
8311controller_handle_wm_event (CtkGesture *gesture,
8312 const CdkEvent *event)
8313{
8314 CdkEventSequence *seq;
8315 gboolean retval;
8316
8317 seq = cdk_event_get_event_sequence (event);
8318 retval = ctk_event_controller_handle_event (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
,
8319 event);
8320
8321 /* Reset immediately the gestures, here we don't get many guarantees
8322 * about whether the target window event mask will be complete enough
8323 * to keep gestures consistent, or whether any widget across the
8324 * hierarchy will be inconsistent about event handler return values.
8325 */
8326 if (ctk_gesture_get_sequence_state (gesture, seq) == CTK_EVENT_SEQUENCE_DENIED)
8327 ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type
()))))))
);
8328
8329 return retval;
8330}
8331
8332static gboolean
8333ctk_window_handle_wm_event (CtkWindow *window,
8334 CdkEvent *event,
8335 gboolean run_drag)
8336{
8337 gboolean retval = CDK_EVENT_PROPAGATE((0));
8338 CtkWindowPrivate *priv;
8339
8340 if (event->type == CDK_BUTTON_PRESS || event->type == CDK_BUTTON_RELEASE ||
8341 event->type == CDK_TOUCH_BEGIN || event->type == CDK_TOUCH_UPDATE ||
8342 event->type == CDK_MOTION_NOTIFY || event->type == CDK_TOUCH_END)
8343 {
8344 priv = window->priv;
8345
8346 if (run_drag && priv->drag_gesture)
8347 retval |= controller_handle_wm_event (priv->drag_gesture,
8348 (const CdkEvent*) event);
8349
8350 if (priv->multipress_gesture)
8351 retval |= controller_handle_wm_event (priv->multipress_gesture,
8352 (const CdkEvent*) event);
8353 }
8354
8355 return retval;
8356}
8357
8358gboolean
8359_ctk_window_check_handle_wm_event (CdkEvent *event)
8360{
8361 CtkWindowPrivate *priv;
8362 CtkWidget *widget;
8363
8364 widget = ctk_get_event_widget (event);
8365
8366 if (!CTK_IS_WINDOW (widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(widget)); GType __t = ((ctk_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
8367 widget = ctk_widget_get_toplevel (widget);
8368
8369 if (!CTK_IS_WINDOW (widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(widget)); GType __t = ((ctk_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
8370 return CDK_EVENT_PROPAGATE((0));
8371
8372 priv = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
->priv;
8373
8374 if (!priv->multipress_gesture)
8375 return CDK_EVENT_PROPAGATE((0));
8376
8377 if (event->type != CDK_BUTTON_PRESS && event->type != CDK_BUTTON_RELEASE &&
8378 event->type != CDK_MOTION_NOTIFY && event->type != CDK_TOUCH_BEGIN &&
8379 event->type != CDK_TOUCH_END && event->type != CDK_TOUCH_UPDATE)
8380 return CDK_EVENT_PROPAGATE((0));
8381
8382 if (ctk_widget_event (widget, event))
8383 return CDK_EVENT_STOP((!(0)));
8384
8385 return ctk_window_handle_wm_event (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
, event, TRUE(!(0)));
8386}
8387
8388static gboolean
8389ctk_window_event (CtkWidget *widget,
8390 CdkEvent *event)
8391{
8392 if (widget != ctk_get_event_widget (event))
8393 return ctk_window_handle_wm_event (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
, event, FALSE(0));
8394
8395 return CDK_EVENT_PROPAGATE((0));
8396}
8397
8398static void
8399ctk_window_real_activate_default (CtkWindow *window)
8400{
8401 ctk_window_activate_default (window);
8402}
8403
8404static void
8405ctk_window_real_activate_focus (CtkWindow *window)
8406{
8407 ctk_window_activate_focus (window);
8408}
8409
8410static void
8411do_focus_change (CtkWidget *widget,
8412 gboolean in)
8413{
8414 CdkWindow *window;
8415 CdkDeviceManager *device_manager;
8416 GList *devices, *d;
8417
8418 g_object_ref (widget)((__typeof__ (widget)) (g_object_ref) (widget));
8419
8420 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
8421 device_manager = cdk_display_get_device_manager (ctk_widget_get_display (widget));
8422 devices = cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_MASTER);
8423 devices = g_list_concat (devices, cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_SLAVE));
8424 devices = g_list_concat (devices, cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_FLOATING));
8425 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
8426
8427 for (d = devices; d; d = d->next)
8428 {
8429 CdkDevice *dev = d->data;
8430 CdkEvent *fevent;
8431
8432 if (cdk_device_get_source (dev) != CDK_SOURCE_KEYBOARD)
8433 continue;
8434
8435 /* Skip non-master keyboards that haven't
8436 * selected for events from this window
8437 */
8438 window = _ctk_widget_get_window (widget);
8439 if (cdk_device_get_device_type (dev) != CDK_DEVICE_TYPE_MASTER &&
8440 window && !cdk_window_get_device_events (window, dev))
8441 continue;
8442
8443 fevent = cdk_event_new (CDK_FOCUS_CHANGE);
8444
8445 fevent->focus_change.type = CDK_FOCUS_CHANGE;
8446 fevent->focus_change.window = window;
8447 if (window)
8448 g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
8449 fevent->focus_change.in = in;
8450 cdk_event_set_device (fevent, dev);
8451
8452 ctk_widget_send_focus_change (widget, fevent);
8453
8454 cdk_event_free (fevent);
8455 }
8456
8457 g_list_free (devices);
8458 g_object_unref (widget);
8459}
8460
8461static gboolean
8462ctk_window_has_mnemonic_modifier_pressed (CtkWindow *window)
8463{
8464 GList *seats, *s;
8465 gboolean retval = FALSE(0);
8466
8467 if (!window->priv->mnemonic_modifier)
8468 return FALSE(0);
8469
8470 seats = cdk_display_list_seats (ctk_widget_get_display (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
));
8471
8472 for (s = seats; s; s = s->next)
8473 {
8474 CdkDevice *dev = cdk_seat_get_pointer (s->data);
8475 CdkModifierType mask;
8476
8477 cdk_device_get_state (dev, _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
8478 NULL((void*)0), &mask);
8479 if (window->priv->mnemonic_modifier == (mask & ctk_accelerator_get_default_mod_mask ()))
8480 {
8481 retval = TRUE(!(0));
8482 break;
8483 }
8484 }
8485
8486 g_list_free (seats);
8487
8488 return retval;
8489}
8490
8491static gint
8492ctk_window_focus_in_event (CtkWidget *widget,
8493 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)))
8494{
8495 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8496
8497 /* It appears spurious focus in events can occur when
8498 * the window is hidden. So we'll just check to see if
8499 * the window is visible before actually handling the
8500 * event
8501 */
8502 if (ctk_widget_get_visible (widget))
8503 {
8504 _ctk_window_set_has_toplevel_focus (window, TRUE(!(0)));
8505 _ctk_window_set_is_active (window, TRUE(!(0)));
8506
8507 if (ctk_window_has_mnemonic_modifier_pressed (window))
8508 _ctk_window_schedule_mnemonics_visible (window);
8509 }
8510
8511 return FALSE(0);
8512}
8513
8514static gint
8515ctk_window_focus_out_event (CtkWidget *widget,
8516 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)))
8517{
8518 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8519
8520 _ctk_window_set_has_toplevel_focus (window, FALSE(0));
8521 _ctk_window_set_is_active (window, FALSE(0));
8522
8523 /* set the mnemonic-visible property to false */
8524 ctk_window_set_mnemonics_visible (window, FALSE(0));
8525
8526 return FALSE(0);
8527}
8528
8529static CtkWindowPopover *
8530_ctk_window_has_popover (CtkWindow *window,
8531 CtkWidget *widget)
8532{
8533 CtkWindowPrivate *priv = window->priv;
8534 GList *link;
8535
8536 for (link = priv->popovers; link; link = link->next)
8537 {
8538 CtkWindowPopover *popover = link->data;
8539
8540 if (popover->widget == widget)
8541 return popover;
8542 }
8543
8544 return NULL((void*)0);
8545}
8546
8547static void
8548ctk_window_remove (CtkContainer *container,
8549 CtkWidget *widget)
8550{
8551 CtkWindow *window = CTK_WINDOW (container)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_window_get_type ()))))))
;
8552
8553 if (widget == window->priv->title_box)
8554 unset_titlebar (window);
8555 else if (_ctk_window_has_popover (window, widget))
8556 _ctk_window_remove_popover (window, widget);
8557 else
8558 CTK_CONTAINER_CLASS (ctk_window_parent_class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_container_get_type ()))
))))
->remove (container, widget);
8559}
8560
8561static void
8562ctk_window_check_resize (CtkContainer *container)
8563{
8564 /* If the window is not toplevel anymore than it's embedded somewhere,
8565 * so handle it like a normal window */
8566 if (!_ctk_widget_is_toplevel (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
))
8567 CTK_CONTAINER_CLASS (ctk_window_parent_class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_container_get_type ()))
))))
->check_resize (container);
8568 else if (!_ctk_widget_get_alloc_needed (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
))
8569 CTK_CONTAINER_CLASS (ctk_window_parent_class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_container_get_type ()))
))))
->check_resize (container);
8570 else if (ctk_widget_get_visible (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
))
8571 ctk_window_move_resize (CTK_WINDOW (container)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_window_get_type ()))))))
);
8572}
8573
8574static void
8575ctk_window_forall (CtkContainer *container,
8576 gboolean include_internals,
8577 CtkCallback callback,
8578 gpointer callback_data)
8579{
8580 CtkWindow *window = CTK_WINDOW (container)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_window_get_type ()))))))
;
8581 CtkWindowPrivate *priv = window->priv;
8582 CtkWidget *child;
8583
8584 if (include_internals)
8585 {
8586 GList *l;
8587
8588 for (l = priv->popovers; l; l = l->next)
8589 {
8590 CtkWindowPopover *data = l->data;
8591 (* callback) (data->widget, callback_data);
8592 }
8593 }
8594
8595 child = ctk_bin_get_child (CTK_BIN (container)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_bin_get_type ()))))))
);
8596 if (child != NULL((void*)0))
8597 (* callback) (child, callback_data);
8598
8599 if (priv->title_box != NULL((void*)0) &&
8600 (priv->titlebar == NULL((void*)0) || include_internals))
8601 (* callback) (priv->title_box, callback_data);
8602}
8603
8604static gboolean
8605ctk_window_focus (CtkWidget *widget,
8606 CtkDirectionType direction)
8607{
8608 CtkWindowPrivate *priv;
8609 CtkBin *bin;
8610 CtkWindow *window;
8611 CtkContainer *container;
8612 CtkWidget *child;
8613 CtkWidget *old_focus_child;
8614 CtkWidget *parent;
8615
8616 if (!_ctk_widget_is_toplevel (widget))
8617 return CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->focus (widget, direction);
8618
8619 container = CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
;
8620 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8621 priv = window->priv;
8622 bin = CTK_BIN (widget)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_bin_get_type ()))))))
;
8623
8624 old_focus_child = ctk_container_get_focus_child (container);
8625
8626 /* We need a special implementation here to deal properly with wrapping
8627 * around in the tab chain without the danger of going into an
8628 * infinite loop.
8629 */
8630 if (old_focus_child)
8631 {
8632 if (ctk_widget_child_focus (old_focus_child, direction))
8633 return TRUE(!(0));
8634 }
8635
8636 if (priv->focus_widget)
8637 {
8638 if (direction == CTK_DIR_LEFT ||
8639 direction == CTK_DIR_RIGHT ||
8640 direction == CTK_DIR_UP ||
8641 direction == CTK_DIR_DOWN)
8642 {
8643 return FALSE(0);
8644 }
8645
8646 /* Wrapped off the end, clear the focus setting for the toplpevel */
8647 parent = _ctk_widget_get_parent (priv->focus_widget);
8648 while (parent)
8649 {
8650 ctk_container_set_focus_child (CTK_CONTAINER (parent)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_container_get_type ()))))))
, NULL((void*)0));
8651 parent = _ctk_widget_get_parent (parent);
8652 }
8653
8654 ctk_window_set_focus (CTK_WINDOW (container)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_window_get_type ()))))))
, NULL((void*)0));
8655 }
8656
8657 /* Now try to focus the first widget in the window,
8658 * taking care to hook titlebar widgets into the
8659 * focus chain.
8660 */
8661 if (priv->title_box != NULL((void*)0) &&
8662 old_focus_child != NULL((void*)0) &&
8663 priv->title_box != old_focus_child)
8664 child = priv->title_box;
8665 else
8666 child = ctk_bin_get_child (bin);
8667
8668 if (child)
8669 {
8670 if (ctk_widget_child_focus (child, direction))
8671 return TRUE(!(0));
8672 else if (priv->title_box != NULL((void*)0) &&
8673 priv->title_box != child &&
8674 ctk_widget_child_focus (priv->title_box, direction))
8675 return TRUE(!(0));
8676 else if (priv->title_box == child &&
8677 ctk_widget_child_focus (ctk_bin_get_child (bin), direction))
8678 return TRUE(!(0));
8679 }
8680
8681 return FALSE(0);
8682}
8683
8684static void
8685ctk_window_move_focus (CtkWidget *widget,
8686 CtkDirectionType dir)
8687{
8688 if (!_ctk_widget_is_toplevel (widget))
8689 {
8690 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->move_focus (widget, dir);
8691 return;
8692 }
8693
8694 ctk_widget_child_focus (widget, dir);
8695
8696 if (! ctk_container_get_focus_child (CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
))
8697 ctk_window_set_focus (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
, NULL((void*)0));
8698}
8699
8700static void
8701ctk_window_real_set_focus (CtkWindow *window,
8702 CtkWidget *focus)
8703{
8704 CtkWindowPrivate *priv = window->priv;
8705 CtkWidget *old_focus = priv->focus_widget;
8706 gboolean had_default = FALSE(0);
8707 gboolean focus_had_default = FALSE(0);
8708 gboolean old_focus_had_default = FALSE(0);
8709
8710 if (old_focus)
8711 {
8712 g_object_ref (old_focus)((__typeof__ (old_focus)) (g_object_ref) (old_focus));
8713 g_object_freeze_notify (G_OBJECT (old_focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((old_focus)), (((GType) ((20) << (2))))))))
);
8714 old_focus_had_default = ctk_widget_has_default (old_focus);
8715 }
8716 if (focus)
8717 {
8718 g_object_ref (focus)((__typeof__ (focus)) (g_object_ref) (focus));
8719 g_object_freeze_notify (G_OBJECT (focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((focus)), (((GType) ((20) << (2))))))))
);
8720 focus_had_default = ctk_widget_has_default (focus);
8721 }
8722
8723 if (priv->default_widget)
8724 had_default = ctk_widget_has_default (priv->default_widget);
8725
8726 if (priv->focus_widget)
8727 {
8728 if (ctk_widget_get_receives_default (priv->focus_widget) &&
8729 (priv->focus_widget != priv->default_widget))
8730 {
8731 _ctk_widget_set_has_default (priv->focus_widget, FALSE(0));
8732 ctk_widget_queue_draw (priv->focus_widget);
8733
8734 if (priv->default_widget)
8735 _ctk_widget_set_has_default (priv->default_widget, TRUE(!(0)));
8736 }
8737
8738 priv->focus_widget = NULL((void*)0);
8739
8740 if (priv->has_focus)
8741 do_focus_change (old_focus, FALSE(0));
8742
8743 g_object_notify (G_OBJECT (old_focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((old_focus)), (((GType) ((20) << (2))))))))
, "is-focus");
8744 }
8745
8746 /* The above notifications may have set a new focus widget,
8747 * if so, we don't want to override it.
8748 */
8749 if (focus && !priv->focus_widget)
8750 {
8751 priv->focus_widget = focus;
8752
8753 if (ctk_widget_get_receives_default (priv->focus_widget) &&
8754 (priv->focus_widget != priv->default_widget))
8755 {
8756 if (ctk_widget_get_can_default (priv->focus_widget))
8757 _ctk_widget_set_has_default (priv->focus_widget, TRUE(!(0)));
8758
8759 if (priv->default_widget)
8760 _ctk_widget_set_has_default (priv->default_widget, FALSE(0));
8761 }
8762
8763 if (priv->has_focus)
8764 do_focus_change (priv->focus_widget, TRUE(!(0)));
8765
8766 /* It's possible for do_focus_change() above to have callbacks
8767 * that clear priv->focus_widget here.
8768 */
8769 if (priv->focus_widget)
8770 g_object_notify (G_OBJECT (priv->focus_widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->focus_widget)), (((GType) ((20) << (2))))
))))
, "is-focus");
8771 }
8772
8773 /* If the default widget changed, a redraw will have been queued
8774 * on the old and new default widgets by ctk_window_set_default(), so
8775 * we only have to worry about the case where it didn't change.
8776 * We'll sometimes queue a draw twice on the new widget but that
8777 * is harmless.
8778 */
8779 if (priv->default_widget &&
8780 (had_default != ctk_widget_has_default (priv->default_widget)))
8781 ctk_widget_queue_draw (priv->default_widget);
8782
8783 if (old_focus)
8784 {
8785 if (old_focus_had_default != ctk_widget_has_default (old_focus))
8786 ctk_widget_queue_draw (old_focus);
8787
8788 g_object_thaw_notify (G_OBJECT (old_focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((old_focus)), (((GType) ((20) << (2))))))))
);
8789 g_object_unref (old_focus);
8790 }
8791 if (focus)
8792 {
8793 if (focus_had_default != ctk_widget_has_default (focus))
8794 ctk_widget_queue_draw (focus);
8795
8796 g_object_thaw_notify (G_OBJECT (focus)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((focus)), (((GType) ((20) << (2))))))))
);
8797 g_object_unref (focus);
8798 }
8799}
8800
8801static void
8802ctk_window_get_preferred_width (CtkWidget *widget,
8803 gint *minimum_size,
8804 gint *natural_size)
8805{
8806 CtkWindow *window;
8807 CtkWidget *child;
8808 CtkWindowPrivate *priv;
8809 guint border_width;
8810 gint title_min = 0, title_nat = 0;
8811 gint child_min = 0, child_nat = 0;
8812 CtkBorder window_border = { 0 };
8813 gboolean has_size_request;
8814
8815 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8816 priv = window->priv;
8817 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
8818 has_size_request = ctk_widget_has_size_request (widget);
8819
8820 border_width = ctk_container_get_border_width (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
);
8821
8822 if (priv->decorated &&
8823 !priv->fullscreen)
8824 {
8825 get_shadow_width (window, &window_border);
8826
8827 if (priv->title_box != NULL((void*)0) &&
8828 ctk_widget_get_visible (priv->title_box) &&
8829 ctk_widget_get_child_visible (priv->title_box))
8830 ctk_widget_get_preferred_width (priv->title_box,
8831 &title_min, &title_nat);
8832
8833 title_min += window_border.left + window_border.right;
8834 title_nat += window_border.left + window_border.right;
8835 }
8836
8837 if (child && ctk_widget_get_visible (child))
8838 {
8839 ctk_widget_get_preferred_width (child, &child_min, &child_nat);
8840
8841 if (child_nat == 0 && !has_size_request)
8842 child_nat = NO_CONTENT_CHILD_NAT200;
8843 child_min += border_width * 2 +
8844 window_border.left + window_border.right;
8845 child_nat += border_width * 2 +
8846 window_border.left + window_border.right;
8847 }
8848 else if (!has_size_request)
8849 {
8850 child_nat = NO_CONTENT_CHILD_NAT200;
8851 }
8852
8853 *minimum_size = MAX (title_min, child_min)(((title_min) > (child_min)) ? (title_min) : (child_min));
8854 *natural_size = MAX (title_nat, child_nat)(((title_nat) > (child_nat)) ? (title_nat) : (child_nat));
8855}
8856
8857
8858static void
8859ctk_window_get_preferred_width_for_height (CtkWidget *widget,
8860 gint height,
8861 gint *minimum_size,
8862 gint *natural_size)
8863{
8864 CtkWindow *window;
8865 CtkWidget *child;
8866 CtkWindowPrivate *priv;
8867 guint border_width;
8868 gint title_min = 0, title_nat = 0;
8869 gint child_min = 0, child_nat = 0;
8870 gint title_height = 0;
8871 CtkBorder window_border = { 0 };
8872 gboolean has_size_request;
8873
8874 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8875 priv = window->priv;
8876 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
8877 has_size_request = ctk_widget_has_size_request (widget);
8878
8879 border_width = ctk_container_get_border_width (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
);
8880
8881 height -= 2 * border_width;
8882
8883 if (priv->decorated &&
8884 !priv->fullscreen)
8885 {
8886 get_shadow_width (window, &window_border);
8887
8888 height -= window_border.top + window_border.bottom;
8889
8890 if (priv->title_box != NULL((void*)0) &&
8891 ctk_widget_get_visible (priv->title_box) &&
8892 ctk_widget_get_child_visible (priv->title_box))
8893 {
8894 ctk_widget_get_preferred_height (priv->title_box,
8895 NULL((void*)0), &title_height);
8896 ctk_widget_get_preferred_width_for_height (priv->title_box,
8897 title_height,
8898 &title_min, &title_nat);
8899 height -= title_height;
8900 }
8901
8902 title_min += window_border.left + window_border.right;
8903 title_nat += window_border.left + window_border.right;
8904 }
8905
8906 if (child && ctk_widget_get_visible (child))
8907 {
8908 ctk_widget_get_preferred_width_for_height (child,
8909 MAX (height, 0)(((height) > (0)) ? (height) : (0)),
8910 &child_min, &child_nat);
8911
8912 if (child_nat == 0 && height == 0 && !has_size_request)
8913 child_nat = NO_CONTENT_CHILD_NAT200;
8914 child_min += border_width * 2 +
8915 window_border.left + window_border.right;
8916 child_nat += border_width * 2 +
8917 window_border.left + window_border.right;
8918 }
8919 else if (!has_size_request)
8920 {
8921 child_nat = NO_CONTENT_CHILD_NAT200;
8922 }
8923
8924 *minimum_size = MAX (title_min, child_min)(((title_min) > (child_min)) ? (title_min) : (child_min));
8925 *natural_size = MAX (title_nat, child_nat)(((title_nat) > (child_nat)) ? (title_nat) : (child_nat));
8926}
8927
8928static void
8929ctk_window_get_preferred_height (CtkWidget *widget,
8930 gint *minimum_size,
8931 gint *natural_size)
8932{
8933 CtkWindow *window;
8934 CtkWindowPrivate *priv;
8935 CtkWidget *child;
8936 guint border_width;
8937 int title_min = 0;
8938 int title_height = 0;
8939 CtkBorder window_border = { 0 };
8940 gboolean has_size_request;
8941
8942 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
8943 priv = window->priv;
8944 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
8945 has_size_request = ctk_widget_has_size_request (widget);
8946
8947 *minimum_size = 0;
8948 *natural_size = 0;
8949
8950 border_width = ctk_container_get_border_width (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
);
8951
8952 if (priv->decorated &&
8953 !priv->fullscreen)
8954 {
8955 get_shadow_width (window, &window_border);
8956
8957 if (priv->title_box != NULL((void*)0) &&
8958 ctk_widget_get_visible (priv->title_box) &&
8959 ctk_widget_get_child_visible (priv->title_box))
8960 ctk_widget_get_preferred_height (priv->title_box,
8961 &title_min,
8962 &title_height);
8963
8964 *minimum_size = title_min +
8965 window_border.top + window_border.bottom;
8966
8967 *natural_size = title_height +
8968 window_border.top + window_border.bottom;
8969 }
8970
8971 if (child && ctk_widget_get_visible (child))
8972 {
8973 gint child_min, child_nat;
8974 ctk_widget_get_preferred_height (child, &child_min, &child_nat);
8975
8976 if (child_nat == 0 && !has_size_request)
8977 child_nat = NO_CONTENT_CHILD_NAT200;
8978 *minimum_size += child_min + 2 * border_width;
8979 *natural_size += child_nat + 2 * border_width;
8980 }
8981 else if (!has_size_request)
8982 {
8983 *natural_size += NO_CONTENT_CHILD_NAT200;
8984 }
8985}
8986
8987
8988static void
8989ctk_window_get_preferred_height_for_width (CtkWidget *widget,
8990 gint width,
8991 gint *minimum_size,
8992 gint *natural_size)
8993{
8994 CtkWindow *window;
8995 CtkWindowPrivate *priv;
8996 CtkWidget *child;
8997 guint border_width;
8998 int title_min = 0;
8999 int title_height = 0;
9000 CtkBorder window_border = { 0 };
9001 gboolean has_size_request;
9002
9003 window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
9004 priv = window->priv;
9005 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
9006 has_size_request = ctk_widget_has_size_request (widget);
9007
9008 *minimum_size = 0;
9009 *natural_size = 0;
9010
9011 border_width = ctk_container_get_border_width (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
);
9012
9013 width -= 2 * border_width;
9014
9015 if (priv->decorated &&
9016 !priv->fullscreen)
9017 {
9018 get_shadow_width (window, &window_border);
9019
9020 width -= window_border.left + window_border.right;
9021
9022 if (priv->title_box != NULL((void*)0) &&
9023 ctk_widget_get_visible (priv->title_box) &&
9024 ctk_widget_get_child_visible (priv->title_box))
9025 ctk_widget_get_preferred_height_for_width (priv->title_box,
9026 MAX (width, 0)(((width) > (0)) ? (width) : (0)),
9027 &title_min,
9028 &title_height);
9029
9030 *minimum_size = title_min +
9031 window_border.top + window_border.bottom;
9032
9033 *natural_size = title_height +
9034 window_border.top + window_border.bottom;
9035 }
9036
9037 if (child && ctk_widget_get_visible (child))
9038 {
9039 gint child_min, child_nat;
9040 ctk_widget_get_preferred_height_for_width (child, MAX (width, 0)(((width) > (0)) ? (width) : (0)),
9041 &child_min, &child_nat);
9042
9043 if (child_nat == 0 && width == 0 && !has_size_request)
9044 child_nat = NO_CONTENT_CHILD_NAT200;
9045 *minimum_size += child_min + 2 * border_width;
9046 *natural_size += child_nat + 2 * border_width;
9047 }
9048 else if (!has_size_request)
9049 {
9050 *natural_size += NO_CONTENT_CHILD_NAT200;
9051 }
9052}
9053
9054static void
9055ctk_window_state_flags_changed (CtkWidget *widget,
9056 CtkStateFlags previous_state)
9057{
9058 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
9059 CtkWindowPrivate *priv = window->priv;
9060 CtkStateFlags state;
9061
9062 state = ctk_widget_get_state_flags (widget);
9063 ctk_css_node_set_state (priv->decoration_node, state);
9064
9065 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->state_flags_changed (widget, previous_state);
9066}
9067
9068static void
9069ctk_window_style_updated (CtkWidget *widget)
9070{
9071 CtkCssStyleChange *change = ctk_style_context_get_change (ctk_widget_get_style_context (widget));
9072 CtkWindow *window = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
;
9073
9074 CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->style_updated (widget);
9075
9076 if (!_ctk_widget_get_alloc_needed (widget) &&
9077 (change == NULL((void*)0) || ctk_css_style_change_changes_property (change, CTK_CSS_PROPERTY_BACKGROUND_COLOR)))
9078 {
9079 CtkAllocation allocation;
9080 CtkBorder window_border;
9081
9082 _ctk_widget_get_allocation (widget, &allocation);
9083 get_shadow_width (window, &window_border);
9084
9085 update_opaque_region (window, &window_border, &allocation);
9086 }
9087
9088 if (change == NULL((void*)0) || ctk_css_style_change_changes_property (change, CTK_CSS_PROPERTY_ICON_THEME))
9089 update_themed_icon (window);
9090}
9091
9092/**
9093 * _ctk_window_unset_focus_and_default:
9094 * @window: a #CtkWindow
9095 * @widget: a widget inside of @window
9096 *
9097 * Checks whether the focus and default widgets of @window are
9098 * @widget or a descendent of @widget, and if so, unset them.
9099 *
9100 * If @widget is a #CtkPopover then nothing will be done with
9101 * respect to the default widget of @window, the reason being that
9102 * popovers already have specific logic for clearing/restablishing
9103 * the default widget of its enclosing window.
9104 **/
9105void
9106_ctk_window_unset_focus_and_default (CtkWindow *window,
9107 CtkWidget *widget)
9108
9109{
9110 CtkWindowPrivate *priv = window->priv;
9111 CtkWidget *child;
9112 CtkWidget *parent;
9113
9114 g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
9115 g_object_ref (widget)((__typeof__ (widget)) (g_object_ref) (widget));
9116
9117 parent = _ctk_widget_get_parent (widget);
9118 if (ctk_container_get_focus_child (CTK_CONTAINER (parent)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_container_get_type ()))))))
) == widget)
9119 {
9120 child = priv->focus_widget;
9121
9122 while (child && child != widget)
9123 child = _ctk_widget_get_parent (child);
9124
9125 if (child == widget)
9126 ctk_window_set_focus (CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
, NULL((void*)0));
9127 }
9128
9129 if (!CTK_IS_POPOVER (widget)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(widget)); GType __t = ((ctk_popover_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
9130 {
9131 child = priv->default_widget;
9132
9133 while (child && child != widget)
9134 child = _ctk_widget_get_parent (child);
9135
9136 if (child == widget)
9137 ctk_window_set_default (window, NULL((void*)0));
9138 }
9139
9140 g_object_unref (widget);
9141 g_object_unref (window);
9142}
9143
9144static void
9145popup_menu_detach (CtkWidget *widget,
9146 CtkMenu *menu G_GNUC_UNUSED__attribute__ ((__unused__)))
9147{
9148 CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
->priv->popup_menu = NULL((void*)0);
9149}
9150
9151static CdkWindowState
9152ctk_window_get_state (CtkWindow *window)
9153{
9154 CdkWindowState state;
9155 CdkWindow *cdk_window;
9156
9157 cdk_window = ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
9158
9159 state = 0;
9160
9161 if (cdk_window)
9162 state = cdk_window_get_state (cdk_window);
9163
9164 return state;
9165}
9166
9167static void
9168restore_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9169 gpointer user_data)
9170{
9171 CtkWindow *window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
9172 CtkWindowPrivate *priv = window->priv;
9173 CdkWindowState state;
9174
9175 if (priv->maximized)
9176 {
9177 ctk_window_unmaximize (window);
9178
9179 return;
9180 }
9181
9182 state = ctk_window_get_state (window);
9183
9184 if (state & CDK_WINDOW_STATE_ICONIFIED)
9185 ctk_window_deiconify (window);
9186}
9187
9188static void
9189move_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9190 gpointer user_data)
9191{
9192 CtkWindow *window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
9193
9194 ctk_window_begin_move_drag (window,
9195 0, /* 0 means "use keyboard" */
9196 0, 0,
9197 CDK_CURRENT_TIME0L);
9198}
9199
9200static void
9201resize_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9202 gpointer user_data)
9203{
9204 CtkWindow *window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
9205
9206 ctk_window_begin_resize_drag (window,
9207 0,
9208 0, /* 0 means "use keyboard" */
9209 0, 0,
9210 CDK_CURRENT_TIME0L);
9211}
9212
9213static void
9214minimize_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9215 gpointer user_data)
9216{
9217 CtkWindow *window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
9218 CtkWindowPrivate *priv = window->priv;
9219
9220 /* Turns out, we can't iconify a maximized window */
9221 if (priv->maximized)
9222 ctk_window_unmaximize (window);
9223
9224 ctk_window_iconify (window);
9225}
9226
9227static void
9228maximize_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9229 gpointer user_data)
9230{
9231 CtkWindow *window = CTK_WINDOW (user_data)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((ctk_window_get_type ()))))))
;
9232 CdkWindowState state;
9233
9234 state = ctk_window_get_state (window);
9235
9236 if (state & CDK_WINDOW_STATE_ICONIFIED)
9237 ctk_window_deiconify (window);
9238
9239 ctk_window_maximize (window);
9240}
9241
9242static void
9243ontop_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9244 gpointer user_data)
9245{
9246 CtkWindow *window = (CtkWindow *)user_data;
9247
9248 ctk_window_set_keep_above (window, !window->priv->above_initially);
9249}
9250
9251static void
9252close_window_clicked (CtkMenuItem *menuitem G_GNUC_UNUSED__attribute__ ((__unused__)),
9253 gpointer user_data)
9254{
9255 CtkWindow *window = (CtkWindow *)user_data;
9256
9257 if (window->priv->delete_event_handler == 0)
9258 send_delete_event (window);
9259}
9260
9261static void
9262ctk_window_do_popup_fallback (CtkWindow *window,
9263 CdkEventButton *event)
9264{
9265 CtkWindowPrivate *priv = window->priv;
9266 CtkWidget *menuitem;
9267 CdkWindowState state;
9268 gboolean maximized, iconified;
9269
9270 if (priv->popup_menu)
9271 ctk_widget_destroy (priv->popup_menu);
9272
9273 state = ctk_window_get_state (window);
9274
9275 iconified = (state & CDK_WINDOW_STATE_ICONIFIED) == CDK_WINDOW_STATE_ICONIFIED;
9276 maximized = priv->maximized && !iconified;
9277
9278 priv->popup_menu = ctk_menu_new ();
9279 ctk_style_context_add_class (ctk_widget_get_style_context (priv->popup_menu),
9280 CTK_STYLE_CLASS_CONTEXT_MENU"context-menu");
9281
9282 ctk_menu_attach_to_widget (CTK_MENU (priv->popup_menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_get_type ()))))))
,
9283 CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
,
9284 popup_menu_detach);
9285
9286 menuitem = ctk_menu_item_new_with_label (_("Restore")((char *) g_dgettext ("ctk30", "Restore")));
9287 ctk_widget_show (menuitem);
9288 /* "Restore" means "Unmaximize" or "Unminimize"
9289 * (yes, some WMs allow window menu to be shown for minimized windows).
9290 * Not restorable:
9291 * - visible windows that are not maximized or minimized
9292 * - non-resizable windows that are not minimized
9293 * - non-normal windows
9294 */
9295 if ((ctk_widget_is_visible (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
) &&
9296 !(maximized || iconified)) ||
9297 (!iconified && !priv->resizable) ||
9298 priv->type_hint != CDK_WINDOW_TYPE_HINT_NORMAL)
9299 ctk_widget_set_sensitive (menuitem, FALSE(0));
9300 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (restore_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
9301 G_CALLBACK (restore_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (restore_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
;
9302 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9303
9304 menuitem = ctk_menu_item_new_with_label (_("Move")((char *) g_dgettext ("ctk30", "Move")));
9305 ctk_widget_show (menuitem);
9306 if (maximized || iconified)
9307 ctk_widget_set_sensitive (menuitem, FALSE(0));
9308 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (move_window_clicked)))
, (window), ((void*)0), (GConnectFlags) 0)
9309 G_CALLBACK (move_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (move_window_clicked)))
, (window), ((void*)0), (GConnectFlags) 0)
;
9310 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9311
9312 menuitem = ctk_menu_item_new_with_label (_("Resize")((char *) g_dgettext ("ctk30", "Resize")));
9313 ctk_widget_show (menuitem);
9314 if (!priv->resizable || maximized || iconified)
9315 ctk_widget_set_sensitive (menuitem, FALSE(0));
9316 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (resize_window_clicked)
)), (window), ((void*)0), (GConnectFlags) 0)
9317 G_CALLBACK (resize_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (resize_window_clicked)
)), (window), ((void*)0), (GConnectFlags) 0)
;
9318 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9319
9320 menuitem = ctk_menu_item_new_with_label (_("Minimize")((char *) g_dgettext ("ctk30", "Minimize")));
9321 ctk_widget_show (menuitem);
9322 if (iconified ||
9323 priv->type_hint != CDK_WINDOW_TYPE_HINT_NORMAL)
9324 ctk_widget_set_sensitive (menuitem, FALSE(0));
9325 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (minimize_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
9326 G_CALLBACK (minimize_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (minimize_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
;
9327 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9328
9329 menuitem = ctk_menu_item_new_with_label (_("Maximize")((char *) g_dgettext ("ctk30", "Maximize")));
9330 ctk_widget_show (menuitem);
9331 if (maximized ||
9332 !priv->resizable ||
9333 priv->type_hint != CDK_WINDOW_TYPE_HINT_NORMAL)
9334 ctk_widget_set_sensitive (menuitem, FALSE(0));
9335 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (maximize_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
9336 G_CALLBACK (maximize_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (maximize_window_clicked
))), (window), ((void*)0), (GConnectFlags) 0)
;
9337 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9338
9339 menuitem = ctk_separator_menu_item_new ();
9340 ctk_widget_show (menuitem);
9341 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9342
9343 menuitem = ctk_check_menu_item_new_with_label (_("Always on Top")((char *) g_dgettext ("ctk30", "Always on Top")));
9344 ctk_check_menu_item_set_active (CTK_CHECK_MENU_ITEM (menuitem)((((CtkCheckMenuItem*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((menuitem)), ((ctk_check_menu_item_get_type (
)))))))
, priv->above_initially);
9345 if (maximized)
9346 ctk_widget_set_sensitive (menuitem, FALSE(0));
9347 ctk_widget_show (menuitem);
9348 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (ontop_window_clicked))
), (window), ((void*)0), (GConnectFlags) 0)
9349 G_CALLBACK (ontop_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (ontop_window_clicked))
), (window), ((void*)0), (GConnectFlags) 0)
;
9350 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9351
9352 menuitem = ctk_separator_menu_item_new ();
9353 ctk_widget_show (menuitem);
9354 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9355
9356 menuitem = ctk_menu_item_new_with_label (_("Close")((char *) g_dgettext ("ctk30", "Close")));
9357 ctk_widget_show (menuitem);
9358 if (!priv->deletable)
9359 ctk_widget_set_sensitive (menuitem, FALSE(0));
9360 g_signal_connect (G_OBJECT (menuitem), "activate",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (close_window_clicked))
), (window), ((void*)0), (GConnectFlags) 0)
9361 G_CALLBACK (close_window_clicked), window)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((menuitem)), (((GType) ((20) << (2)
)))))))), ("activate"), (((GCallback) (close_window_clicked))
), (window), ((void*)0), (GConnectFlags) 0)
;
9362 ctk_menu_shell_append (CTK_MENU_SHELL (priv->popup_menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_shell_get_type ())))))
)
, menuitem);
9363 ctk_menu_popup_at_pointer (CTK_MENU (priv->popup_menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->popup_menu)), ((ctk_menu_get_type ()))))))
, (CdkEvent *) event);
9364}
9365
9366static void
9367ctk_window_do_popup (CtkWindow *window,
9368 CdkEventButton *event)
9369{
9370 if (!cdk_window_show_window_menu (_ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
9371 (CdkEvent *) event))
9372 ctk_window_do_popup_fallback (window, event);
9373}
9374
9375/*********************************
9376 * Functions related to resizing *
9377 *********************************/
9378
9379static void
9380geometry_size_to_pixels (CdkGeometry *geometry,
9381 guint flags,
9382 gint *width,
9383 gint *height)
9384{
9385 gint base_width = 0;
9386 gint base_height = 0;
9387 gint min_width = 0;
9388 gint min_height = 0;
9389 gint width_inc = 1;
9390 gint height_inc = 1;
9391
9392 if (flags & CDK_HINT_BASE_SIZE)
9393 {
9394 base_width = geometry->base_width;
9395 base_height = geometry->base_height;
9396 }
9397 if (flags & CDK_HINT_MIN_SIZE)
9398 {
9399 min_width = geometry->min_width;
9400 min_height = geometry->min_height;
9401 }
9402 if (flags & CDK_HINT_RESIZE_INC)
9403 {
9404 width_inc = geometry->width_inc;
9405 height_inc = geometry->height_inc;
9406 }
9407
9408 if (width)
9409 *width = MAX (*width * width_inc + base_width, min_width)(((*width * width_inc + base_width) > (min_width)) ? (*width
* width_inc + base_width) : (min_width))
;
9410 if (height)
9411 *height = MAX (*height * height_inc + base_height, min_height)(((*height * height_inc + base_height) > (min_height)) ? (
*height * height_inc + base_height) : (min_height))
;
9412}
9413
9414/* This function doesn't constrain to geometry hints */
9415static void
9416ctk_window_compute_configure_request_size (CtkWindow *window,
9417 CdkGeometry *geometry,
9418 guint flags,
9419 gint *width,
9420 gint *height)
9421{
9422 CtkWindowPrivate *priv = window->priv;
9423 CtkWindowGeometryInfo *info;
9424 int w, h;
9425
9426 /* Preconditions:
9427 * - we've done a size request
9428 */
9429
9430 info = ctk_window_get_geometry_info (window, FALSE(0));
9431
9432 if ((priv->need_default_size || priv->force_resize) &&
9433 !priv->maximized &&
9434 !priv->fullscreen)
9435 {
9436 ctk_window_guess_default_size (window, width, height);
9437 ctk_window_get_remembered_size (window, &w, &h);
9438 *width = MAX (*width, w)(((*width) > (w)) ? (*width) : (w));
9439 *height = MAX (*height, h)(((*height) > (h)) ? (*height) : (h));
9440
9441 /* Override with default size */
9442 if (info)
9443 {
9444 /* Take width of shadows/headerbar into account. We want to set the
9445 * default size of the content area and not the window area.
9446 */
9447 gint default_width_csd = info->default_width;
9448 gint default_height_csd = info->default_height;
9449 ctk_window_update_csd_size (window,
9450 &default_width_csd, &default_height_csd,
9451 INCLUDE_CSD_SIZE);
9452
9453 if (info->default_width > 0)
9454 *width = default_width_csd;
9455 if (info->default_height > 0)
9456 *height = default_height_csd;
9457
9458 if (info->default_is_geometry)
9459 geometry_size_to_pixels (geometry, flags,
9460 info->default_width > 0 ? width : NULL((void*)0),
9461 info->default_height > 0 ? height : NULL((void*)0));
9462 }
9463 }
9464 else
9465 {
9466 /* Default to keeping current size */
9467 ctk_window_get_remembered_size (window, width, height);
9468 }
9469
9470 if (info)
9471 {
9472 gint resize_width_csd = info->resize_width;
9473 gint resize_height_csd = info->resize_height;
9474 ctk_window_update_csd_size (window,
9475 &resize_width_csd, &resize_height_csd,
9476 INCLUDE_CSD_SIZE);
9477
9478 if (info->resize_width > 0)
9479 *width = resize_width_csd;
9480 if (info->resize_height > 0)
9481 *height = resize_height_csd;
9482 }
9483
9484 /* Don't ever request zero width or height, it's not supported by
9485 cdk. The size allocation code will round it to 1 anyway but if
9486 we do it then the value returned from this function will is
9487 not comparable to the size allocation read from the CtkWindow. */
9488 *width = MAX (*width, 1)(((*width) > (1)) ? (*width) : (1));
9489 *height = MAX (*height, 1)(((*height) > (1)) ? (*height) : (1));
9490}
9491
9492static CtkWindowPosition
9493get_effective_position (CtkWindow *window)
9494{
9495 CtkWindowPrivate *priv = window->priv;
9496 CtkWindowPosition pos = priv->position;
9497
9498 if (pos == CTK_WIN_POS_CENTER_ON_PARENT &&
9499 (priv->transient_parent == NULL((void*)0) ||
9500 !_ctk_widget_get_mapped (CTK_WIDGET (priv->transient_parent)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->transient_parent)), ((ctk_widget_get_type ())))
)))
)))
9501 pos = CTK_WIN_POS_NONE;
9502
9503 return pos;
9504}
9505
9506static CdkMonitor *
9507get_center_monitor_of_window (CtkWindow *window)
9508{
9509 CdkDisplay *display;
9510
9511 /* We could try to sort out the relative positions of the monitors and
9512 * stuff, or we could just be losers and assume you have a row
9513 * or column of monitors.
9514 */
9515 display = cdk_screen_get_display (ctk_window_check_screen (window));
9516 return cdk_display_get_monitor (display, cdk_display_get_n_monitors (display) / 2);
9517}
9518
9519static CdkMonitor *
9520get_monitor_containing_pointer (CtkWindow *window)
9521{
9522 gint px, py;
9523 CdkDisplay *display;
9524 CdkDevice *pointer;
9525
9526 display = cdk_screen_get_display (ctk_window_check_screen (window));
9527 pointer = cdk_seat_get_pointer (cdk_display_get_default_seat (display));
9528 cdk_device_get_position (pointer, NULL((void*)0), &px, &py);
9529
9530 return cdk_display_get_monitor_at_point (display, px, py);
9531}
9532
9533static void
9534center_window_on_monitor (CtkWindow *window,
9535 gint w,
9536 gint h,
9537 gint *x,
9538 gint *y)
9539{
9540 CdkRectangle area;
9541 CdkMonitor *monitor;
9542
9543 monitor = get_monitor_containing_pointer (window);
9544
9545 if (monitor == NULL((void*)0))
9546 monitor = get_center_monitor_of_window (window);
9547
9548 cdk_monitor_get_workarea (monitor, &area);
9549
9550 *x = (area.width - w) / 2 + area.x;
9551 *y = (area.height - h) / 2 + area.y;
9552
9553 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
9554 * and WM decorations.
9555 */
9556 if (*x < area.x)
9557 *x = area.x;
9558 if (*y < area.y)
9559 *y = area.y;
9560}
9561
9562static void
9563clamp (gint *base,
9564 gint extent,
9565 gint clamp_base,
9566 gint clamp_extent)
9567{
9568 if (extent > clamp_extent)
9569 /* Center */
9570 *base = clamp_base + clamp_extent/2 - extent/2;
9571 else if (*base < clamp_base)
9572 *base = clamp_base;
9573 else if (*base + extent > clamp_base + clamp_extent)
9574 *base = clamp_base + clamp_extent - extent;
9575}
9576
9577static void
9578clamp_window_to_rectangle (gint *x,
9579 gint *y,
9580 gint w,
9581 gint h,
9582 const CdkRectangle *rect)
9583{
9584 /* If it is too large, center it. If it fits on the monitor but is
9585 * partially outside, move it to the closest edge. Do this
9586 * separately in x and y directions.
9587 */
9588 clamp (x, w, rect->x, rect->width);
9589 clamp (y, h, rect->y, rect->height);
9590}
9591
9592
9593static void
9594ctk_window_compute_configure_request (CtkWindow *window,
9595 CdkRectangle *request,
9596 CdkGeometry *geometry,
9597 guint *flags)
9598{
9599 CtkWindowPrivate *priv = window->priv;
9600 CdkGeometry new_geometry;
9601 guint new_flags;
9602 int w, h;
9603 CtkWindowPosition pos;
9604 CtkWidget *parent_widget;
9605 CtkWindowGeometryInfo *info;
9606 CdkScreen *screen;
9607 int x, y;
9608
9609 screen = ctk_window_check_screen (window);
9610
9611 ctk_window_compute_hints (window, &new_geometry, &new_flags);
9612 ctk_window_compute_configure_request_size (window,
9613 &new_geometry, new_flags,
9614 &w, &h);
9615 ctk_window_update_fixed_size (window, &new_geometry, w, h);
9616 ctk_window_constrain_size (window,
9617 &new_geometry, new_flags,
9618 w, h,
9619 &w, &h);
9620
9621 parent_widget = (CtkWidget*) priv->transient_parent;
9622
9623 pos = get_effective_position (window);
9624 info = ctk_window_get_geometry_info (window, FALSE(0));
9625
9626 /* by default, don't change position requested */
9627 if (info)
9628 {
9629 x = info->last.configure_request.x;
9630 y = info->last.configure_request.y;
9631 }
9632 else
9633 {
9634 x = 0;
9635 y = 0;
9636 }
9637
9638
9639 if (priv->need_default_position)
9640 {
9641
9642 /* FIXME this all interrelates with window gravity.
9643 * For most of them I think we want to set GRAVITY_CENTER.
9644 *
9645 * Not sure how to go about that.
9646 */
9647 switch (pos)
9648 {
9649 /* here we are only handling CENTER_ALWAYS
9650 * as it relates to default positioning,
9651 * where it's equivalent to simply CENTER
9652 */
9653 case CTK_WIN_POS_CENTER_ALWAYS:
9654 case CTK_WIN_POS_CENTER:
9655 center_window_on_monitor (window, w, h, &x, &y);
9656 break;
9657
9658 case CTK_WIN_POS_CENTER_ON_PARENT:
9659 {
9660 CdkDisplay *display;
9661 CtkAllocation allocation;
9662 CdkWindow *cdk_window;
9663 CdkMonitor *monitor;
9664 CdkRectangle area;
9665 gint ox, oy;
9666
9667 g_assert (_ctk_widget_get_mapped (parent_widget))do { if (_ctk_widget_get_mapped (parent_widget)) ; else g_assertion_message_expr
("Ctk", "ctkwindow.c", 9667, ((const char*) (__func__)), "_ctk_widget_get_mapped (parent_widget)"
); } while (0)
; /* established earlier */
9668
9669 display = cdk_screen_get_display (screen);
9670 cdk_window = _ctk_widget_get_window (parent_widget);
9671 monitor = cdk_display_get_monitor_at_window (display, cdk_window);
9672
9673 cdk_window_get_origin (cdk_window, &ox, &oy);
9674
9675 _ctk_widget_get_allocation (parent_widget, &allocation);
9676 x = ox + (allocation.width - w) / 2;
9677 y = oy + (allocation.height - h) / 2;
9678
9679 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
9680 * WM decorations. If parent wasn't on a monitor, just
9681 * give up.
9682 */
9683 if (monitor != NULL((void*)0))
9684 {
9685 cdk_monitor_get_geometry (monitor, &area);
9686 clamp_window_to_rectangle (&x, &y, w, h, &area);
9687 }
9688 }
9689 break;
9690
9691 case CTK_WIN_POS_MOUSE:
9692 {
9693 CdkRectangle area;
9694 CdkDisplay *display;
9695 CdkDevice *pointer;
9696 CdkMonitor *monitor;
9697 gint px, py;
9698
9699 display = cdk_screen_get_display (screen);
9700 pointer = cdk_seat_get_pointer (cdk_display_get_default_seat (display));
9701
9702 cdk_device_get_position (pointer, NULL((void*)0), &px, &py);
9703 monitor = cdk_display_get_monitor_at_point (display, px, py);
9704
9705 x = px - w / 2;
9706 y = py - h / 2;
9707
9708 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
9709 * WM decorations.
9710 */
9711 cdk_monitor_get_geometry (monitor, &area);
9712 clamp_window_to_rectangle (&x, &y, w, h, &area);
9713 }
9714 break;
9715
9716 default:
9717 break;
9718 }
9719 } /* if (priv->need_default_position) */
9720
9721 if (priv->need_default_position && info &&
9722 info->initial_pos_set)
9723 {
9724 x = info->initial_x;
9725 y = info->initial_y;
9726 ctk_window_constrain_position (window, w, h, &x, &y);
9727 }
9728
9729 request->x = x;
9730 request->y = y;
9731 request->width = w;
9732 request->height = h;
9733
9734 if (geometry)
9735 *geometry = new_geometry;
9736 if (flags)
9737 *flags = new_flags;
9738}
9739
9740static void
9741ctk_window_constrain_position (CtkWindow *window,
9742 gint new_width,
9743 gint new_height,
9744 gint *x,
9745 gint *y)
9746{
9747 CtkWindowPrivate *priv = window->priv;
9748
9749 /* See long comments in ctk_window_move_resize()
9750 * on when it's safe to call this function.
9751 */
9752 if (priv->position == CTK_WIN_POS_CENTER_ALWAYS)
9753 {
9754 gint center_x, center_y;
9755
9756 center_window_on_monitor (window, new_width, new_height, &center_x, &center_y);
9757
9758 *x = center_x;
9759 *y = center_y;
9760 }
9761}
9762
9763void
9764ctk_window_move_resize (CtkWindow *window)
9765{
9766 /* Overview:
9767 *
9768 * First we determine whether any information has changed that would
9769 * cause us to revise our last configure request. If we would send
9770 * a different configure request from last time, then
9771 * configure_request_size_changed = TRUE or
9772 * configure_request_pos_changed = TRUE. configure_request_size_changed
9773 * may be true due to new hints, a ctk_window_resize(), or whatever.
9774 * configure_request_pos_changed may be true due to ctk_window_set_position()
9775 * or ctk_window_move().
9776 *
9777 * If the configure request has changed, we send off a new one. To
9778 * ensure CTK+ invariants are maintained (resize queue does what it
9779 * should), we go ahead and size_allocate the requested size in this
9780 * function.
9781 *
9782 * If the configure request has not changed, we don't ever resend
9783 * it, because it could mean fighting the user or window manager.
9784 *
9785 * To prepare the configure request, we come up with a base size/pos:
9786 * - the one from ctk_window_move()/ctk_window_resize()
9787 * - else default_width, default_height if we haven't ever
9788 * been mapped
9789 * - else the size request if we haven't ever been mapped,
9790 * as a substitute default size
9791 * - else the current size of the window, as received from
9792 * configure notifies (i.e. the current allocation)
9793 *
9794 * If CTK_WIN_POS_CENTER_ALWAYS is active, we constrain
9795 * the position request to be centered.
9796 */
9797 CtkWindowPrivate *priv = window->priv;
9798 CtkWidget *widget;
9799 CtkContainer *container;
9800 CtkWindowGeometryInfo *info;
9801 CdkGeometry new_geometry;
9802 CdkWindow *cdk_window;
9803 guint new_flags;
9804 CdkRectangle new_request;
9805 gboolean configure_request_size_changed;
9806 gboolean configure_request_pos_changed;
9807 gboolean hints_changed; /* do we need to send these again */
9808 CtkWindowLastGeometryInfo saved_last_info;
9809 int current_width, current_height;
9810
9811 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
9812
9813 cdk_window = _ctk_widget_get_window (widget);
9814 container = CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_container_get_type ()))))))
;
9815 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
9816
9817 configure_request_size_changed = FALSE(0);
9818 configure_request_pos_changed = FALSE(0);
9819
9820 ctk_window_compute_configure_request (window, &new_request,
9821 &new_geometry, &new_flags);
9822
9823 /* This check implies the invariant that we never set info->last
9824 * without setting the hints and sending off a configure request.
9825 *
9826 * If we change info->last without sending the request, we may
9827 * miss a request.
9828 */
9829 if (info->last.configure_request.x != new_request.x ||
9830 info->last.configure_request.y != new_request.y)
9831 configure_request_pos_changed = TRUE(!(0));
9832
9833 if (priv->force_resize ||
9834 (info->last.configure_request.width != new_request.width ||
9835 info->last.configure_request.height != new_request.height))
9836 {
9837 priv->force_resize = FALSE(0);
9838 configure_request_size_changed = TRUE(!(0));
9839 }
9840
9841 hints_changed = FALSE(0);
9842
9843 if (!ctk_window_compare_hints (&info->last.geometry, info->last.flags,
9844 &new_geometry, new_flags))
9845 {
9846 hints_changed = TRUE(!(0));
9847 }
9848
9849 /* Position Constraints
9850 * ====================
9851 *
9852 * POS_CENTER_ALWAYS is conceptually a constraint rather than
9853 * a default. The other POS_ values are used only when the
9854 * window is shown, not after that.
9855 *
9856 * However, we can't implement a position constraint as
9857 * "anytime the window size changes, center the window"
9858 * because this may well end up fighting the WM or user. In
9859 * fact it gets in an infinite loop with at least one WM.
9860 *
9861 * Basically, applications are in no way in a position to
9862 * constrain the position of a window, with one exception:
9863 * override redirect windows. (Really the intended purpose
9864 * of CENTER_ALWAYS anyhow, I would think.)
9865 *
9866 * So the way we implement this "constraint" is to say that when WE
9867 * cause a move or resize, i.e. we make a configure request changing
9868 * window size, we recompute the CENTER_ALWAYS position to reflect
9869 * the new window size, and include it in our request. Also, if we
9870 * just turned on CENTER_ALWAYS we snap to center with a new
9871 * request. Otherwise, if we are just NOTIFIED of a move or resize
9872 * done by someone else e.g. the window manager, we do NOT send a
9873 * new configure request.
9874 *
9875 * For override redirect windows, this works fine; all window
9876 * sizes are from our configure requests. For managed windows,
9877 * it is at least semi-sane, though who knows what the
9878 * app author is thinking.
9879 */
9880
9881 /* This condition should be kept in sync with the condition later on
9882 * that determines whether we send a configure request. i.e. we
9883 * should do this position constraining anytime we were going to
9884 * send a configure request anyhow, plus when constraints have
9885 * changed.
9886 */
9887 if (configure_request_pos_changed ||
9888 configure_request_size_changed ||
9889 hints_changed ||
9890 info->position_constraints_changed)
9891 {
9892 /* We request the constrained position if:
9893 * - we were changing position, and need to clamp
9894 * the change to the constraint
9895 * - we're changing the size anyway
9896 * - set_position() was called to toggle CENTER_ALWAYS on
9897 */
9898
9899 ctk_window_constrain_position (window,
9900 new_request.width,
9901 new_request.height,
9902 &new_request.x,
9903 &new_request.y);
9904
9905 /* Update whether we need to request a move */
9906 if (info->last.configure_request.x != new_request.x ||
9907 info->last.configure_request.y != new_request.y)
9908 configure_request_pos_changed = TRUE(!(0));
9909 else
9910 configure_request_pos_changed = FALSE(0);
9911 }
9912
9913#if 0
9914 if (priv->type == CTK_WINDOW_TOPLEVEL)
9915 {
9916 CtkAllocation alloc;
9917
9918 ctk_widget_get_allocation (widget, &alloc);
9919
9920 g_message ("--- %s ---\n"
9921 "last : %d,%d\t%d x %d\n"
9922 "this : %d,%d\t%d x %d\n"
9923 "alloc : %d,%d\t%d x %d\n"
9924 "resize: \t%d x %d\n"
9925 "size_changed: %d pos_changed: %d hints_changed: %d\n"
9926 "configure_notify_received: %d\n"
9927 "configure_request_count: %d\n"
9928 "position_constraints_changed: %d",
9929 priv->title ? priv->title : "(no title)",
9930 info->last.configure_request.x,
9931 info->last.configure_request.y,
9932 info->last.configure_request.width,
9933 info->last.configure_request.height,
9934 new_request.x,
9935 new_request.y,
9936 new_request.width,
9937 new_request.height,
9938 alloc.x,
9939 alloc.y,
9940 alloc.width,
9941 alloc.height,
9942 info->resize_width,
9943 info->resize_height,
9944 configure_request_size_changed,
9945 configure_request_pos_changed,
9946 hints_changed,
9947 priv->configure_notify_received,
9948 priv->configure_request_count,
9949 info->position_constraints_changed);
9950 }
9951#endif
9952
9953 saved_last_info = info->last;
9954 info->last.geometry = new_geometry;
9955 info->last.flags = new_flags;
9956 info->last.configure_request = new_request;
9957
9958 /* need to set PPosition so the WM will look at our position,
9959 * but we don't want to count PPosition coming and going as a hints
9960 * change for future iterations. So we saved info->last prior to
9961 * this.
9962 */
9963
9964 /* Also, if the initial position was explicitly set, then we always
9965 * toggle on PPosition. This makes ctk_window_move(window, 0, 0)
9966 * work.
9967 */
9968
9969 /* Also, we toggle on PPosition if CTK_WIN_POS_ is in use and
9970 * this is an initial map
9971 */
9972
9973 if ((configure_request_pos_changed ||
9974 info->initial_pos_set ||
9975 (priv->need_default_position &&
9976 get_effective_position (window) != CTK_WIN_POS_NONE)) &&
9977 (new_flags & CDK_HINT_POS) == 0)
9978 {
9979 new_flags |= CDK_HINT_POS;
9980 hints_changed = TRUE(!(0));
9981 }
9982
9983 /* Set hints if necessary
9984 */
9985 if (hints_changed)
9986 cdk_window_set_geometry_hints (cdk_window,
9987 &new_geometry,
9988 new_flags);
9989
9990 current_width = cdk_window_get_width (cdk_window);
9991 current_height = cdk_window_get_height (cdk_window);
9992
9993 /* handle resizing/moving and widget tree allocation
9994 */
9995 if (priv->configure_notify_received)
9996 {
9997 CtkAllocation allocation;
9998
9999 /* If we have received a configure event since
10000 * the last time in this function, we need to
10001 * accept our new size and size_allocate child widgets.
10002 * (see ctk_window_configure_event() for more details).
10003 *
10004 * 1 or more configure notifies may have been received.
10005 * Also, configure_notify_received will only be TRUE
10006 * if all expected configure notifies have been received
10007 * (one per configure request), as an optimization.
10008 *
10009 */
10010 priv->configure_notify_received = FALSE(0);
10011
10012 allocation.x = 0;
10013 allocation.y = 0;
10014 allocation.width = current_width;
10015 allocation.height = current_height;
10016
10017 ctk_widget_size_allocate (widget, &allocation);
10018
10019 /* If the configure request changed, it means that
10020 * we either:
10021 * 1) coincidentally changed hints or widget properties
10022 * impacting the configure request before getting
10023 * a configure notify, or
10024 * 2) some broken widget is changing its size request
10025 * during size allocation, resulting in
10026 * a false appearance of changed configure request.
10027 *
10028 * For 1), we could just go ahead and ask for the
10029 * new size right now, but doing that for 2)
10030 * might well be fighting the user (and can even
10031 * trigger a loop). Since we really don't want to
10032 * do that, we requeue a resize in hopes that
10033 * by the time it gets handled, the child has seen
10034 * the light and is willing to go along with the
10035 * new size. (this happens for the zvt widget, since
10036 * the size_allocate() above will have stored the
10037 * requisition corresponding to the new size in the
10038 * zvt widget)
10039 *
10040 * This doesn't buy us anything for 1), but it shouldn't
10041 * hurt us too badly, since it is what would have
10042 * happened if we had gotten the configure event before
10043 * the new size had been set.
10044 */
10045
10046 if (configure_request_size_changed ||
10047 configure_request_pos_changed)
10048 {
10049 /* Don't change the recorded last info after all, because we
10050 * haven't actually updated to the new info yet - we decided
10051 * to postpone our configure request until later.
10052 */
10053 info->last = saved_last_info;
10054 ctk_widget_queue_resize_no_redraw (widget); /* might recurse for CTK_RESIZE_IMMEDIATE */
10055 }
10056
10057 return; /* Bail out, we didn't really process the move/resize */
10058 }
10059 else if ((configure_request_size_changed || hints_changed) &&
10060 (current_width != new_request.width || current_height != new_request.height))
10061 {
10062 /* We are in one of the following situations:
10063 * A. configure_request_size_changed
10064 * our requisition has changed and we need a different window size,
10065 * so we request it from the window manager.
10066 * B. !configure_request_size_changed && hints_changed
10067 * the window manager rejects our size, but we have just changed the
10068 * window manager hints, so there's a chance our request will
10069 * be honoured this time, so we try again.
10070 *
10071 * However, if the new requisition is the same as the current allocation,
10072 * we don't request it again, since we won't get a ConfigureNotify back from
10073 * the window manager unless it decides to change our requisition. If
10074 * we don't get the ConfigureNotify back, the resize queue will never be run.
10075 */
10076
10077 /* Now send the configure request */
10078 if (configure_request_pos_changed)
10079 {
10080 cdk_window_move_resize (cdk_window,
10081 new_request.x, new_request.y,
10082 new_request.width, new_request.height);
10083 }
10084 else /* only size changed */
10085 {
10086 cdk_window_resize (cdk_window,
10087 new_request.width, new_request.height);
10088 }
10089
10090 if (priv->type == CTK_WINDOW_POPUP)
10091 {
10092 CtkAllocation allocation;
10093
10094 /* Directly size allocate for override redirect (popup) windows. */
10095 allocation.x = 0;
10096 allocation.y = 0;
10097 allocation.width = new_request.width;
10098 allocation.height = new_request.height;
10099
10100 ctk_widget_size_allocate (widget, &allocation);
10101
10102 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
10103 if (ctk_container_get_resize_mode (container) == CTK_RESIZE_QUEUE)
10104 ctk_widget_queue_draw (widget);
10105 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
10106 }
10107 else
10108 {
10109 /* Increment the number of have-not-yet-received-notify requests */
10110 priv->configure_request_count += 1;
10111
10112 CDK_PRIVATE_CALL (cdk_window_freeze_toplevel_updates)(cdk__private__ ()->cdk_window_freeze_toplevel_updates) (cdk_window);
10113
10114 /* for CTK_RESIZE_QUEUE toplevels, we are now awaiting a new
10115 * configure event in response to our resizing request.
10116 * the configure event will cause a new resize with
10117 * ->configure_notify_received=TRUE.
10118 * until then, we want to
10119 * - discard expose events
10120 * - coalesce resizes for our children
10121 * - defer any window resizes until the configure event arrived
10122 * to achieve this, we queue a resize for the window, but remove its
10123 * resizing handler, so resizing will not be handled from the next
10124 * idle handler but when the configure event arrives.
10125 *
10126 * FIXME: we should also dequeue the pending redraws here, since
10127 * we handle those ourselves upon ->configure_notify_received==TRUE.
10128 */
10129 }
10130 }
10131 else
10132 {
10133 CtkAllocation allocation;
10134
10135 /* Handle any position changes.
10136 */
10137 if (configure_request_pos_changed)
10138 {
10139 cdk_window_move (cdk_window,
10140 new_request.x, new_request.y);
10141 }
10142
10143 /* Our configure request didn't change size, but maybe some of
10144 * our child widgets have. Run a size allocate with our current
10145 * size to make sure that we re-layout our child widgets. */
10146 allocation.x = 0;
10147 allocation.y = 0;
10148 allocation.width = current_width;
10149 allocation.height = current_height;
10150
10151 ctk_widget_size_allocate (widget, &allocation);
10152 }
10153
10154 /* We have now processed a move/resize since the last position
10155 * constraint change, setting of the initial position, or resize.
10156 * (Not resetting these flags here can lead to infinite loops for
10157 * CTK_RESIZE_IMMEDIATE containers)
10158 */
10159 info->position_constraints_changed = FALSE(0);
10160 info->initial_pos_set = FALSE(0);
10161 info->resize_width = -1;
10162 info->resize_height = -1;
10163}
10164
10165/* Compare two sets of Geometry hints for equality.
10166 */
10167static gboolean
10168ctk_window_compare_hints (CdkGeometry *geometry_a,
10169 guint flags_a,
10170 CdkGeometry *geometry_b,
10171 guint flags_b)
10172{
10173 if (flags_a != flags_b)
10174 return FALSE(0);
10175
10176 if ((flags_a & CDK_HINT_MIN_SIZE) &&
10177 (geometry_a->min_width != geometry_b->min_width ||
10178 geometry_a->min_height != geometry_b->min_height))
10179 return FALSE(0);
10180
10181 if ((flags_a & CDK_HINT_MAX_SIZE) &&
10182 (geometry_a->max_width != geometry_b->max_width ||
10183 geometry_a->max_height != geometry_b->max_height))
10184 return FALSE(0);
10185
10186 if ((flags_a & CDK_HINT_BASE_SIZE) &&
10187 (geometry_a->base_width != geometry_b->base_width ||
10188 geometry_a->base_height != geometry_b->base_height))
10189 return FALSE(0);
10190
10191 if ((flags_a & CDK_HINT_ASPECT) &&
10192 (geometry_a->min_aspect != geometry_b->min_aspect ||
10193 geometry_a->max_aspect != geometry_b->max_aspect))
10194 return FALSE(0);
10195
10196 if ((flags_a & CDK_HINT_RESIZE_INC) &&
10197 (geometry_a->width_inc != geometry_b->width_inc ||
10198 geometry_a->height_inc != geometry_b->height_inc))
10199 return FALSE(0);
10200
10201 if ((flags_a & CDK_HINT_WIN_GRAVITY) &&
10202 geometry_a->win_gravity != geometry_b->win_gravity)
10203 return FALSE(0);
10204
10205 return TRUE(!(0));
10206}
10207
10208static void
10209ctk_window_constrain_size (CtkWindow *window,
10210 CdkGeometry *geometry,
10211 guint flags,
10212 gint width,
10213 gint height,
10214 gint *new_width,
10215 gint *new_height)
10216{
10217 CtkWindowPrivate *priv = window->priv;
10218 guint geometry_flags;
10219
10220 /* ignore size increments for windows that fit in a fixed space */
10221 if (priv->maximized || priv->fullscreen || priv->tiled)
10222 geometry_flags = flags & ~CDK_HINT_RESIZE_INC;
10223 else
10224 geometry_flags = flags;
10225
10226 cdk_window_constrain_size (geometry, geometry_flags, width, height,
10227 new_width, new_height);
10228}
10229
10230/* For non-resizable windows, make sure the given width/height fits
10231 * in the geometry contrains and update the geometry hints to match
10232 * the given width/height if not.
10233 * This is to make sure that non-resizable windows get the default
10234 * width/height if set, but can still grow if their content requires.
10235 *
10236 * Note: Fixed size windows with a default size set will not shrink
10237 * smaller than the default size when their content requires less size.
10238 */
10239static void
10240ctk_window_update_fixed_size (CtkWindow *window,
10241 CdkGeometry *new_geometry,
10242 gint new_width,
10243 gint new_height)
10244{
10245 CtkWindowPrivate *priv = window->priv;
10246 CtkWindowGeometryInfo *info;
10247 gboolean has_size_request;
10248
10249 /* Adjust the geometry hints for non-resizable windows only */
10250 has_size_request = ctk_widget_has_size_request (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10251 if (priv->resizable || has_size_request)
10252 return;
10253
10254 info = ctk_window_get_geometry_info (window, FALSE(0));
10255 if (info)
10256 {
10257 gint default_width_csd = info->default_width;
10258 gint default_height_csd = info->default_height;
10259
10260 ctk_window_update_csd_size (window,
10261 &default_width_csd, &default_height_csd,
10262 INCLUDE_CSD_SIZE);
10263
10264 if (info->default_width > -1)
10265 {
10266 gint w = MAX (MAX (default_width_csd, new_width), new_geometry->min_width)((((((default_width_csd) > (new_width)) ? (default_width_csd
) : (new_width))) > (new_geometry->min_width)) ? ((((default_width_csd
) > (new_width)) ? (default_width_csd) : (new_width))) : (
new_geometry->min_width))
;
10267 new_geometry->min_width = w;
10268 new_geometry->max_width = w;
10269 }
10270
10271 if (info->default_height > -1)
10272 {
10273 gint h = MAX (MAX (default_height_csd, new_height), new_geometry->min_height)((((((default_height_csd) > (new_height)) ? (default_height_csd
) : (new_height))) > (new_geometry->min_height)) ? ((((
default_height_csd) > (new_height)) ? (default_height_csd)
: (new_height))) : (new_geometry->min_height))
;
10274 new_geometry->min_height = h;
10275 new_geometry->max_height = h;
10276 }
10277 }
10278}
10279
10280/* Compute the set of geometry hints and flags for a window
10281 * based on the application set geometry, and requisition
10282 * of the window. ctk_widget_get_preferred_size() must have been
10283 * called first.
10284 */
10285static void
10286ctk_window_compute_hints (CtkWindow *window,
10287 CdkGeometry *new_geometry,
10288 guint *new_flags)
10289{
10290 CtkWindowPrivate *priv = window->priv;
10291 CtkWidget *widget;
10292 gint extra_width = 0;
10293 gint extra_height = 0;
10294 CtkWindowGeometryInfo *geometry_info;
10295 CtkRequisition requisition;
10296
10297 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
10298
10299 ctk_widget_get_preferred_size (widget, &requisition, NULL((void*)0));
10300 geometry_info = ctk_window_get_geometry_info (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
, FALSE(0));
10301
10302 if (geometry_info)
10303 {
10304 *new_flags = geometry_info->mask;
10305 *new_geometry = geometry_info->geometry;
10306 }
10307 else
10308 {
10309 *new_flags = 0;
10310 }
10311
10312 /* We don't want to set CDK_HINT_POS in here, we just set it
10313 * in ctk_window_move_resize() when we want the position
10314 * honored.
10315 */
10316
10317 if (*new_flags & CDK_HINT_BASE_SIZE)
10318 {
10319 new_geometry->base_width += extra_width;
10320 new_geometry->base_height += extra_height;
10321 }
10322 else
10323 {
10324 /* For simplicity, we always set the base hint, even when we
10325 * don't expect it to have any visible effect.
10326 * (Note: geometry_size_to_pixels() depends on this.)
10327 */
10328 *new_flags |= CDK_HINT_BASE_SIZE;
10329
10330 new_geometry->base_width = extra_width;
10331 new_geometry->base_height = extra_height;
10332
10333 /* As for X, if BASE_SIZE is not set but MIN_SIZE is set, then the
10334 * base size is the minimum size */
10335 if (*new_flags & CDK_HINT_MIN_SIZE)
10336 {
10337 if (new_geometry->min_width > 0)
10338 new_geometry->base_width += new_geometry->min_width;
10339 if (new_geometry->min_height > 0)
10340 new_geometry->base_height += new_geometry->min_height;
10341 }
10342 }
10343
10344 /* Please use a good size for unresizable widgets, not the minimum one. */
10345 if (!priv->resizable)
10346 ctk_window_guess_default_size (window, &requisition.width, &requisition.height);
10347
10348 if (*new_flags & CDK_HINT_MIN_SIZE)
10349 {
10350 if (new_geometry->min_width < 0)
10351 new_geometry->min_width = requisition.width;
10352 else
10353 new_geometry->min_width = MAX (requisition.width, new_geometry->min_width + extra_width)(((requisition.width) > (new_geometry->min_width + extra_width
)) ? (requisition.width) : (new_geometry->min_width + extra_width
))
;
10354
10355 if (new_geometry->min_height < 0)
10356 new_geometry->min_height = requisition.height;
10357 else
10358 new_geometry->min_height = MAX (requisition.height, new_geometry->min_height + extra_height)(((requisition.height) > (new_geometry->min_height + extra_height
)) ? (requisition.height) : (new_geometry->min_height + extra_height
))
;
10359 }
10360 else
10361 {
10362 *new_flags |= CDK_HINT_MIN_SIZE;
10363
10364 new_geometry->min_width = requisition.width;
10365 new_geometry->min_height = requisition.height;
10366 }
10367
10368 if (*new_flags & CDK_HINT_MAX_SIZE)
10369 {
10370 if (new_geometry->max_width >= 0)
10371 new_geometry->max_width += extra_width;
10372 new_geometry->max_width = MAX (new_geometry->max_width, new_geometry->min_width)(((new_geometry->max_width) > (new_geometry->min_width
)) ? (new_geometry->max_width) : (new_geometry->min_width
))
;
10373
10374 if (new_geometry->max_height >= 0)
10375 new_geometry->max_height += extra_height;
10376
10377 new_geometry->max_height = MAX (new_geometry->max_height, new_geometry->min_height)(((new_geometry->max_height) > (new_geometry->min_height
)) ? (new_geometry->max_height) : (new_geometry->min_height
))
;
10378 }
10379 else if (!priv->resizable)
10380 {
10381 *new_flags |= CDK_HINT_MAX_SIZE;
10382
10383 new_geometry->max_width = new_geometry->min_width;
10384 new_geometry->max_height = new_geometry->min_height;
10385 }
10386
10387 *new_flags |= CDK_HINT_WIN_GRAVITY;
10388 new_geometry->win_gravity = priv->gravity;
10389}
10390
10391#undef INCLUDE_CSD_SIZE
10392#undef EXCLUDE_CSD_SIZE
10393
10394/***********************
10395 * Redrawing functions *
10396 ***********************/
10397
10398static gboolean
10399ctk_window_draw (CtkWidget *widget,
10400 cairo_t *cr)
10401{
10402 CtkWindowPrivate *priv = CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
->priv;
10403 CtkStyleContext *context;
10404 gboolean ret = FALSE(0);
10405 CtkAllocation allocation;
10406 CtkBorder window_border;
10407 gint title_height;
10408
10409 context = ctk_widget_get_style_context (widget);
10410
10411 get_shadow_width (CTK_WINDOW (widget)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_window_get_type ()))))))
, &window_border);
10412 _ctk_widget_get_allocation (widget, &allocation);
10413
10414 if (ctk_cairo_should_draw_window (cr, _ctk_widget_get_window (widget)))
10415 {
10416 if (priv->client_decorated &&
10417 priv->decorated &&
10418 !priv->fullscreen &&
10419 !priv->maximized)
10420 {
10421 ctk_style_context_save_to_node (context, priv->decoration_node);
10422
10423 if (priv->use_client_shadow)
10424 {
10425 CtkBorder padding, border;
10426
10427 ctk_style_context_get_padding (context, ctk_style_context_get_state (context), &padding);
10428 ctk_style_context_get_border (context, ctk_style_context_get_state (context), &border);
10429 sum_borders (&border, &padding);
10430
10431 ctk_render_background (context, cr,
10432 window_border.left - border.left, window_border.top - border.top,
10433 allocation.width -
10434 (window_border.left + window_border.right - border.left - border.right),
10435 allocation.height -
10436 (window_border.top + window_border.bottom - border.top - border.bottom));
10437 ctk_render_frame (context, cr,
10438 window_border.left - border.left, window_border.top - border.top,
10439 allocation.width -
10440 (window_border.left + window_border.right - border.left - border.right),
10441 allocation.height -
10442 (window_border.top + window_border.bottom - border.top - border.bottom));
10443 }
10444 else
10445 {
10446 ctk_render_background (context, cr, 0, 0,
10447 allocation.width,
10448 allocation.height);
10449
10450 ctk_render_frame (context, cr, 0, 0,
10451 allocation.width,
10452 allocation.height);
10453 }
10454
10455 ctk_style_context_restore (context);
10456 }
10457
10458 if (!ctk_widget_get_app_paintable (widget))
10459 {
10460 if (priv->title_box &&
10461 ctk_widget_get_visible (priv->title_box) &&
10462 ctk_widget_get_child_visible (priv->title_box))
10463 title_height = priv->title_height;
10464 else
10465 title_height = 0;
10466
10467 ctk_render_background (context, cr,
10468 window_border.left,
10469 window_border.top + title_height,
10470 allocation.width -
10471 (window_border.left + window_border.right),
10472 allocation.height -
10473 (window_border.top + window_border.bottom +
10474 title_height));
10475 ctk_render_frame (context, cr,
10476 window_border.left,
10477 window_border.top + title_height,
10478 allocation.width -
10479 (window_border.left + window_border.right),
10480 allocation.height -
10481 (window_border.top + window_border.bottom +
10482 title_height));
10483 }
10484 }
10485
10486 if (CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->draw)
10487 ret = CTK_WIDGET_CLASS (ctk_window_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ctk_window_parent_class)), ((ctk_widget_get_type ())))))
)
->draw (widget, cr);
10488
10489 return ret;
10490}
10491
10492/**
10493 * ctk_window_present:
10494 * @window: a #CtkWindow
10495 *
10496 * Presents a window to the user. This function should not be used
10497 * as when it is called, it is too late to gather a valid timestamp
10498 * to allow focus stealing prevention to work correctly.
10499 **/
10500void
10501ctk_window_present (CtkWindow *window)
10502{
10503 ctk_window_present_with_time (window, CDK_CURRENT_TIME0L);
10504}
10505
10506/**
10507 * ctk_window_present_with_time:
10508 * @window: a #CtkWindow
10509 * @timestamp: the timestamp of the user interaction (typically a
10510 * button or key press event) which triggered this call
10511 *
10512 * Presents a window to the user. This may mean raising the window
10513 * in the stacking order, deiconifying it, moving it to the current
10514 * desktop, and/or giving it the keyboard focus, possibly dependent
10515 * on the user’s platform, window manager, and preferences.
10516 *
10517 * If @window is hidden, this function calls ctk_widget_show()
10518 * as well.
10519 *
10520 * This function should be used when the user tries to open a window
10521 * that’s already open. Say for example the preferences dialog is
10522 * currently open, and the user chooses Preferences from the menu
10523 * a second time; use ctk_window_present() to move the already-open dialog
10524 * where the user can see it.
10525 *
10526 * Presents a window to the user in response to a user interaction. The
10527 * timestamp should be gathered when the window was requested to be shown
10528 * (when clicking a link for example), rather than once the window is
10529 * ready to be shown.
10530 *
10531 * Since: 2.8
10532 **/
10533void
10534ctk_window_present_with_time (CtkWindow *window,
10535 guint32 timestamp)
10536{
10537 CtkWindowPrivate *priv;
10538 CtkWidget *widget;
10539 CdkWindow *cdk_window;
10540
10541 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10542
10543 priv = window->priv;
10544 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
10545
10546 if (ctk_widget_get_visible (widget))
10547 {
10548 cdk_window = _ctk_widget_get_window (widget);
10549
10550 g_assert (cdk_window != NULL)do { if (cdk_window != ((void*)0)) ; else g_assertion_message_expr
("Ctk", "ctkwindow.c", 10550, ((const char*) (__func__)), "cdk_window != NULL"
); } while (0)
;
10551
10552 cdk_window_show (cdk_window);
10553
10554 /* Translate a timestamp of CDK_CURRENT_TIME appropriately */
10555 if (timestamp == CDK_CURRENT_TIME0L)
10556 {
10557#ifdef CDK_WINDOWING_X11
10558 if (CDK_IS_X11_WINDOW(cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
10559 {
10560 CdkDisplay *display;
10561
10562 display = ctk_widget_get_display (widget);
10563 timestamp = cdk_x11_display_get_user_time (display);
10564 }
10565 else
10566#endif
10567 timestamp = ctk_get_current_event_time ();
10568 }
10569
10570 cdk_window_focus (cdk_window, timestamp);
10571 }
10572 else
10573 {
10574 priv->initial_timestamp = timestamp;
10575 ctk_widget_show (widget);
10576 }
10577}
10578
10579/**
10580 * ctk_window_iconify:
10581 * @window: a #CtkWindow
10582 *
10583 * Asks to iconify (i.e. minimize) the specified @window. Note that
10584 * you shouldn’t assume the window is definitely iconified afterward,
10585 * because other entities (e.g. the user or
10586 * [window manager][ctk-X11-arch]) could deiconify it
10587 * again, or there may not be a window manager in which case
10588 * iconification isn’t possible, etc. But normally the window will end
10589 * up iconified. Just don’t write code that crashes if not.
10590 *
10591 * It’s permitted to call this function before showing a window,
10592 * in which case the window will be iconified before it ever appears
10593 * onscreen.
10594 *
10595 * You can track iconification via the “window-state-event” signal
10596 * on #CtkWidget.
10597 **/
10598void
10599ctk_window_iconify (CtkWindow *window)
10600{
10601 CdkWindow *toplevel;
10602
10603 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10604
10605 window->priv->iconify_initially = TRUE(!(0));
10606
10607 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10608
10609 if (toplevel != NULL((void*)0))
10610 cdk_window_iconify (toplevel);
10611}
10612
10613/**
10614 * ctk_window_deiconify:
10615 * @window: a #CtkWindow
10616 *
10617 * Asks to deiconify (i.e. unminimize) the specified @window. Note
10618 * that you shouldn’t assume the window is definitely deiconified
10619 * afterward, because other entities (e.g. the user or
10620 * [window manager][ctk-X11-arch])) could iconify it
10621 * again before your code which assumes deiconification gets to run.
10622 *
10623 * You can track iconification via the “window-state-event” signal
10624 * on #CtkWidget.
10625 **/
10626void
10627ctk_window_deiconify (CtkWindow *window)
10628{
10629 CdkWindow *toplevel;
10630
10631 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10632
10633 window->priv->iconify_initially = FALSE(0);
10634
10635 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10636
10637 if (toplevel != NULL((void*)0))
10638 cdk_window_deiconify (toplevel);
10639}
10640
10641/**
10642 * ctk_window_stick:
10643 * @window: a #CtkWindow
10644 *
10645 * Asks to stick @window, which means that it will appear on all user
10646 * desktops. Note that you shouldn’t assume the window is definitely
10647 * stuck afterward, because other entities (e.g. the user or
10648 * [window manager][ctk-X11-arch] could unstick it
10649 * again, and some window managers do not support sticking
10650 * windows. But normally the window will end up stuck. Just don't
10651 * write code that crashes if not.
10652 *
10653 * It’s permitted to call this function before showing a window.
10654 *
10655 * You can track stickiness via the “window-state-event” signal
10656 * on #CtkWidget.
10657 **/
10658void
10659ctk_window_stick (CtkWindow *window)
10660{
10661 CdkWindow *toplevel;
10662
10663 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10664
10665 window->priv->stick_initially = TRUE(!(0));
10666
10667 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10668
10669 if (toplevel != NULL((void*)0))
10670 cdk_window_stick (toplevel);
10671}
10672
10673/**
10674 * ctk_window_unstick:
10675 * @window: a #CtkWindow
10676 *
10677 * Asks to unstick @window, which means that it will appear on only
10678 * one of the user’s desktops. Note that you shouldn’t assume the
10679 * window is definitely unstuck afterward, because other entities
10680 * (e.g. the user or [window manager][ctk-X11-arch]) could
10681 * stick it again. But normally the window will
10682 * end up stuck. Just don’t write code that crashes if not.
10683 *
10684 * You can track stickiness via the “window-state-event” signal
10685 * on #CtkWidget.
10686 **/
10687void
10688ctk_window_unstick (CtkWindow *window)
10689{
10690 CdkWindow *toplevel;
10691
10692 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10693
10694 window->priv->stick_initially = FALSE(0);
10695
10696 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10697
10698 if (toplevel != NULL((void*)0))
10699 cdk_window_unstick (toplevel);
10700}
10701
10702/**
10703 * ctk_window_maximize:
10704 * @window: a #CtkWindow
10705 *
10706 * Asks to maximize @window, so that it becomes full-screen. Note that
10707 * you shouldn’t assume the window is definitely maximized afterward,
10708 * because other entities (e.g. the user or
10709 * [window manager][ctk-X11-arch]) could unmaximize it
10710 * again, and not all window managers support maximization. But
10711 * normally the window will end up maximized. Just don’t write code
10712 * that crashes if not.
10713 *
10714 * It’s permitted to call this function before showing a window,
10715 * in which case the window will be maximized when it appears onscreen
10716 * initially.
10717 *
10718 * You can track maximization via the “window-state-event” signal
10719 * on #CtkWidget, or by listening to notifications on the
10720 * #CtkWindow:is-maximized property.
10721 **/
10722void
10723ctk_window_maximize (CtkWindow *window)
10724{
10725 CdkWindow *toplevel;
10726
10727 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10728
10729 window->priv->maximize_initially = TRUE(!(0));
10730
10731 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10732
10733 if (toplevel != NULL((void*)0))
10734 cdk_window_maximize (toplevel);
10735}
10736
10737/**
10738 * ctk_window_unmaximize:
10739 * @window: a #CtkWindow
10740 *
10741 * Asks to unmaximize @window. Note that you shouldn’t assume the
10742 * window is definitely unmaximized afterward, because other entities
10743 * (e.g. the user or [window manager][ctk-X11-arch])
10744 * could maximize it again, and not all window
10745 * managers honor requests to unmaximize. But normally the window will
10746 * end up unmaximized. Just don’t write code that crashes if not.
10747 *
10748 * You can track maximization via the “window-state-event” signal
10749 * on #CtkWidget.
10750 **/
10751void
10752ctk_window_unmaximize (CtkWindow *window)
10753{
10754 CdkWindow *toplevel;
10755
10756 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10757
10758 window->priv->maximize_initially = FALSE(0);
10759
10760 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10761
10762 if (toplevel != NULL((void*)0))
10763 cdk_window_unmaximize (toplevel);
10764}
10765
10766/**
10767 * ctk_window_fullscreen:
10768 * @window: a #CtkWindow
10769 *
10770 * Asks to place @window in the fullscreen state. Note that you
10771 * shouldn’t assume the window is definitely full screen afterward,
10772 * because other entities (e.g. the user or
10773 * [window manager][ctk-X11-arch]) could unfullscreen it
10774 * again, and not all window managers honor requests to fullscreen
10775 * windows. But normally the window will end up fullscreen. Just
10776 * don’t write code that crashes if not.
10777 *
10778 * You can track the fullscreen state via the “window-state-event” signal
10779 * on #CtkWidget.
10780 *
10781 * Since: 2.2
10782 **/
10783void
10784ctk_window_fullscreen (CtkWindow *window)
10785{
10786 CdkWindow *toplevel;
10787
10788 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10789
10790 window->priv->fullscreen_initially = TRUE(!(0));
10791
10792 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10793
10794 if (toplevel != NULL((void*)0))
10795 cdk_window_fullscreen (toplevel);
10796}
10797
10798/**
10799 * ctk_window_fullscreen_on_monitor:
10800 * @window: a #CtkWindow
10801 * @screen: a #CdkScreen to draw to
10802 * @monitor: which monitor to go fullscreen on
10803 *
10804 * Asks to place @window in the fullscreen state. Note that you shouldn't assume
10805 * the window is definitely full screen afterward.
10806 *
10807 * You can track the fullscreen state via the "window-state-event" signal
10808 * on #CtkWidget.
10809 *
10810 * Since: 3.18
10811 */
10812void
10813ctk_window_fullscreen_on_monitor (CtkWindow *window,
10814 CdkScreen *screen,
10815 gint monitor)
10816{
10817 CtkWindowPrivate *priv;
10818 CtkWidget *widget;
10819 CdkWindow *toplevel;
10820
10821 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10822 g_return_if_fail (CDK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CDK_IS_SCREEN (screen)"); return; } } while (0)
;
10823 g_return_if_fail (cdk_display_get_monitor (cdk_screen_get_display (screen), monitor) != NULL)do { if ((cdk_display_get_monitor (cdk_screen_get_display (screen
), monitor) != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "cdk_display_get_monitor (cdk_screen_get_display (screen), monitor) != NULL"
); return; } } while (0)
;
10824
10825 priv = window->priv;
10826 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
10827
10828 ctk_window_set_screen (window, screen);
10829
10830 priv->initial_fullscreen_monitor = monitor;
10831 priv->fullscreen_initially = TRUE(!(0));
10832
10833 toplevel = _ctk_widget_get_window (widget);
10834
10835 if (toplevel != NULL((void*)0))
10836 cdk_window_fullscreen_on_monitor (toplevel, monitor);
10837}
10838
10839/**
10840 * ctk_window_unfullscreen:
10841 * @window: a #CtkWindow
10842 *
10843 * Asks to toggle off the fullscreen state for @window. Note that you
10844 * shouldn’t assume the window is definitely not full screen
10845 * afterward, because other entities (e.g. the user or
10846 * [window manager][ctk-X11-arch]) could fullscreen it
10847 * again, and not all window managers honor requests to unfullscreen
10848 * windows. But normally the window will end up restored to its normal
10849 * state. Just don’t write code that crashes if not.
10850 *
10851 * You can track the fullscreen state via the “window-state-event” signal
10852 * on #CtkWidget.
10853 *
10854 * Since: 2.2
10855 **/
10856void
10857ctk_window_unfullscreen (CtkWindow *window)
10858{
10859 CdkWindow *toplevel;
10860
10861 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10862
10863 window->priv->initial_fullscreen_monitor = -1;
10864 window->priv->fullscreen_initially = FALSE(0);
10865
10866 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10867
10868 if (toplevel != NULL((void*)0))
10869 cdk_window_unfullscreen (toplevel);
10870}
10871
10872/**
10873 * ctk_window_set_keep_above:
10874 * @window: a #CtkWindow
10875 * @setting: whether to keep @window above other windows
10876 *
10877 * Asks to keep @window above, so that it stays on top. Note that
10878 * you shouldn’t assume the window is definitely above afterward,
10879 * because other entities (e.g. the user or
10880 * [window manager][ctk-X11-arch]) could not keep it above,
10881 * and not all window managers support keeping windows above. But
10882 * normally the window will end kept above. Just don’t write code
10883 * that crashes if not.
10884 *
10885 * It’s permitted to call this function before showing a window,
10886 * in which case the window will be kept above when it appears onscreen
10887 * initially.
10888 *
10889 * You can track the above state via the “window-state-event” signal
10890 * on #CtkWidget.
10891 *
10892 * Note that, according to the
10893 * [Extended Window Manager Hints Specification](http://www.freedesktop.org/Standards/wm-spec),
10894 * the above state is mainly meant for user preferences and should not
10895 * be used by applications e.g. for drawing attention to their
10896 * dialogs.
10897 *
10898 * Since: 2.4
10899 **/
10900void
10901ctk_window_set_keep_above (CtkWindow *window,
10902 gboolean setting)
10903{
10904 CdkWindow *toplevel;
10905
10906 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10907
10908 setting = setting != FALSE(0);
10909
10910 window->priv->above_initially = setting;
10911 window->priv->below_initially &= !setting;
10912
10913 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10914
10915 if (toplevel != NULL((void*)0))
10916 cdk_window_set_keep_above (toplevel, setting);
10917}
10918
10919/**
10920 * ctk_window_set_keep_below:
10921 * @window: a #CtkWindow
10922 * @setting: whether to keep @window below other windows
10923 *
10924 * Asks to keep @window below, so that it stays in bottom. Note that
10925 * you shouldn’t assume the window is definitely below afterward,
10926 * because other entities (e.g. the user or
10927 * [window manager][ctk-X11-arch]) could not keep it below,
10928 * and not all window managers support putting windows below. But
10929 * normally the window will be kept below. Just don’t write code
10930 * that crashes if not.
10931 *
10932 * It’s permitted to call this function before showing a window,
10933 * in which case the window will be kept below when it appears onscreen
10934 * initially.
10935 *
10936 * You can track the below state via the “window-state-event” signal
10937 * on #CtkWidget.
10938 *
10939 * Note that, according to the
10940 * [Extended Window Manager Hints Specification](http://www.freedesktop.org/Standards/wm-spec),
10941 * the above state is mainly meant for user preferences and should not
10942 * be used by applications e.g. for drawing attention to their
10943 * dialogs.
10944 *
10945 * Since: 2.4
10946 **/
10947void
10948ctk_window_set_keep_below (CtkWindow *window,
10949 gboolean setting)
10950{
10951 CdkWindow *toplevel;
10952
10953 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10954
10955 setting = setting != FALSE(0);
10956
10957 window->priv->below_initially = setting;
10958 window->priv->above_initially &= !setting;
10959
10960 toplevel = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10961
10962 if (toplevel != NULL((void*)0))
10963 cdk_window_set_keep_below (toplevel, setting);
10964}
10965
10966/**
10967 * ctk_window_set_resizable:
10968 * @window: a #CtkWindow
10969 * @resizable: %TRUE if the user can resize this window
10970 *
10971 * Sets whether the user can resize a window. Windows are user resizable
10972 * by default.
10973 **/
10974void
10975ctk_window_set_resizable (CtkWindow *window,
10976 gboolean resizable)
10977{
10978 CtkWindowPrivate *priv;
10979
10980 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
10981
10982 priv = window->priv;
10983
10984 resizable = (resizable != FALSE(0));
10985
10986 if (priv->resizable != resizable)
10987 {
10988 priv->resizable = resizable;
10989
10990 update_window_buttons (window);
10991
10992 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
10993
10994 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_RESIZABLE]);
10995 }
10996}
10997
10998/**
10999 * ctk_window_get_resizable:
11000 * @window: a #CtkWindow
11001 *
11002 * Gets the value set by ctk_window_set_resizable().
11003 *
11004 * Returns: %TRUE if the user can resize the window
11005 **/
11006gboolean
11007ctk_window_get_resizable (CtkWindow *window)
11008{
11009 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
11010
11011 return window->priv->resizable;
11012}
11013
11014/**
11015 * ctk_window_set_gravity:
11016 * @window: a #CtkWindow
11017 * @gravity: window gravity
11018 *
11019 * Window gravity defines the meaning of coordinates passed to
11020 * ctk_window_move(). See ctk_window_move() and #CdkGravity for
11021 * more details.
11022 *
11023 * The default window gravity is #CDK_GRAVITY_NORTH_WEST which will
11024 * typically “do what you mean.”
11025 *
11026 **/
11027void
11028ctk_window_set_gravity (CtkWindow *window,
11029 CdkGravity gravity)
11030{
11031 CtkWindowPrivate *priv;
11032
11033 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
11034
11035 priv = window->priv;
11036
11037 if (gravity != priv->gravity)
11038 {
11039 priv->gravity = gravity;
11040
11041 /* ctk_window_move_resize() will adapt gravity
11042 */
11043 ctk_widget_queue_resize_no_redraw (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
11044
11045 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_GRAVITY]);
11046 }
11047}
11048
11049/**
11050 * ctk_window_get_gravity:
11051 * @window: a #CtkWindow
11052 *
11053 * Gets the value set by ctk_window_set_gravity().
11054 *
11055 * Returns: (transfer none): window gravity
11056 **/
11057CdkGravity
11058ctk_window_get_gravity (CtkWindow *window)
11059{
11060 g_return_val_if_fail (CTK_IS_WINDOW (window), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (0); } } while (0)
;
11061
11062 return window->priv->gravity;
11063}
11064
11065/**
11066 * ctk_window_begin_resize_drag:
11067 * @window: a #CtkWindow
11068 * @button: mouse button that initiated the drag
11069 * @edge: position of the resize control
11070 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
11071 * @root_y: Y position where the user clicked to initiate the drag
11072 * @timestamp: timestamp from the click event that initiated the drag
11073 *
11074 * Starts resizing a window. This function is used if an application
11075 * has window resizing controls. When CDK can support it, the resize
11076 * will be done using the standard mechanism for the
11077 * [window manager][ctk-X11-arch] or windowing
11078 * system. Otherwise, CDK will try to emulate window resizing,
11079 * potentially not all that well, depending on the windowing system.
11080 */
11081void
11082ctk_window_begin_resize_drag (CtkWindow *window,
11083 CdkWindowEdge edge,
11084 gint button,
11085 gint root_x,
11086 gint root_y,
11087 guint32 timestamp)
11088{
11089 CtkWidget *widget;
11090 CdkWindow *toplevel;
11091
11092 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
11093 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
11094 g_return_if_fail (ctk_widget_get_visible (widget))do { if ((ctk_widget_get_visible (widget))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "ctk_widget_get_visible (widget)"
); return; } } while (0)
;
11095
11096 toplevel = _ctk_widget_get_window (widget);
11097
11098 cdk_window_begin_resize_drag (toplevel,
11099 edge, button,
11100 root_x, root_y,
11101 timestamp);
11102}
11103
11104/**
11105 * ctk_window_begin_move_drag:
11106 * @window: a #CtkWindow
11107 * @button: mouse button that initiated the drag
11108 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
11109 * @root_y: Y position where the user clicked to initiate the drag
11110 * @timestamp: timestamp from the click event that initiated the drag
11111 *
11112 * Starts moving a window. This function is used if an application has
11113 * window movement grips. When CDK can support it, the window movement
11114 * will be done using the standard mechanism for the
11115 * [window manager][ctk-X11-arch] or windowing
11116 * system. Otherwise, CDK will try to emulate window movement,
11117 * potentially not all that well, depending on the windowing system.
11118 */
11119void
11120ctk_window_begin_move_drag (CtkWindow *window,
11121 gint button,
11122 gint root_x,
11123 gint root_y,
11124 guint32 timestamp)
11125{
11126 CtkWidget *widget;
11127 CdkWindow *toplevel;
11128
11129 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
11130 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
11131 g_return_if_fail (ctk_widget_get_visible (widget))do { if ((ctk_widget_get_visible (widget))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "ctk_widget_get_visible (widget)"
); return; } } while (0)
;
11132
11133 toplevel = _ctk_widget_get_window (widget);
11134
11135 cdk_window_begin_move_drag (toplevel,
11136 button,
11137 root_x, root_y,
11138 timestamp);
11139}
11140
11141/**
11142 * ctk_window_set_screen:
11143 * @window: a #CtkWindow.
11144 * @screen: a #CdkScreen.
11145 *
11146 * Sets the #CdkScreen where the @window is displayed; if
11147 * the window is already mapped, it will be unmapped, and
11148 * then remapped on the new screen.
11149 *
11150 * Since: 2.2
11151 */
11152void
11153ctk_window_set_screen (CtkWindow *window,
11154 CdkScreen *screen)
11155{
11156 CtkWindowPrivate *priv;
11157 CtkWidget *widget;
11158 CdkScreen *previous_screen;
11159 gboolean was_rgba;
11160 gboolean was_mapped;
11161
11162 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
11163 g_return_if_fail (CDK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CDK_IS_SCREEN (screen)"); return; } } while (0)
;
11164
11165 priv = window->priv;
11166
11167 if (screen == priv->screen)
11168 return;
11169
11170 /* reset initial_fullscreen_monitor since they are relative to the screen */
11171 priv->initial_fullscreen_monitor = -1;
11172
11173 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
11174
11175 previous_screen = priv->screen;
11176
11177 if (cdk_screen_get_rgba_visual (previous_screen) == ctk_widget_get_visual (widget))
11178 was_rgba = TRUE(!(0));
11179 else
11180 was_rgba = FALSE(0);
11181
11182 was_mapped = _ctk_widget_get_mapped (widget);
11183
11184 if (was_mapped)
11185 ctk_widget_unmap (widget);
11186 if (_ctk_widget_get_realized (widget))
11187 ctk_widget_unrealize (widget);
11188
11189 ctk_window_free_key_hash (window);
11190 priv->screen = screen;
11191 if (screen != previous_screen)
11192 {
11193 if (previous_screen)
11194 {
11195 g_signal_handlers_disconnect_by_func (previous_screen,g_signal_handlers_disconnect_matched ((previous_screen), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (ctk_window_on_composited_changed), (window))
11196 ctk_window_on_composited_changed, window)g_signal_handlers_disconnect_matched ((previous_screen), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (ctk_window_on_composited_changed), (window))
;
11197#ifdef CDK_WINDOWING_X11
11198 g_signal_handlers_disconnect_by_func (ctk_settings_get_for_screen (previous_screen),g_signal_handlers_disconnect_matched ((ctk_settings_get_for_screen
(previous_screen)), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA), 0, 0, ((void*)0), (ctk_window_on_theme_variant_changed
), (window))
11199 ctk_window_on_theme_variant_changed, window)g_signal_handlers_disconnect_matched ((ctk_settings_get_for_screen
(previous_screen)), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA), 0, 0, ((void*)0), (ctk_window_on_theme_variant_changed
), (window))
;
11200#endif
11201 }
11202 g_signal_connect (screen, "composited-changed",g_signal_connect_data ((screen), ("composited-changed"), (((GCallback
) (ctk_window_on_composited_changed))), (window), ((void*)0),
(GConnectFlags) 0)
11203 G_CALLBACK (ctk_window_on_composited_changed), window)g_signal_connect_data ((screen), ("composited-changed"), (((GCallback
) (ctk_window_on_composited_changed))), (window), ((void*)0),
(GConnectFlags) 0)
;
11204#ifdef CDK_WINDOWING_X11
11205 g_signal_connect (ctk_settings_get_for_screen (screen),g_signal_connect_data ((ctk_settings_get_for_screen (screen))
, ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
11206 "notify::ctk-application-prefer-dark-theme",g_signal_connect_data ((ctk_settings_get_for_screen (screen))
, ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
11207 G_CALLBACK (ctk_window_on_theme_variant_changed), window)g_signal_connect_data ((ctk_settings_get_for_screen (screen))
, ("notify::ctk-application-prefer-dark-theme"), (((GCallback
) (ctk_window_on_theme_variant_changed))), (window), ((void*)
0), (GConnectFlags) 0)
;
11208#endif
11209
11210 _ctk_widget_propagate_screen_changed (widget, previous_screen);
11211 _ctk_widget_propagate_composited_changed (widget);
11212 }
11213 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_SCREEN]);
11214
11215 if (was_rgba && priv->use_client_shadow)
11216 {
11217 CdkVisual *visual;
11218
11219 visual = cdk_screen_get_rgba_visual (screen);
11220 if (visual)
11221 ctk_widget_set_visual (widget, visual);
11222 }
11223
11224 if (was_mapped)
11225 ctk_widget_map (widget);
11226
11227 check_scale_changed (window);
11228}
11229
11230static void
11231ctk_window_set_theme_variant (CtkWindow *window)
11232{
11233#ifdef CDK_WINDOWING_X11
11234 CdkWindow *cdk_window;
11235 gboolean dark_theme_requested;
11236
11237 g_object_get (ctk_settings_get_for_screen (window->priv->screen),
11238 "ctk-application-prefer-dark-theme", &dark_theme_requested,
11239 NULL((void*)0));
11240
11241 cdk_window = _ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
11242
11243 if (CDK_IS_X11_WINDOW (cdk_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(cdk_window)); GType __t = ((cdk_x11_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
11244 cdk_x11_window_set_theme_variant (cdk_window,
11245 dark_theme_requested ? "dark" : NULL((void*)0));
11246#endif
11247}
11248
11249#ifdef CDK_WINDOWING_X11
11250static void
11251ctk_window_on_theme_variant_changed (CtkSettings *settings G_GNUC_UNUSED__attribute__ ((__unused__)),
11252 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
11253 CtkWindow *window)
11254{
11255 if (window->priv->type == CTK_WINDOW_TOPLEVEL)
11256 ctk_window_set_theme_variant (window);
11257}
11258#endif
11259
11260static void
11261ctk_window_on_composited_changed (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)),
11262 CtkWindow *window)
11263{
11264 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
11265
11266 ctk_widget_queue_draw (widget);
11267 _ctk_widget_propagate_composited_changed (widget);
11268}
11269
11270static CdkScreen *
11271ctk_window_check_screen (CtkWindow *window)
11272{
11273 CtkWindowPrivate *priv = window->priv;
11274
11275 if (priv->screen)
11276 return priv->screen;
11277 else
11278 {
11279 g_warning ("Screen for CtkWindow not set; you must always set\n"
11280 "a screen for a CtkWindow before using the window");
11281 return NULL((void*)0);
11282 }
11283}
11284
11285/**
11286 * ctk_window_get_screen:
11287 * @window: a #CtkWindow.
11288 *
11289 * Returns the #CdkScreen associated with @window.
11290 *
11291 * Returns: (transfer none): a #CdkScreen.
11292 *
11293 * Since: 2.2
11294 */
11295CdkScreen*
11296ctk_window_get_screen (CtkWindow *window)
11297{
11298 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
11299
11300 return window->priv->screen;
11301}
11302
11303CdkScreen *
11304_ctk_window_get_screen (CtkWindow *window)
11305{
11306 return window->priv->screen;
11307}
11308
11309/**
11310 * ctk_window_is_active:
11311 * @window: a #CtkWindow
11312 *
11313 * Returns whether the window is part of the current active toplevel.
11314 * (That is, the toplevel window receiving keystrokes.)
11315 * The return value is %TRUE if the window is active toplevel
11316 * itself, but also if it is, say, a #CtkPlug embedded in the active toplevel.
11317 * You might use this function if you wanted to draw a widget
11318 * differently in an active window from a widget in an inactive window.
11319 * See ctk_window_has_toplevel_focus()
11320 *
11321 * Returns: %TRUE if the window part of the current active window.
11322 *
11323 * Since: 2.4
11324 **/
11325gboolean
11326ctk_window_is_active (CtkWindow *window)
11327{
11328 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
11329
11330 return window->priv->is_active;
11331}
11332
11333/**
11334 * ctk_window_has_toplevel_focus:
11335 * @window: a #CtkWindow
11336 *
11337 * Returns whether the input focus is within this CtkWindow.
11338 * For real toplevel windows, this is identical to ctk_window_is_active(),
11339 * but for embedded windows, like #CtkPlug, the results will differ.
11340 *
11341 * Returns: %TRUE if the input focus is within this CtkWindow
11342 *
11343 * Since: 2.4
11344 **/
11345gboolean
11346ctk_window_has_toplevel_focus (CtkWindow *window)
11347{
11348 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
11349
11350 return window->priv->has_toplevel_focus;
11351}
11352
11353/**
11354 * ctk_window_get_group:
11355 * @window: (allow-none): a #CtkWindow, or %NULL
11356 *
11357 * Returns the group for @window or the default group, if
11358 * @window is %NULL or if @window does not have an explicit
11359 * window group.
11360 *
11361 * Returns: (transfer none): the #CtkWindowGroup for a window or the default group
11362 *
11363 * Since: 2.10
11364 */
11365CtkWindowGroup *
11366ctk_window_get_group (CtkWindow *window)
11367{
11368 if (window && window->priv->group)
11369 return window->priv->group;
11370 else
11371 {
11372 static CtkWindowGroup *default_group = NULL((void*)0);
11373
11374 if (!default_group)
11375 default_group = ctk_window_group_new ();
11376
11377 return default_group;
11378 }
11379}
11380
11381/**
11382 * ctk_window_has_group:
11383 * @window: a #CtkWindow
11384 *
11385 * Returns whether @window has an explicit window group.
11386 *
11387 * Returns: %TRUE if @window has an explicit window group.
11388 *
11389 * Since 2.22
11390 **/
11391gboolean
11392ctk_window_has_group (CtkWindow *window)
11393{
11394 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
11395
11396 return window->priv->group != NULL((void*)0);
11397}
11398
11399CtkWindowGroup *
11400_ctk_window_get_window_group (CtkWindow *window)
11401{
11402 return window->priv->group;
11403}
11404
11405void
11406_ctk_window_set_window_group (CtkWindow *window,
11407 CtkWindowGroup *group)
11408{
11409 window->priv->group = group;
11410}
11411
11412/*
11413 Derived from XParseGeometry() in XFree86
11414
11415 Copyright 1985, 1986, 1987,1998 The Open Group
11416
11417 All Rights Reserved.
11418
11419 The above copyright notice and this permission notice shall be included
11420 in all copies or substantial portions of the Software.
11421
11422 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11423 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11424 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
11425 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
11426 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
11427 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
11428 OTHER DEALINGS IN THE SOFTWARE.
11429
11430 Except as contained in this notice, the name of The Open Group shall
11431 not be used in advertising or otherwise to promote the sale, use or
11432 other dealings in this Software without prior written authorization
11433 from The Open Group.
11434*/
11435
11436
11437/*
11438 * XParseGeometry parses strings of the form
11439 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
11440 * width, height, xoffset, and yoffset are unsigned integers.
11441 * Example: “=80x24+300-49”
11442 * The equal sign is optional.
11443 * It returns a bitmask that indicates which of the four values
11444 * were actually found in the string. For each value found,
11445 * the corresponding argument is updated; for each value
11446 * not found, the corresponding argument is left unchanged.
11447 */
11448
11449/* The following code is from Xlib, and is minimally modified, so we
11450 * can track any upstream changes if required. Don’t change this
11451 * code. Or if you do, put in a huge comment marking which thing
11452 * changed.
11453 */
11454
11455static int
11456read_int (gchar *string,
11457 gchar **next)
11458{
11459 int result = 0;
11460 int sign = 1;
11461
11462 if (*string == '+')
11463 string++;
11464 else if (*string == '-')
11465 {
11466 string++;
11467 sign = -1;
11468 }
11469
11470 for (; (*string >= '0') && (*string <= '9'); string++)
11471 {
11472 result = (result * 10) + (*string - '0');
11473 }
11474
11475 *next = string;
11476
11477 if (sign >= 0)
11478 return (result);
11479 else
11480 return (-result);
11481}
11482
11483/*
11484 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
11485 * value (x, y, width, height) was found in the parsed string.
11486 */
11487#define NoValue0x0000 0x0000
11488#define XValue0x0001 0x0001
11489#define YValue0x0002 0x0002
11490#define WidthValue0x0004 0x0004
11491#define HeightValue0x0008 0x0008
11492#define AllValues0x000F 0x000F
11493#define XNegative0x0010 0x0010
11494#define YNegative0x0020 0x0020
11495
11496/* Try not to reformat/modify, so we can compare/sync with X sources */
11497static int
11498ctk_XParseGeometry (const char *string,
11499 int *x,
11500 int *y,
11501 unsigned int *width,
11502 unsigned int *height)
11503{
11504 int mask = NoValue0x0000;
11505 char *strind;
11506 unsigned int tempWidth, tempHeight;
11507 int tempX, tempY;
11508 char *nextCharacter;
11509
11510 /* These initializations are just to silence gcc */
11511 tempWidth = 0;
11512 tempHeight = 0;
11513 tempX = 0;
11514 tempY = 0;
11515
11516 if ( (string == NULL((void*)0)) || (*string == '\0')) return(mask);
11517 if (*string == '=')
11518 string++; /* ignore possible '=' at beg of geometry spec */
11519
11520 strind = (char *)string;
11521 if (*strind != '+' && *strind != '-' && *strind != 'x') {
11522 tempWidth = read_int(strind, &nextCharacter);
11523 if (strind == nextCharacter)
11524 return (0);
11525 strind = nextCharacter;
11526 mask |= WidthValue0x0004;
11527 }
11528
11529 if (*strind == 'x' || *strind == 'X') {
11530 strind++;
11531 tempHeight = read_int(strind, &nextCharacter);
11532 if (strind == nextCharacter)
11533 return (0);
11534 strind = nextCharacter;
11535 mask |= HeightValue0x0008;
11536 }
11537
11538 if ((*strind == '+') || (*strind == '-')) {
11539 if (*strind == '-') {
11540 strind++;
11541 tempX = -read_int(strind, &nextCharacter);
11542 if (strind == nextCharacter)
11543 return (0);
11544 strind = nextCharacter;
11545 mask |= XNegative0x0010;
11546
11547 }
11548 else
11549 { strind++;
11550 tempX = read_int(strind, &nextCharacter);
11551 if (strind == nextCharacter)
11552 return(0);
11553 strind = nextCharacter;
11554 }
11555 mask |= XValue0x0001;
11556 if ((*strind == '+') || (*strind == '-')) {
11557 if (*strind == '-') {
11558 strind++;
11559 tempY = -read_int(strind, &nextCharacter);
11560 if (strind == nextCharacter)
11561 return(0);
11562 strind = nextCharacter;
11563 mask |= YNegative0x0020;
11564
11565 }
11566 else
11567 {
11568 strind++;
11569 tempY = read_int(strind, &nextCharacter);
11570 if (strind == nextCharacter)
11571 return(0);
11572 strind = nextCharacter;
11573 }
11574 mask |= YValue0x0002;
11575 }
11576 }
11577
11578 /* If strind isn't at the end of the string the it's an invalid
11579 geometry specification. */
11580
11581 if (*strind != '\0') return (0);
11582
11583 if (mask & XValue0x0001)
11584 *x = tempX;
11585 if (mask & YValue0x0002)
11586 *y = tempY;
11587 if (mask & WidthValue0x0004)
11588 *width = tempWidth;
11589 if (mask & HeightValue0x0008)
11590 *height = tempHeight;
11591 return (mask);
11592}
11593
11594/**
11595 * ctk_window_parse_geometry:
11596 * @window: a #CtkWindow
11597 * @geometry: geometry string
11598 *
11599 * Parses a standard X Window System geometry string - see the
11600 * manual page for X (type “man X”) for details on this.
11601 * ctk_window_parse_geometry() does work on all CTK+ ports
11602 * including Win32 but is primarily intended for an X environment.
11603 *
11604 * If either a size or a position can be extracted from the
11605 * geometry string, ctk_window_parse_geometry() returns %TRUE
11606 * and calls ctk_window_set_default_size() and/or ctk_window_move()
11607 * to resize/move the window.
11608 *
11609 * If ctk_window_parse_geometry() returns %TRUE, it will also
11610 * set the #CDK_HINT_USER_POS and/or #CDK_HINT_USER_SIZE hints
11611 * indicating to the window manager that the size/position of
11612 * the window was user-specified. This causes most window
11613 * managers to honor the geometry.
11614 *
11615 * Note that for ctk_window_parse_geometry() to work as expected, it has
11616 * to be called when the window has its “final” size, i.e. after calling
11617 * ctk_widget_show_all() on the contents and ctk_window_set_geometry_hints()
11618 * on the window.
11619 * |[<!-- language="C" -->
11620 * #include <ctk/ctk.h>
11621 *
11622 * static void
11623 * fill_with_content (CtkWidget *vbox)
11624 * {
11625 * // fill with content...
11626 * }
11627 *
11628 * int
11629 * main (int argc, char *argv[])
11630 * {
11631 * CtkWidget *window, *vbox;
11632 * CdkGeometry size_hints = {
11633 * 100, 50, 0, 0, 100, 50, 10,
11634 * 10, 0.0, 0.0, CDK_GRAVITY_NORTH_WEST
11635 * };
11636 *
11637 * ctk_init (&argc, &argv);
11638 *
11639 * window = ctk_window_new (CTK_WINDOW_TOPLEVEL);
11640 * vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
11641 *
11642 * ctk_container_add (CTK_CONTAINER (window), vbox);
11643 * fill_with_content (vbox);
11644 * ctk_widget_show_all (vbox);
11645 *
11646 * ctk_window_set_geometry_hints (CTK_WINDOW (window),
11647 * NULL,
11648 * &size_hints,
11649 * CDK_HINT_MIN_SIZE |
11650 * CDK_HINT_BASE_SIZE |
11651 * CDK_HINT_RESIZE_INC);
11652 *
11653 * if (argc > 1)
11654 * {
11655 * gboolean res;
11656 * res = ctk_window_parse_geometry (CTK_WINDOW (window),
11657 * argv[1]);
11658 * if (! res)
11659 * fprintf (stderr,
11660 * "Failed to parse “%s”\n",
11661 * argv[1]);
11662 * }
11663 *
11664 * ctk_widget_show_all (window);
11665 * ctk_main ();
11666 *
11667 * return 0;
11668 * }
11669 * ]|
11670 *
11671 * Returns: %TRUE if string was parsed successfully
11672 **/
11673gboolean
11674ctk_window_parse_geometry (CtkWindow *window,
11675 const gchar *geometry)
11676{
11677 gint result, x = 0, y = 0;
11678 guint w, h;
11679 CtkWidget *child;
11680 CdkGravity grav;
11681 gboolean size_set, pos_set;
11682 CdkScreen *screen;
11683
11684 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
11685 g_return_val_if_fail (geometry != NULL, FALSE)do { if ((geometry != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "geometry != NULL"); return
((0)); } } while (0)
;
11686
11687 child = ctk_bin_get_child (CTK_BIN (window)((((CtkBin*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_bin_get_type ()))))))
);
11688 if (!child || !ctk_widget_get_visible (child))
11689 g_warning ("ctk_window_parse_geometry() called on a window with no "
11690 "visible children; the window should be set up before "
11691 "ctk_window_parse_geometry() is called.");
11692
11693 screen = ctk_window_check_screen (window);
11694
11695 result = ctk_XParseGeometry (geometry, &x, &y, &w, &h);
11696
11697 size_set = FALSE(0);
11698 if ((result & WidthValue0x0004) || (result & HeightValue0x0008))
11699 {
11700 ctk_window_set_default_size_internal (window,
11701 TRUE(!(0)), result & WidthValue0x0004 ? w : -1,
11702 TRUE(!(0)), result & HeightValue0x0008 ? h : -1,
11703 TRUE(!(0)));
11704 size_set = TRUE(!(0));
11705 }
11706
11707 ctk_window_get_size (window, (gint *)&w, (gint *)&h);
11708
11709 grav = CDK_GRAVITY_NORTH_WEST;
11710
11711 if ((result & XNegative0x0010) && (result & YNegative0x0020))
11712 grav = CDK_GRAVITY_SOUTH_EAST;
11713 else if (result & XNegative0x0010)
11714 grav = CDK_GRAVITY_NORTH_EAST;
11715 else if (result & YNegative0x0020)
11716 grav = CDK_GRAVITY_SOUTH_WEST;
11717
11718 if ((result & XValue0x0001) == 0)
11719 x = 0;
11720
11721 if ((result & YValue0x0002) == 0)
11722 y = 0;
11723
11724G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
11725 if (grav == CDK_GRAVITY_SOUTH_WEST ||
11726 grav == CDK_GRAVITY_SOUTH_EAST)
11727 y = cdk_screen_get_height (screen) - h + y;
11728
11729 if (grav == CDK_GRAVITY_SOUTH_EAST ||
11730 grav == CDK_GRAVITY_NORTH_EAST)
11731 x = cdk_screen_get_width (screen) - w + x;
11732G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop
11733
11734 /* we don't let you put a window offscreen; maybe some people would
11735 * prefer to be able to, but it's kind of a bogus thing to do.
11736 */
11737 if (y < 0)
11738 y = 0;
11739
11740 if (x < 0)
11741 x = 0;
11742
11743 pos_set = FALSE(0);
11744 if ((result & XValue0x0001) || (result & YValue0x0002))
11745 {
11746 ctk_window_set_gravity (window, grav);
11747 ctk_window_move (window, x, y);
11748 pos_set = TRUE(!(0));
11749 }
11750
11751 if (size_set || pos_set)
11752 {
11753 /* Set USSize, USPosition hints */
11754 CtkWindowGeometryInfo *info;
11755
11756 info = ctk_window_get_geometry_info (window, TRUE(!(0)));
11757
11758 if (pos_set)
11759 info->mask |= CDK_HINT_USER_POS;
11760 if (size_set)
11761 info->mask |= CDK_HINT_USER_SIZE;
11762 }
11763
11764 return result != 0;
11765}
11766
11767static gboolean
11768ctk_window_activate_menubar (CtkWindow *window,
11769 CdkEventKey *event)
11770{
11771 CtkWindowPrivate *priv = window->priv;
11772 gchar *accel = NULL((void*)0);
11773 guint keyval = 0;
11774 CdkModifierType mods = 0;
11775
11776 g_object_get (ctk_widget_get_settings (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
11777 "ctk-menu-bar-accel", &accel,
11778 NULL((void*)0));
11779
11780 if (accel == NULL((void*)0) || *accel == 0)
11781 return FALSE(0);
11782
11783 ctk_accelerator_parse (accel, &keyval, &mods);
11784
11785 if (keyval == 0)
11786 {
11787 g_warning ("Failed to parse menu bar accelerator '%s'", accel);
11788 g_free (accel);
11789 return FALSE(0);
11790 }
11791
11792 g_free (accel);
11793
11794 /* FIXME this is wrong, needs to be in the global accel resolution
11795 * thing, to properly consider i18n etc., but that probably requires
11796 * AccelGroup changes etc.
11797 */
11798 if (event->keyval == keyval &&
11799 ((event->state & ctk_accelerator_get_default_mod_mask ()) ==
11800 (mods & ctk_accelerator_get_default_mod_mask ())))
11801 {
11802 GList *tmp_menubars;
11803 GList *menubars;
11804 CtkMenuShell *menu_shell;
11805 CtkWidget *focus;
11806
11807 focus = ctk_window_get_focus (window);
11808
11809 if (priv->title_box != NULL((void*)0) &&
11810 (focus == NULL((void*)0) || !ctk_widget_is_ancestor (focus, priv->title_box)) &&
11811 ctk_widget_child_focus (priv->title_box, CTK_DIR_TAB_FORWARD))
11812 return TRUE(!(0));
11813
11814 tmp_menubars = _ctk_menu_bar_get_viewable_menu_bars (window);
11815 if (tmp_menubars == NULL((void*)0))
11816 return FALSE(0);
11817
11818 menubars = _ctk_container_focus_sort (CTK_CONTAINER (window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_container_get_type ()))))))
, tmp_menubars,
11819 CTK_DIR_TAB_FORWARD, NULL((void*)0));
11820 g_list_free (tmp_menubars);
11821
11822 if (menubars == NULL((void*)0))
11823 return FALSE(0);
11824
11825 menu_shell = CTK_MENU_SHELL (menubars->data)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menubars->data)), ((ctk_menu_shell_get_type ()))))))
;
11826
11827 _ctk_menu_shell_set_keyboard_mode (menu_shell, TRUE(!(0)));
11828 ctk_menu_shell_select_first (menu_shell, FALSE(0));
11829
11830 g_list_free (menubars);
11831
11832 return TRUE(!(0));
11833 }
11834 return FALSE(0);
11835}
11836
11837static void
11838ctk_window_mnemonic_hash_foreach (guint keyval,
11839 GSList *targets G_GNUC_UNUSED__attribute__ ((__unused__)),
11840 gpointer data)
11841{
11842 struct {
11843 CtkWindow *window;
11844 CtkWindowKeysForeachFunc func;
11845 gpointer func_data;
11846 } *info = data;
11847
11848 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE(!(0)), info->func_data);
11849}
11850
11851void
11852_ctk_window_keys_foreach (CtkWindow *window,
11853 CtkWindowKeysForeachFunc func,
11854 gpointer func_data)
11855{
11856 GSList *groups;
11857 CtkMnemonicHash *mnemonic_hash;
11858
11859 struct {
11860 CtkWindow *window;
11861 CtkWindowKeysForeachFunc func;
11862 gpointer func_data;
11863 } info;
11864
11865 info.window = window;
11866 info.func = func;
11867 info.func_data = func_data;
11868
11869 mnemonic_hash = ctk_window_get_mnemonic_hash (window, FALSE(0));
11870 if (mnemonic_hash)
11871 _ctk_mnemonic_hash_foreach (mnemonic_hash,
11872 ctk_window_mnemonic_hash_foreach, &info);
11873
11874 groups = ctk_accel_groups_from_object (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
);
11875 while (groups)
11876 {
11877 CtkAccelGroup *group = groups->data;
11878 gint i;
11879
11880 for (i = 0; i < group->priv->n_accels; i++)
11881 {
11882 CtkAccelKey *key = &group->priv->priv_accels[i].key;
11883
11884 if (key->accel_key)
11885 (*func) (window, key->accel_key, key->accel_mods, FALSE(0), func_data);
11886 }
11887
11888 groups = groups->next;
11889 }
11890
11891 if (window->priv->application)
11892 {
11893 CtkApplicationAccels *app_accels;
11894
11895 app_accels = ctk_application_get_application_accels (window->priv->application);
11896 ctk_application_accels_foreach_key (app_accels, window, func, func_data);
11897 }
11898}
11899
11900static void
11901ctk_window_keys_changed (CtkWindow *window)
11902{
11903 ctk_window_free_key_hash (window);
11904 ctk_window_get_key_hash (window);
11905}
11906
11907typedef struct _CtkWindowKeyEntry CtkWindowKeyEntry;
11908
11909struct _CtkWindowKeyEntry
11910{
11911 guint keyval;
11912 guint modifiers;
11913 guint is_mnemonic : 1;
11914};
11915
11916static void
11917window_key_entry_destroy (gpointer data)
11918{
11919 g_slice_free (CtkWindowKeyEntry, data)do { if (1) g_slice_free1 (sizeof (CtkWindowKeyEntry), (data)
); else (void) ((CtkWindowKeyEntry*) 0 == (data)); } while (0
)
;
11920}
11921
11922static void
11923add_to_key_hash (CtkWindow *window G_GNUC_UNUSED__attribute__ ((__unused__)),
11924 guint keyval,
11925 CdkModifierType modifiers,
11926 gboolean is_mnemonic,
11927 gpointer data)
11928{
11929 CtkKeyHash *key_hash = data;
11930
11931 CtkWindowKeyEntry *entry = g_slice_new (CtkWindowKeyEntry)((CtkWindowKeyEntry*) g_slice_alloc (sizeof (CtkWindowKeyEntry
)))
;
11932
11933 entry->keyval = keyval;
11934 entry->modifiers = modifiers;
11935 entry->is_mnemonic = is_mnemonic;
11936
11937 /* CtkAccelGroup stores lowercased accelerators. To deal
11938 * with this, if <Shift> was specified, uppercase.
11939 */
11940 if (modifiers & CDK_SHIFT_MASK)
11941 {
11942 if (keyval == CDK_KEY_Tab0xff09)
11943 keyval = CDK_KEY_ISO_Left_Tab0xfe20;
11944 else
11945 keyval = cdk_keyval_to_upper (keyval);
11946 }
11947
11948 _ctk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
11949}
11950
11951static CtkKeyHash *
11952ctk_window_get_key_hash (CtkWindow *window)
11953{
11954 CdkScreen *screen = ctk_window_check_screen (window);
11955 CtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, quark_ctk_window_key_hash);
11956
11957 if (key_hash)
11958 return key_hash;
11959
11960 key_hash = _ctk_key_hash_new (cdk_keymap_get_for_display (cdk_screen_get_display (screen)),
11961 (GDestroyNotify)window_key_entry_destroy);
11962 _ctk_window_keys_foreach (window, add_to_key_hash, key_hash);
11963 g_object_set_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, quark_ctk_window_key_hash, key_hash);
11964
11965 return key_hash;
11966}
11967
11968static void
11969ctk_window_free_key_hash (CtkWindow *window)
11970{
11971 CtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, quark_ctk_window_key_hash);
11972 if (key_hash)
11973 {
11974 _ctk_key_hash_free (key_hash);
11975 g_object_set_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, quark_ctk_window_key_hash, NULL((void*)0));
11976 }
11977}
11978
11979/**
11980 * ctk_window_activate_key:
11981 * @window: a #CtkWindow
11982 * @event: a #CdkEventKey
11983 *
11984 * Activates mnemonics and accelerators for this #CtkWindow. This is normally
11985 * called by the default ::key_press_event handler for toplevel windows,
11986 * however in some cases it may be useful to call this directly when
11987 * overriding the standard key handling for a toplevel window.
11988 *
11989 * Returns: %TRUE if a mnemonic or accelerator was found and activated.
11990 *
11991 * Since: 2.4
11992 */
11993gboolean
11994ctk_window_activate_key (CtkWindow *window,
11995 CdkEventKey *event)
11996{
11997 CtkKeyHash *key_hash;
11998 CtkWindowKeyEntry *found_entry = NULL((void*)0);
11999 gboolean enable_accels;
12000 gboolean enable_mnemonics;
12001
12002 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
12003 g_return_val_if_fail (event != NULL, FALSE)do { if ((event != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "event != NULL"); return
((0)); } } while (0)
;
12004
12005 key_hash = ctk_window_get_key_hash (window);
12006
12007 if (key_hash)
12008 {
12009 GSList *tmp_list;
12010 GSList *entries = _ctk_key_hash_lookup (key_hash,
12011 event->hardware_keycode,
12012 event->state,
12013 ctk_accelerator_get_default_mod_mask (),
12014 event->group);
12015
12016 g_object_get (ctk_widget_get_settings (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
),
12017 "ctk-enable-mnemonics", &enable_mnemonics,
12018 "ctk-enable-accels", &enable_accels,
12019 NULL((void*)0));
12020
12021 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
12022 {
12023 CtkWindowKeyEntry *entry = tmp_list->data;
12024 if (entry->is_mnemonic)
12025 {
12026 if( enable_mnemonics)
12027 {
12028 found_entry = entry;
12029 break;
12030 }
12031 }
12032 else
12033 {
12034 if (enable_accels && !found_entry)
12035 {
12036 found_entry = entry;
12037 }
12038 }
12039 }
12040
12041 g_slist_free (entries);
12042 }
12043
12044 if (found_entry)
12045 {
12046 if (found_entry->is_mnemonic)
12047 {
12048 if( enable_mnemonics)
12049 return ctk_window_mnemonic_activate (window, found_entry->keyval,
12050 found_entry->modifiers);
12051 }
12052 else
12053 {
12054 if (enable_accels)
12055 {
12056 if (ctk_accel_groups_activate (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, found_entry->keyval, found_entry->modifiers))
12057 return TRUE(!(0));
12058
12059 if (window->priv->application)
12060 {
12061 CtkWidget *focused_widget;
12062 CtkActionMuxer *muxer;
12063 CtkApplicationAccels *app_accels;
12064
12065 focused_widget = ctk_window_get_focus (window);
12066
12067 if (focused_widget)
12068 muxer = _ctk_widget_get_action_muxer (focused_widget, FALSE(0));
12069 else
12070 muxer = _ctk_widget_get_action_muxer (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
, FALSE(0));
12071
12072 if (muxer == NULL((void*)0))
12073 return FALSE(0);
12074
12075 app_accels = ctk_application_get_application_accels (window->priv->application);
12076 return ctk_application_accels_activate (app_accels,
12077 G_ACTION_GROUP (muxer)((((GActionGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((muxer)), ((g_action_group_get_type ()))))))
,
12078 found_entry->keyval, found_entry->modifiers);
12079 }
12080 }
12081 }
12082 }
12083
12084 return ctk_window_activate_menubar (window, event);
12085}
12086
12087static void
12088window_update_has_focus (CtkWindow *window)
12089{
12090 CtkWindowPrivate *priv = window->priv;
12091 CtkWidget *widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
12092 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
12093
12094 if (has_focus != priv->has_focus)
12095 {
12096 priv->has_focus = has_focus;
12097
12098 if (has_focus)
12099 {
12100 if (priv->focus_widget &&
12101 priv->focus_widget != widget &&
12102 !ctk_widget_has_focus (priv->focus_widget))
12103 do_focus_change (priv->focus_widget, TRUE(!(0)));
12104 }
12105 else
12106 {
12107 if (priv->focus_widget &&
12108 priv->focus_widget != widget &&
12109 ctk_widget_has_focus (priv->focus_widget))
12110 do_focus_change (priv->focus_widget, FALSE(0));
12111 }
12112 }
12113}
12114
12115/**
12116 * _ctk_window_set_is_active:
12117 * @window: a #CtkWindow
12118 * @is_active: %TRUE if the window is in the currently active toplevel
12119 *
12120 * Internal function that sets whether the #CtkWindow is part
12121 * of the currently active toplevel window (taking into account inter-process
12122 * embedding.)
12123 **/
12124void
12125_ctk_window_set_is_active (CtkWindow *window,
12126 gboolean is_active)
12127{
12128 CtkWindowPrivate *priv;
12129
12130 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12131
12132 priv = window->priv;
12133
12134 is_active = is_active != FALSE(0);
12135
12136 if (is_active != priv->is_active)
12137 {
12138 priv->is_active = is_active;
12139 window_update_has_focus (window);
12140
12141 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_IS_ACTIVE]);
12142 }
12143}
12144
12145/**
12146 * _ctk_window_set_is_toplevel:
12147 * @window: a #CtkWindow
12148 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
12149 * child of the root window); %FALSE if it is not (for example, for an
12150 * in-process, parented CtkPlug)
12151 *
12152 * Internal function used by #CtkPlug when it gets parented/unparented by a
12153 * #CtkSocket. This keeps the @window’s #CTK_WINDOW_TOPLEVEL flag in sync
12154 * with the global list of toplevel windows.
12155 */
12156void
12157_ctk_window_set_is_toplevel (CtkWindow *window,
12158 gboolean is_toplevel)
12159{
12160 CtkWidget *widget;
12161 CtkWidget *toplevel;
12162
12163 widget = CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
;
12164
12165 if (_ctk_widget_is_toplevel (widget))
12166 g_assert (g_slist_find (toplevel_list, window) != NULL)do { if (g_slist_find (toplevel_list, window) != ((void*)0)) ;
else g_assertion_message_expr ("Ctk", "ctkwindow.c", 12166, (
(const char*) (__func__)), "g_slist_find (toplevel_list, window) != NULL"
); } while (0)
;
12167 else
12168 g_assert (g_slist_find (toplevel_list, window) == NULL)do { if (g_slist_find (toplevel_list, window) == ((void*)0)) ;
else g_assertion_message_expr ("Ctk", "ctkwindow.c", 12168, (
(const char*) (__func__)), "g_slist_find (toplevel_list, window) == NULL"
); } while (0)
;
12169
12170 if (is_toplevel == _ctk_widget_is_toplevel (widget))
12171 return;
12172
12173 if (is_toplevel)
12174 {
12175 /* Pass through regular pathways of an embedded toplevel
12176 * to go through unmapping and hiding the widget before
12177 * becomming a toplevel again.
12178 *
12179 * We remain hidden after becomming toplevel in order to
12180 * avoid problems during an embedded toplevel's dispose cycle
12181 * (When a toplevel window is shown it tries to grab focus again,
12182 * this causes problems while disposing).
12183 */
12184 ctk_widget_hide (widget);
12185
12186 /* Save the toplevel this widget was previously anchored into before
12187 * propagating a hierarchy-changed.
12188 *
12189 * Usually this happens by way of ctk_widget_unparent() and we are
12190 * already unanchored at this point, just adding this clause incase
12191 * things happen differently.
12192 */
12193 toplevel = _ctk_widget_get_toplevel (widget);
12194 if (!_ctk_widget_is_toplevel (toplevel))
12195 toplevel = NULL((void*)0);
12196
12197 _ctk_widget_set_is_toplevel (widget, TRUE(!(0)));
12198
12199 /* When a window becomes toplevel after being embedded and anchored
12200 * into another window we need to unset its anchored flag so that
12201 * the hierarchy changed signal kicks in properly.
12202 */
12203 _ctk_widget_set_anchored (widget, FALSE(0));
12204 _ctk_widget_propagate_hierarchy_changed (widget, toplevel);
12205
12206 toplevel_list = g_slist_prepend (toplevel_list, window);
12207 }
12208 else
12209 {
12210 _ctk_widget_set_is_toplevel (widget, FALSE(0));
12211 toplevel_list = g_slist_remove (toplevel_list, window);
12212 _ctk_widget_propagate_hierarchy_changed (widget, widget);
12213 }
12214 ctk_window_update_debugging ();
12215}
12216
12217/**
12218 * _ctk_window_set_has_toplevel_focus:
12219 * @window: a #CtkWindow
12220 * @has_toplevel_focus: %TRUE if the in
12221 *
12222 * Internal function that sets whether the keyboard focus for the
12223 * toplevel window (taking into account inter-process embedding.)
12224 **/
12225void
12226_ctk_window_set_has_toplevel_focus (CtkWindow *window,
12227 gboolean has_toplevel_focus)
12228{
12229 CtkWindowPrivate *priv;
12230
12231 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12232
12233 priv = window->priv;
12234
12235 has_toplevel_focus = has_toplevel_focus != FALSE(0);
12236
12237 if (has_toplevel_focus != priv->has_toplevel_focus)
12238 {
12239 priv->has_toplevel_focus = has_toplevel_focus;
12240 window_update_has_focus (window);
12241
12242 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_HAS_TOPLEVEL_FOCUS]);
12243 }
12244}
12245
12246/**
12247 * ctk_window_set_auto_startup_notification:
12248 * @setting: %TRUE to automatically do startup notification
12249 *
12250 * By default, after showing the first #CtkWindow, CTK+ calls
12251 * cdk_notify_startup_complete(). Call this function to disable
12252 * the automatic startup notification. You might do this if your
12253 * first window is a splash screen, and you want to delay notification
12254 * until after your real main window has been shown, for example.
12255 *
12256 * In that example, you would disable startup notification
12257 * temporarily, show your splash screen, then re-enable it so that
12258 * showing the main window would automatically result in notification.
12259 *
12260 * Since: 2.2
12261 **/
12262void
12263ctk_window_set_auto_startup_notification (gboolean setting)
12264{
12265 disable_startup_notification = !setting;
12266}
12267
12268/**
12269 * ctk_window_get_window_type:
12270 * @window: a #CtkWindow
12271 *
12272 * Gets the type of the window. See #CtkWindowType.
12273 *
12274 * Returns: the type of the window
12275 *
12276 * Since: 2.20
12277 **/
12278CtkWindowType
12279ctk_window_get_window_type (CtkWindow *window)
12280{
12281 g_return_val_if_fail (CTK_IS_WINDOW (window), CTK_WINDOW_TOPLEVEL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (CTK_WINDOW_TOPLEVEL); }
} while (0)
;
12282
12283 return window->priv->type;
12284}
12285
12286/**
12287 * ctk_window_get_mnemonics_visible:
12288 * @window: a #CtkWindow
12289 *
12290 * Gets the value of the #CtkWindow:mnemonics-visible property.
12291 *
12292 * Returns: %TRUE if mnemonics are supposed to be visible
12293 * in this window.
12294 *
12295 * Since: 2.20
12296 */
12297gboolean
12298ctk_window_get_mnemonics_visible (CtkWindow *window)
12299{
12300 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
12301
12302 return window->priv->mnemonics_visible;
12303}
12304
12305/**
12306 * ctk_window_set_mnemonics_visible:
12307 * @window: a #CtkWindow
12308 * @setting: the new value
12309 *
12310 * Sets the #CtkWindow:mnemonics-visible property.
12311 *
12312 * Since: 2.20
12313 */
12314void
12315ctk_window_set_mnemonics_visible (CtkWindow *window,
12316 gboolean setting)
12317{
12318 CtkWindowPrivate *priv;
12319
12320 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12321
12322 priv = window->priv;
12323
12324 setting = setting != FALSE(0);
12325
12326 if (priv->mnemonics_visible != setting)
12327 {
12328 priv->mnemonics_visible = setting;
12329 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_MNEMONICS_VISIBLE]);
12330 }
12331
12332 if (priv->mnemonics_display_timeout_id)
12333 {
12334 g_source_remove (priv->mnemonics_display_timeout_id);
12335 priv->mnemonics_display_timeout_id = 0;
12336 }
12337
12338 priv->mnemonics_visible_set = TRUE(!(0));
12339}
12340
12341static gboolean
12342schedule_mnemonics_visible_cb (gpointer data)
12343{
12344 CtkWindow *window = data;
12345
12346 window->priv->mnemonics_display_timeout_id = 0;
12347
12348 ctk_window_set_mnemonics_visible (window, TRUE(!(0)));
12349
12350 return FALSE(0);
12351}
12352
12353void
12354_ctk_window_schedule_mnemonics_visible (CtkWindow *window)
12355{
12356 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12357
12358 if (window->priv->mnemonics_display_timeout_id)
12359 return;
12360
12361 window->priv->mnemonics_display_timeout_id =
12362 cdk_threads_add_timeout (MNEMONICS_DELAY300, schedule_mnemonics_visible_cb, window);
12363 g_source_set_name_by_id (window->priv->mnemonics_display_timeout_id, "[ctk+] schedule_mnemonics_visible_cb");
12364}
12365
12366/**
12367 * ctk_window_get_focus_visible:
12368 * @window: a #CtkWindow
12369 *
12370 * Gets the value of the #CtkWindow:focus-visible property.
12371 *
12372 * Returns: %TRUE if “focus rectangles” are supposed to be visible
12373 * in this window.
12374 *
12375 * Since: 3.2
12376 */
12377gboolean
12378ctk_window_get_focus_visible (CtkWindow *window)
12379{
12380 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
12381
12382 return window->priv->focus_visible;
12383}
12384
12385/**
12386 * ctk_window_set_focus_visible:
12387 * @window: a #CtkWindow
12388 * @setting: the new value
12389 *
12390 * Sets the #CtkWindow:focus-visible property.
12391 *
12392 * Since: 3.2
12393 */
12394void
12395ctk_window_set_focus_visible (CtkWindow *window,
12396 gboolean setting)
12397{
12398 CtkWindowPrivate *priv;
12399
12400 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12401
12402 priv = window->priv;
12403
12404 setting = setting != FALSE(0);
12405
12406 if (priv->focus_visible != setting)
12407 {
12408 priv->focus_visible = setting;
12409 g_object_notify_by_pspec (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, window_props[PROP_FOCUS_VISIBLE]);
12410 }
12411}
12412
12413void
12414_ctk_window_get_wmclass (CtkWindow *window,
12415 gchar **wmclass_name,
12416 gchar **wmclass_class)
12417{
12418 CtkWindowPrivate *priv = window->priv;
12419
12420 *wmclass_name = priv->wmclass_name;
12421 *wmclass_class = priv->wmclass_class;
12422}
12423
12424/**
12425 * ctk_window_set_has_user_ref_count:
12426 * @window: a #CtkWindow
12427 * @setting: the new value
12428 *
12429 * Tells CTK+ whether to drop its extra reference to the window
12430 * when ctk_widget_destroy() is called.
12431 *
12432 * This function is only exported for the benefit of language
12433 * bindings which may need to keep the window alive until their
12434 * wrapper object is garbage collected. There is no justification
12435 * for ever calling this function in an application.
12436 *
12437 * Since: 3.0
12438 */
12439void
12440ctk_window_set_has_user_ref_count (CtkWindow *window,
12441 gboolean setting)
12442{
12443 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12444
12445 window->priv->has_user_ref_count = setting;
12446}
12447
12448static void
12449ensure_state_flag_backdrop (CtkWidget *widget)
12450{
12451 CdkWindow *window;
12452 gboolean window_focused = TRUE(!(0));
12453
12454 window = _ctk_widget_get_window (widget);
12455
12456 window_focused = cdk_window_get_state (window) & CDK_WINDOW_STATE_FOCUSED;
12457
12458 if (!window_focused)
12459 ctk_widget_set_state_flags (widget, CTK_STATE_FLAG_BACKDROP, FALSE(0));
12460 else
12461 ctk_widget_unset_state_flags (widget, CTK_STATE_FLAG_BACKDROP);
12462}
12463
12464void
12465_ctk_window_get_shadow_width (CtkWindow *window,
12466 CtkBorder *border)
12467{
12468 get_shadow_width (window, border);
12469}
12470
12471void
12472_ctk_window_add_popover (CtkWindow *window,
12473 CtkWidget *popover,
12474 CtkWidget *parent,
12475 gboolean clamp_allocation)
12476{
12477 CtkWindowPrivate *priv;
12478 CtkWindowPopover *data;
12479 AtkObject *accessible;
12480
12481 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12482 g_return_if_fail (CTK_IS_WIDGET (popover))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((popover)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (popover)"); return; } } while (0)
;
12483 g_return_if_fail (CTK_IS_WIDGET (parent))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((parent)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (parent)"); return; } } while (0)
;
12484 g_return_if_fail (_ctk_widget_get_parent (popover) == NULL)do { if ((_ctk_widget_get_parent (popover) == ((void*)0))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "_ctk_widget_get_parent (popover) == NULL"); return; } } while
(0)
;
12485 g_return_if_fail (ctk_widget_is_ancestor (parent, CTK_WIDGET (window)))do { if ((ctk_widget_is_ancestor (parent, ((((CtkWidget*) (void
*) g_type_check_instance_cast ((GTypeInstance*) ((window)), (
(ctk_widget_get_type ()))))))))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "ctk_widget_is_ancestor (parent, CTK_WIDGET (window))"
); return; } } while (0)
;
12486
12487 priv = window->priv;
12488
12489 if (_ctk_window_has_popover (window, popover))
12490 return;
12491
12492 data = g_new0 (CtkWindowPopover, 1)((CtkWindowPopover *) g_malloc0_n ((1), sizeof (CtkWindowPopover
)))
;
12493 data->widget = popover;
12494 data->parent = parent;
12495 data->clamp_allocation = !!clamp_allocation;
12496 priv->popovers = g_list_prepend (priv->popovers, data);
12497
12498 if (_ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
12499 popover_realize (popover, data, window);
12500
12501 ctk_widget_set_parent (popover, CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
12502
12503 accessible = ctk_widget_get_accessible (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
12504 _ctk_container_accessible_add_child (CTK_CONTAINER_ACCESSIBLE (accessible)((((CtkContainerAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((accessible)), ((ctk_container_accessible_get_type
()))))))
,
12505 ctk_widget_get_accessible (popover), -1);
12506}
12507
12508void
12509_ctk_window_remove_popover (CtkWindow *window,
12510 CtkWidget *popover)
12511{
12512 CtkWindowPrivate *priv;
12513 CtkWindowPopover *data;
12514 AtkObject *accessible;
12515
12516 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12517 g_return_if_fail (CTK_IS_WIDGET (popover))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((popover)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (popover)"); return; } } while (0)
;
12518
12519 priv = window->priv;
12520
12521 data = _ctk_window_has_popover (window, popover);
12522
12523 if (!data)
12524 return;
12525
12526 g_object_ref (popover)((__typeof__ (popover)) (g_object_ref) (popover));
12527 ctk_widget_unparent (popover);
12528
12529 popover_unmap (popover, data);
12530
12531 if (_ctk_widget_get_realized (CTK_WIDGET (popover)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((popover)), ((ctk_widget_get_type ()))))))
))
12532 popover_unrealize (popover, data, window);
12533
12534 priv->popovers = g_list_remove (priv->popovers, data);
12535
12536 accessible = ctk_widget_get_accessible (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
12537 _ctk_container_accessible_remove_child (CTK_CONTAINER_ACCESSIBLE (accessible)((((CtkContainerAccessible*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((accessible)), ((ctk_container_accessible_get_type
()))))))
,
12538 ctk_widget_get_accessible (popover), -1);
12539 popover_destroy (data);
12540 g_object_unref (popover);
12541}
12542
12543void
12544_ctk_window_set_popover_position (CtkWindow *window,
12545 CtkWidget *popover,
12546 CtkPositionType pos,
12547 const cairo_rectangle_int_t *rect)
12548{
12549 gboolean need_resize;
12550 gboolean need_move;
12551 CtkWindowPopover *data;
12552
12553 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12554 g_return_if_fail (CTK_IS_WIDGET (popover))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((popover)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (popover)"); return; } } while (0)
;
12555
12556 data = _ctk_window_has_popover (window, popover);
12557
12558 if (!data)
12559 {
12560 g_warning ("Widget %s(%p) is not a popover of window %s(%p)",
12561 ctk_widget_get_name (popover), popover,
12562 ctk_widget_get_name (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
), window);
12563 return;
12564 }
12565
12566
12567 /* Don't queue a resize if the position as well as the size are the same */
12568 need_move = data->pos != pos ||
12569 data->rect.x != rect->x ||
12570 data->rect.y != rect->y;
12571
12572 need_resize = data->pos != pos ||
12573 data->rect.width != rect->width ||
12574 data->rect.height != rect->height;
12575
12576 data->rect = *rect;
12577 data->pos = pos;
12578
12579 if (ctk_widget_is_visible (popover) && !data->window &&
12580 ctk_widget_get_realized (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
))
12581 {
12582 popover_realize (popover, data, window);
12583 popover_map (popover, data);
12584 }
12585
12586 if (need_resize)
12587 {
12588 ctk_widget_queue_resize (popover);
12589 }
12590 else if (need_move)
12591 {
12592 cairo_rectangle_int_t new_size;
12593 popover_get_rect (data, window, &new_size);
12594 cdk_window_move (data->window, new_size.x, new_size.y);
12595 }
12596}
12597
12598void
12599_ctk_window_get_popover_position (CtkWindow *window,
12600 CtkWidget *popover,
12601 CtkPositionType *pos,
12602 cairo_rectangle_int_t *rect)
12603{
12604 CtkWindowPopover *data;
12605
12606 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12607 g_return_if_fail (CTK_IS_WIDGET (popover))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((popover)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (popover)"); return; } } while (0)
;
12608
12609 data = _ctk_window_has_popover (window, popover);
12610
12611 if (!data)
12612 {
12613 g_warning ("Widget %s(%p) is not a popover of window %s(%p)",
12614 ctk_widget_get_name (popover), popover,
12615 ctk_widget_get_name (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
), window);
12616 return;
12617 }
12618
12619 if (pos)
12620 *pos = data->pos;
12621
12622 if (rect)
12623 *rect = data->rect;
12624}
12625
12626/*<private>
12627 * _ctk_window_get_popover_parent:
12628 * @window: A #CtkWindow
12629 * @popover: A popover #CtkWidget
12630 *
12631 * Returns the conceptual parent of this popover, the real
12632 * parent will always be @window.
12633 *
12634 * Returns: (nullable): The conceptual parent widget, or %NULL.
12635 **/
12636CtkWidget *
12637_ctk_window_get_popover_parent (CtkWindow *window,
12638 CtkWidget *popover)
12639{
12640 CtkWindowPopover *data;
12641
12642 g_return_val_if_fail (CTK_IS_WINDOW (window), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
12643 g_return_val_if_fail (CTK_IS_WIDGET (popover), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((popover)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WIDGET (popover)"); return (((void*)0)); } } while
(0)
;
12644
12645 data = _ctk_window_has_popover (window, popover);
12646
12647 if (data && data->parent)
12648 return data->parent;
12649
12650 return NULL((void*)0);
12651}
12652
12653/*<private>
12654 * _ctk_window_is_popover_widget:
12655 * @window: A #CtkWindow
12656 * @possible_popover: A possible popover of @window
12657 *
12658 * Returns #TRUE if @possible_popover is a popover of @window.
12659 *
12660 * Returns: Whether the widget is a popover of @window
12661 **/
12662gboolean
12663_ctk_window_is_popover_widget (CtkWindow *window,
12664 CtkWidget *possible_popover)
12665{
12666 g_return_val_if_fail (CTK_IS_WINDOW (window), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return ((0)); } } while (0)
;
12667 g_return_val_if_fail (CTK_IS_WIDGET (possible_popover), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((possible_popover)); GType __t = ((ctk_widget_get_type ()
)); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "CTK_IS_WIDGET (possible_popover)"); return
((0)); } } while (0)
;
12668
12669 return _ctk_window_has_popover (window, possible_popover) != NULL((void*)0);
12670}
12671
12672void
12673_ctk_window_raise_popover (CtkWindow *window,
12674 CtkWidget *widget)
12675{
12676 CtkWindowPrivate *priv = window->priv;
12677 GList *link;
12678
12679 for (link = priv->popovers; link; link = link->next)
12680 {
12681 CtkWindowPopover *popover = link->data;
12682
12683 if (popover->widget != widget)
12684 continue;
12685
12686 priv->popovers = g_list_remove_link (priv->popovers, link);
12687 priv->popovers = g_list_append (priv->popovers, link->data);
12688 g_list_free (link);
12689 break;
12690 }
12691 ctk_window_restack_popovers (window);
12692}
12693
12694static CtkWidget *inspector_window = NULL((void*)0);
12695
12696static guint ctk_window_update_debugging_id;
12697
12698static void set_warn_again (gboolean warn);
12699
12700static void
12701warn_response (CtkDialog *dialog,
12702 gint response)
12703{
12704 CtkWidget *check;
12705 gboolean remember;
12706
12707 check = g_object_get_data (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "check");
12708 remember = ctk_toggle_button_get_active (CTK_TOGGLE_BUTTON (check)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((check)), ((ctk_toggle_button_get_type ()))))))
);
12709
12710 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
12711 g_object_set_data (G_OBJECT (inspector_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inspector_window)), (((GType) ((20) << (2))))))))
, "warning_dialog", NULL((void*)0));
12712 if (response == CTK_RESPONSE_NO)
12713 {
12714 CtkWidget *window;
12715
12716 if (ctk_window_update_debugging_id)
12717 {
12718 g_source_remove (ctk_window_update_debugging_id);
12719 ctk_window_update_debugging_id = 0;
12720 }
12721
12722 /* Steal reference into temp variable, so not to mess up with
12723 * inspector_window during ctk_widget_destroy().
12724 */
12725 window = inspector_window;
12726 inspector_window = NULL((void*)0);
12727 ctk_widget_destroy (window);
12728 }
12729 else
12730 {
12731 set_warn_again (!remember);
12732 }
12733}
12734
12735static gboolean
12736update_debugging (gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
12737{
12738 ctk_inspector_window_rescan (inspector_window);
12739 ctk_window_update_debugging_id = 0;
12740 return G_SOURCE_REMOVE(0);
12741}
12742
12743static void
12744ctk_window_update_debugging (void)
12745{
12746 if (inspector_window &&
12747 ctk_window_update_debugging_id == 0)
12748 {
12749 ctk_window_update_debugging_id = cdk_threads_add_idle (update_debugging, NULL((void*)0));
12750 g_source_set_name_by_id (ctk_window_update_debugging_id, "[ctk+] ctk_window_update_debugging");
12751 }
12752}
12753
12754static void
12755ctk_window_set_debugging (gboolean enable,
12756 gboolean select,
12757 gboolean warn)
12758{
12759 CtkWidget *dialog = NULL((void*)0);
12760 CtkWidget *area;
12761 CtkWidget *check;
12762
12763 if (inspector_window == NULL((void*)0))
12764 {
12765 ctk_inspector_init ();
12766 inspector_window = ctk_inspector_window_new ();
12767 g_signal_connect (inspector_window, "delete-event",g_signal_connect_data ((inspector_window), ("delete-event"), (
((GCallback) (ctk_widget_hide_on_delete))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
12768 G_CALLBACK (ctk_widget_hide_on_delete), NULL)g_signal_connect_data ((inspector_window), ("delete-event"), (
((GCallback) (ctk_widget_hide_on_delete))), (((void*)0)), ((void
*)0), (GConnectFlags) 0)
;
12769
12770 if (warn)
12771 {
12772 dialog = ctk_message_dialog_new (CTK_WINDOW (inspector_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inspector_window)), ((ctk_window_get_type ()))))))
,
12773 CTK_DIALOG_MODAL|CTK_DIALOG_DESTROY_WITH_PARENT,
12774 CTK_MESSAGE_QUESTION,
12775 CTK_BUTTONS_NONE,
12776 _("Do you want to use CTK+ Inspector?")((char *) g_dgettext ("ctk30", "Do you want to use CTK+ Inspector?"
))
);
12777 ctk_message_dialog_format_secondary_text (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
,
12778 _("CTK+ Inspector is an interactive debugger that lets you explore and "((char *) g_dgettext ("ctk30", "CTK+ Inspector is an interactive debugger that lets you explore and "
"modify the internals of any CTK+ application. Using it may cause the "
"application to break or crash."))
12779 "modify the internals of any CTK+ application. Using it may cause the "((char *) g_dgettext ("ctk30", "CTK+ Inspector is an interactive debugger that lets you explore and "
"modify the internals of any CTK+ application. Using it may cause the "
"application to break or crash."))
12780 "application to break or crash.")((char *) g_dgettext ("ctk30", "CTK+ Inspector is an interactive debugger that lets you explore and "
"modify the internals of any CTK+ application. Using it may cause the "
"application to break or crash."))
);
12781
12782 area = ctk_message_dialog_get_message_area (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
);
12783 check = ctk_check_button_new_with_label (_("Don't show this message again")((char *) g_dgettext ("ctk30", "Don't show this message again"
))
);
12784 ctk_widget_set_margin_start (check, 10);
12785 ctk_widget_show (check);
12786 ctk_container_add (CTK_CONTAINER (area)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((area)), ((ctk_container_get_type ()))))))
, check);
12787 g_object_set_data (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "check", check);
12788 ctk_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, _("_Cancel")((char *) g_dgettext ("ctk30", "_Cancel")), CTK_RESPONSE_NO);
12789 ctk_dialog_add_button (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
, _("_OK")((char *) g_dgettext ("ctk30", "_OK")), CTK_RESPONSE_YES);
12790 g_signal_connect (dialog, "response", G_CALLBACK (warn_response), NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
warn_response))), (((void*)0)), ((void*)0), (GConnectFlags) 0
)
;
12791 g_object_set_data (G_OBJECT (inspector_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inspector_window)), (((GType) ((20) << (2))))))))
, "warning_dialog", dialog);
12792 }
12793 }
12794
12795 dialog = g_object_get_data (G_OBJECT (inspector_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inspector_window)), (((GType) ((20) << (2))))))))
, "warning_dialog");
12796
12797 if (enable)
12798 {
12799 ctk_window_present (CTK_WINDOW (inspector_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inspector_window)), ((ctk_window_get_type ()))))))
);
12800
12801 if (dialog)
12802 ctk_widget_show (dialog);
12803
12804 if (select)
12805 ctk_inspector_window_select_widget_under_pointer (CTK_INSPECTOR_WINDOW (inspector_window)((((CtkInspectorWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((inspector_window)), ((ctk_inspector_window_get_type
()))))))
);
12806 }
12807 else
12808 {
12809 if (dialog)
12810 ctk_widget_hide (dialog);
12811 ctk_widget_hide (inspector_window);
12812 }
12813}
12814
12815/**
12816 * ctk_window_set_interactive_debugging:
12817 * @enable: %TRUE to enable interactive debugging
12818 *
12819 * Opens or closes the [interactive debugger][interactive-debugging],
12820 * which offers access to the widget hierarchy of the application
12821 * and to useful debugging tools.
12822 *
12823 * Since: 3.14
12824 */
12825void
12826ctk_window_set_interactive_debugging (gboolean enable)
12827{
12828 ctk_window_set_debugging (enable, FALSE(0), FALSE(0));
12829}
12830
12831static gboolean
12832inspector_keybinding_enabled (gboolean *warn)
12833{
12834 GSettingsSchema *schema;
12835 GSettings *settings;
12836 gboolean enabled;
12837
12838 enabled = FALSE(0);
12839 *warn = FALSE(0);
12840
12841 schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
12842 "org.ctk.Settings.Debug",
12843 TRUE(!(0)));
12844
12845 if (schema)
12846 {
12847 settings = g_settings_new_full (schema, NULL((void*)0), NULL((void*)0));
12848 enabled = g_settings_get_boolean (settings, "enable-inspector-keybinding");
12849 *warn = g_settings_get_boolean (settings, "inspector-warning");
12850 g_object_unref (settings);
12851 g_settings_schema_unref (schema);
12852 }
12853
12854 return enabled;
12855}
12856
12857static void
12858set_warn_again (gboolean warn)
12859{
12860 GSettingsSchema *schema;
12861 GSettings *settings;
12862
12863 schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
12864 "org.ctk.Settings.Debug",
12865 TRUE(!(0)));
12866
12867 if (schema)
12868 {
12869 settings = g_settings_new_full (schema, NULL((void*)0), NULL((void*)0));
12870 g_settings_set_boolean (settings, "inspector-warning", warn);
12871 g_object_unref (settings);
12872 g_settings_schema_unref (schema);
12873 }
12874}
12875
12876static gboolean
12877ctk_window_enable_debugging (CtkWindow *window G_GNUC_UNUSED__attribute__ ((__unused__)),
12878 gboolean toggle)
12879{
12880 gboolean warn;
12881
12882 if (!inspector_keybinding_enabled (&warn))
12883 return FALSE(0);
12884
12885 if (toggle)
12886 {
12887 if (CTK_IS_WIDGET (inspector_window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(inspector_window)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
&&
12888 ctk_widget_is_visible (inspector_window))
12889 ctk_window_set_debugging (FALSE(0), FALSE(0), FALSE(0));
12890 else
12891 ctk_window_set_debugging (TRUE(!(0)), FALSE(0), warn);
12892 }
12893 else
12894 ctk_window_set_debugging (TRUE(!(0)), TRUE(!(0)), warn);
12895
12896 return TRUE(!(0));
12897}
12898
12899void
12900ctk_window_set_use_subsurface (CtkWindow *window,
12901 gboolean use_subsurface)
12902{
12903 CtkWindowPrivate *priv = window->priv;
12904
12905 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12906 g_return_if_fail (!_ctk_widget_get_realized (CTK_WIDGET (window)))do { if ((!_ctk_widget_get_realized (((((CtkWidget*) (void *)
g_type_check_instance_cast ((GTypeInstance*) ((window)), ((ctk_widget_get_type
()))))))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "!_ctk_widget_get_realized (CTK_WIDGET (window))"
); return; } } while (0)
;
12907
12908 priv->use_subsurface = use_subsurface;
12909}
12910
12911void
12912ctk_window_set_hardcoded_window (CtkWindow *window,
12913 CdkWindow *cdk_window)
12914{
12915 CtkWindowPrivate *priv = window->priv;
12916
12917 g_return_if_fail (CTK_IS_WINDOW (window))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((window)); GType __t = ((ctk_window_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_WINDOW (window)"); return; } } while (0)
;
12918 g_return_if_fail (!_ctk_widget_get_realized (CTK_WIDGET (window)))do { if ((!_ctk_widget_get_realized (((((CtkWidget*) (void *)
g_type_check_instance_cast ((GTypeInstance*) ((window)), ((ctk_widget_get_type
()))))))))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "!_ctk_widget_get_realized (CTK_WIDGET (window))"
); return; } } while (0)
;
12919
12920 g_set_object (&priv->hardcoded_window, cdk_window)(__extension__ ({ _Static_assert (sizeof *(&priv->hardcoded_window
) == sizeof (cdk_window), "Expression evaluates to false"); union
{ char *in; GObject **out; } _object_ptr; _object_ptr.in = (
char *) (&priv->hardcoded_window); (void) (0 ? *(&
priv->hardcoded_window) = (cdk_window), (0) : (0)); (g_set_object
) (_object_ptr.out, (GObject *) cdk_window); }))
;
12921}
12922
12923#ifdef CDK_WINDOWING_WAYLAND
12924typedef struct {
12925 CtkWindow *window;
12926 CtkWindowHandleExported callback;
12927 gpointer user_data;
12928} WaylandWindowHandleExportedData;
12929
12930static void
12931wayland_window_handle_exported (CdkWindow *window G_GNUC_UNUSED__attribute__ ((__unused__)),
12932 const char *wayland_handle_str,
12933 gpointer user_data)
12934{
12935 WaylandWindowHandleExportedData *data = user_data;
12936 char *handle_str;
12937
12938 handle_str = g_strdup_printf ("wayland:%s", wayland_handle_str);
12939 data->callback (data->window, handle_str, data->user_data);
12940 g_free (handle_str);
12941}
12942#endif
12943
12944gboolean
12945ctk_window_export_handle (CtkWindow *window,
12946 CtkWindowHandleExported callback,
12947 gpointer user_data)
12948{
12949
12950#ifdef CDK_WINDOWING_X11
12951 if (CDK_IS_X11_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
))); GType __t = ((cdk_x11_display_get_type())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
12952 {
12953 CdkWindow *cdk_window = ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
12954 char *handle_str;
12955 guint32 xid = (guint32) cdk_x11_window_get_xid (cdk_window);
12956
12957 handle_str = g_strdup_printf ("x11:%x", xid);
12958 callback (window, handle_str, user_data);
12959
12960 return TRUE(!(0));
12961 }
12962#endif
12963#ifdef CDK_WINDOWING_WAYLAND
12964 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
))); GType __t = ((cdk_wayland_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
12965 {
12966 CdkWindow *cdk_window = ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
12967 WaylandWindowHandleExportedData *data;
12968
12969 data = g_new0 (WaylandWindowHandleExportedData, 1)((WaylandWindowHandleExportedData *) g_malloc0_n ((1), sizeof
(WaylandWindowHandleExportedData)))
;
12970 data->window = window;
12971 data->callback = callback;
12972 data->user_data = user_data;
12973
12974 if (!cdk_wayland_window_export_handle (cdk_window,
12975 wayland_window_handle_exported,
12976 data,
12977 g_free))
12978 {
12979 g_free (data);
12980 return FALSE(0);
12981 }
12982 else
12983 {
12984 return TRUE(!(0));
12985 }
12986 }
12987#endif
12988
12989 g_warning ("Couldn't export handle, unsupported windowing system");
12990
12991 return FALSE(0);
12992}
12993
12994void
12995ctk_window_unexport_handle (CtkWindow *window)
12996{
12997#ifdef CDK_WINDOWING_WAYLAND
12998 if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (CTK_WIDGET (window)))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(ctk_widget_get_display (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((ctk_widget_get_type ()))))))
))); GType __t = ((cdk_wayland_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
12999 {
13000 CdkWindow *cdk_window = ctk_widget_get_window (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
13001
13002 cdk_wayland_window_unexport_handle (cdk_window);
13003 }
13004#endif
13005}