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 | |
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 (rc: &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 * |
95 | gdk_toplevel_layout_ref (GdkToplevelLayout *layout) |
96 | { |
97 | g_ref_count_inc (rc: &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 |
108 | gdk_toplevel_layout_unref (GdkToplevelLayout *layout) |
109 | { |
110 | if (g_ref_count_dec (rc: &layout->ref_count)) |
111 | { |
112 | g_clear_object (&layout->fullscreen_monitor); |
113 | g_free (mem: 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 * |
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 (rc: &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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 * |
293 | gdk_toplevel_layout_get_fullscreen_monitor (GdkToplevelLayout *layout) |
294 | { |
295 | return layout->fullscreen_monitor; |
296 | } |
297 | |