1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2020 Red Hat
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 #include "config.h"
20
21 #include "gdktoplevellayout.h"
22
23 #include "gdkmonitor.h"
24
25 /**
26 * GdkToplevelLayout:
27 *
28 * The `GdkToplevelLayout` struct contains information that
29 * is necessary to present a sovereign window on screen.
30 *
31 * The `GdkToplevelLayout` struct is necessary for using
32 * [method@Gdk.Toplevel.present].
33 *
34 * Toplevel surfaces are sovereign windows that can be presented
35 * to the user in various states (maximized, on all workspaces,
36 * etc).
37 */
38 struct _GdkToplevelLayout
39 {
40 /* < private >*/
41 grefcount ref_count;
42
43 guint resizable : 1;
44
45 guint maximized_valid : 1;
46 guint maximized : 1;
47 guint fullscreen_valid : 1;
48 guint fullscreen : 1;
49 GdkMonitor *fullscreen_monitor;
50 };
51
G_DEFINE_BOXED_TYPE(GdkToplevelLayout,gdk_toplevel_layout,gdk_toplevel_layout_ref,gdk_toplevel_layout_unref)52 G_DEFINE_BOXED_TYPE (GdkToplevelLayout, gdk_toplevel_layout,
53 gdk_toplevel_layout_ref,
54 gdk_toplevel_layout_unref)
55
56 /**
57 * gdk_toplevel_layout_new: (constructor)
58 *
59 * Create a toplevel layout description.
60 *
61 * Used together with gdk_toplevel_present() to describe
62 * how a toplevel surface should be placed and behave on-screen.
63 *
64 * The size is in ”application pixels”, not
65 * ”device pixels” (see gdk_surface_get_scale_factor()).
66 *
67 * Returns: (transfer full): newly created instance of `GdkToplevelLayout`
68 */
69 GdkToplevelLayout *
70 gdk_toplevel_layout_new (void)
71 {
72 GdkToplevelLayout *layout;
73
74 layout = g_new0 (GdkToplevelLayout, 1);
75 g_ref_count_init (&layout->ref_count);
76 layout->resizable = TRUE;
77 layout->maximized_valid = FALSE;
78 layout->maximized = FALSE;
79 layout->fullscreen_valid = FALSE;
80 layout->fullscreen = FALSE;
81 layout->fullscreen_monitor = NULL;
82
83 return layout;
84 }
85
86 /**
87 * gdk_toplevel_layout_ref:
88 * @layout: a `GdkToplevelLayout`
89 *
90 * Increases the reference count of @layout.
91 *
92 * Returns: the same @layout
93 */
94 GdkToplevelLayout *
gdk_toplevel_layout_ref(GdkToplevelLayout * layout)95 gdk_toplevel_layout_ref (GdkToplevelLayout *layout)
96 {
97 g_ref_count_inc (&layout->ref_count);
98 return layout;
99 }
100
101 /**
102 * gdk_toplevel_layout_unref:
103 * @layout: a `GdkToplevelLayout`
104 *
105 * Decreases the reference count of @layout.
106 */
107 void
gdk_toplevel_layout_unref(GdkToplevelLayout * layout)108 gdk_toplevel_layout_unref (GdkToplevelLayout *layout)
109 {
110 if (g_ref_count_dec (&layout->ref_count))
111 {
112 g_clear_object (&layout->fullscreen_monitor);
113 g_free (layout);
114 }
115 }
116
117 /**
118 * gdk_toplevel_layout_copy:
119 * @layout: a `GdkToplevelLayout`
120 *
121 * Create a new `GdkToplevelLayout` and copy the contents of @layout into it.
122 *
123 * Returns: (transfer full): a copy of @layout.
124 */
125 GdkToplevelLayout *
gdk_toplevel_layout_copy(GdkToplevelLayout * layout)126 gdk_toplevel_layout_copy (GdkToplevelLayout *layout)
127 {
128 GdkToplevelLayout *new_layout;
129
130 new_layout = g_new0 (GdkToplevelLayout, 1);
131 g_ref_count_init (&new_layout->ref_count);
132
133 new_layout->resizable = layout->resizable;
134 new_layout->maximized_valid = layout->maximized_valid;
135 new_layout->maximized = layout->maximized;
136 new_layout->fullscreen_valid = layout->fullscreen_valid;
137 new_layout->fullscreen = layout->fullscreen;
138 if (layout->fullscreen_monitor)
139 new_layout->fullscreen_monitor = g_object_ref (layout->fullscreen_monitor);
140
141 return new_layout;
142 }
143
144 /**
145 * gdk_toplevel_layout_equal:
146 * @layout: a `GdkToplevelLayout`
147 * @other: another `GdkToplevelLayout`
148 *
149 * Check whether @layout and @other has identical layout properties.
150 *
151 * Returns: %TRUE if @layout and @other have identical layout properties,
152 * otherwise %FALSE.
153 */
154 gboolean
gdk_toplevel_layout_equal(GdkToplevelLayout * layout,GdkToplevelLayout * other)155 gdk_toplevel_layout_equal (GdkToplevelLayout *layout,
156 GdkToplevelLayout *other)
157 {
158 g_return_val_if_fail (layout, FALSE);
159 g_return_val_if_fail (other, FALSE);
160
161 return layout->resizable == other->resizable &&
162 layout->maximized_valid == other->maximized_valid &&
163 layout->maximized == other->maximized &&
164 layout->fullscreen_valid == other->fullscreen_valid &&
165 layout->fullscreen == other->fullscreen &&
166 layout->fullscreen_monitor == other->fullscreen_monitor;
167 }
168
169 /**
170 * gdk_toplevel_layout_set_resizable:
171 * @layout: a `GdkToplevelLayout`
172 * @resizable: %TRUE to allow resizing
173 *
174 * Sets whether the layout should allow the user
175 * to resize the surface after it has been presented.
176 */
177 void
gdk_toplevel_layout_set_resizable(GdkToplevelLayout * layout,gboolean resizable)178 gdk_toplevel_layout_set_resizable (GdkToplevelLayout *layout,
179 gboolean resizable)
180 {
181 layout->resizable = resizable;
182 }
183
184 /**
185 * gdk_toplevel_layout_get_resizable:
186 * @layout: a `GdkToplevelLayout`
187 *
188 * Returns whether the layout should allow the user
189 * to resize the surface.
190 *
191 * Returns: %TRUE if the layout is resizable
192 */
193 gboolean
gdk_toplevel_layout_get_resizable(GdkToplevelLayout * layout)194 gdk_toplevel_layout_get_resizable (GdkToplevelLayout *layout)
195 {
196 return layout->resizable;
197 }
198
199 /**
200 * gdk_toplevel_layout_set_maximized:
201 * @layout: a `GdkToplevelLayout`
202 * @maximized: %TRUE to maximize
203 *
204 * Sets whether the layout should cause the surface
205 * to be maximized when presented.
206 */
207 void
gdk_toplevel_layout_set_maximized(GdkToplevelLayout * layout,gboolean maximized)208 gdk_toplevel_layout_set_maximized (GdkToplevelLayout *layout,
209 gboolean maximized)
210 {
211 layout->maximized_valid = TRUE;
212 layout->maximized = maximized;
213 }
214
215 /**
216 * gdk_toplevel_layout_get_maximized:
217 * @layout: a `GdkToplevelLayout`
218 * @maximized: (out): set to %TRUE if the toplevel should be maximized
219 *
220 * If the layout specifies whether to the toplevel should go maximized,
221 * the value pointed to by @maximized is set to %TRUE if it should go
222 * fullscreen, or %FALSE, if it should go unmaximized.
223 *
224 * Returns: whether the @layout specifies the maximized state for the toplevel
225 */
226 gboolean
gdk_toplevel_layout_get_maximized(GdkToplevelLayout * layout,gboolean * maximized)227 gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout,
228 gboolean *maximized)
229 {
230 if (layout->maximized_valid)
231 {
232 *maximized = layout->maximized;
233 return TRUE;
234 }
235
236 return FALSE;
237 }
238
239 /**
240 * gdk_toplevel_layout_set_fullscreen:
241 * @layout: a `GdkToplevelLayout`
242 * @fullscreen: %TRUE to fullscreen the surface
243 * @monitor: (nullable): the monitor to fullscreen on
244 *
245 * Sets whether the layout should cause the surface
246 * to be fullscreen when presented.
247 */
248 void
gdk_toplevel_layout_set_fullscreen(GdkToplevelLayout * layout,gboolean fullscreen,GdkMonitor * monitor)249 gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *layout,
250 gboolean fullscreen,
251 GdkMonitor *monitor)
252 {
253 layout->fullscreen_valid = TRUE;
254 layout->fullscreen = fullscreen;
255 if (monitor)
256 layout->fullscreen_monitor = g_object_ref (monitor);
257 }
258
259 /**
260 * gdk_toplevel_layout_get_fullscreen:
261 * @layout: a ``GdkToplevelLayout`
262 * @fullscreen: (out): location to store whether the toplevel should be fullscreen
263 *
264 * If the layout specifies whether to the toplevel should go fullscreen,
265 * the value pointed to by @fullscreen is set to %TRUE if it should go
266 * fullscreen, or %FALSE, if it should go unfullscreen.
267 *
268 * Returns: whether the @layout specifies the fullscreen state for the toplevel
269 */
270 gboolean
gdk_toplevel_layout_get_fullscreen(GdkToplevelLayout * layout,gboolean * fullscreen)271 gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout,
272 gboolean *fullscreen)
273 {
274 if (layout->fullscreen_valid)
275 {
276 *fullscreen = layout->fullscreen;
277 return TRUE;
278 }
279
280 return FALSE;
281 }
282
283 /**
284 * gdk_toplevel_layout_get_fullscreen_monitor:
285 * @layout: a `GdkToplevelLayout`
286 *
287 * Returns the monitor that the layout is fullscreening
288 * the surface on.
289 *
290 * Returns: (nullable) (transfer none): the monitor on which @layout fullscreens
291 */
292 GdkMonitor *
gdk_toplevel_layout_get_fullscreen_monitor(GdkToplevelLayout * layout)293 gdk_toplevel_layout_get_fullscreen_monitor (GdkToplevelLayout *layout)
294 {
295 return layout->fullscreen_monitor;
296 }
297