1/*
2 * Copyright © 2017-2018 Red Hat Inc.
3 * Copyright © 2018 Jonas Ådahl
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27#ifndef LIBDECOR_H
28#define LIBDECOR_H
29
30#include <stdbool.h>
31#include <wayland-client.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37#if defined(__GNUC__) && __GNUC__ >= 4
38#define LIBDECOR_EXPORT __attribute__ ((visibility("default")))
39#else
40#define LIBDECOR_EXPORT
41#endif
42
43struct xdg_toplevel;
44
45/** \class libdecor
46 *
47 * \brief A libdecor context instance.
48 */
49struct libdecor;
50
51/** \class libdecor_frame
52 *
53 * \brief A frame used for decorating a Wayland surface.
54 */
55struct libdecor_frame;
56
57/** \class libdecor_configuration
58 *
59 * \brief An object representing a toplevel window configuration.
60 */
61struct libdecor_configuration;
62
63/** \class libdecor_state
64 *
65 * \brief An object corresponding to a configured content state.
66 */
67struct libdecor_state;
68
69enum libdecor_error {
70 LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
71 LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
72};
73
74enum libdecor_window_state {
75 LIBDECOR_WINDOW_STATE_NONE = 0,
76 LIBDECOR_WINDOW_STATE_ACTIVE = 1 << 0,
77 LIBDECOR_WINDOW_STATE_MAXIMIZED = 1 << 1,
78 LIBDECOR_WINDOW_STATE_FULLSCREEN = 1 << 2,
79 LIBDECOR_WINDOW_STATE_TILED_LEFT = 1 << 3,
80 LIBDECOR_WINDOW_STATE_TILED_RIGHT = 1 << 4,
81 LIBDECOR_WINDOW_STATE_TILED_TOP = 1 << 5,
82 LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 1 << 6,
83};
84
85enum libdecor_resize_edge {
86 LIBDECOR_RESIZE_EDGE_NONE,
87 LIBDECOR_RESIZE_EDGE_TOP,
88 LIBDECOR_RESIZE_EDGE_BOTTOM,
89 LIBDECOR_RESIZE_EDGE_LEFT,
90 LIBDECOR_RESIZE_EDGE_TOP_LEFT,
91 LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT,
92 LIBDECOR_RESIZE_EDGE_RIGHT,
93 LIBDECOR_RESIZE_EDGE_TOP_RIGHT,
94 LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT,
95};
96
97enum libdecor_capabilities {
98 LIBDECOR_ACTION_MOVE = 1 << 0,
99 LIBDECOR_ACTION_RESIZE = 1 << 1,
100 LIBDECOR_ACTION_MINIMIZE = 1 << 2,
101 LIBDECOR_ACTION_FULLSCREEN = 1 << 3,
102 LIBDECOR_ACTION_CLOSE = 1 << 4,
103};
104
105struct libdecor_interface {
106 /**
107 * An error event
108 */
109 void (* error)(struct libdecor *context,
110 enum libdecor_error error,
111 const char *message);
112
113 /* Reserved */
114 void (* reserved0)(void);
115 void (* reserved1)(void);
116 void (* reserved2)(void);
117 void (* reserved3)(void);
118 void (* reserved4)(void);
119 void (* reserved5)(void);
120 void (* reserved6)(void);
121 void (* reserved7)(void);
122 void (* reserved8)(void);
123 void (* reserved9)(void);
124};
125
126/**
127 * Interface for integrating a Wayland surface with libdecor.
128 */
129struct libdecor_frame_interface {
130 /**
131 * A new configuration was received. An application should respond to
132 * this by creating a suitable libdecor_state, and apply it using
133 * libdecor_frame_commit.
134 */
135 void (* configure)(struct libdecor_frame *frame,
136 struct libdecor_configuration *configuration,
137 void *user_data);
138
139 /**
140 * The window was requested to be closed by the compositor.
141 */
142 void (* close)(struct libdecor_frame *frame,
143 void *user_data);
144
145 /**
146 * The window decoration asked to have the main surface to be
147 * committed. This is required when the decoration is implemented using
148 * synchronous subsurfaces.
149 */
150 void (* commit)(struct libdecor_frame *frame,
151 void *user_data);
152
153 /**
154 * Any mapped popup that has a grab on the given seat should be
155 * dismissed.
156 */
157 void (* dismiss_popup)(struct libdecor_frame *frame,
158 const char *seat_name,
159 void *user_data);
160
161 /* Reserved */
162 void (* reserved0)(void);
163 void (* reserved1)(void);
164 void (* reserved2)(void);
165 void (* reserved3)(void);
166 void (* reserved4)(void);
167 void (* reserved5)(void);
168 void (* reserved6)(void);
169 void (* reserved7)(void);
170 void (* reserved8)(void);
171 void (* reserved9)(void);
172};
173
174/**
175 * Remove a reference to the libdecor instance. When the reference count
176 * reaches zero, it is freed.
177 */
178void
179libdecor_unref(struct libdecor *context);
180
181/**
182 * Create a new libdecor context for the given wl_display.
183 */
184struct libdecor *
185libdecor_new(struct wl_display *display,
186 struct libdecor_interface *iface);
187
188/**
189 * Get the file descriptor used by libdecor. This is similar to
190 * wl_display_get_fd(), thus should be polled, and when data is available,
191 * libdecor_dispatch() should be called.
192 */
193int
194libdecor_get_fd(struct libdecor *context);
195
196/**
197 * Dispatch events. This function should be called when data is available on
198 * the file descriptor returned by libdecor_get_fd(). If timeout is zero, this
199 * function will never block.
200 */
201int
202libdecor_dispatch(struct libdecor *context,
203 int timeout);
204
205/**
206 * Decorate the given content wl_surface.
207 *
208 * This will create an xdg_surface and an xdg_toplevel, and integrate it
209 * properly with the windowing system, including creating appropriate
210 * decorations when needed, as well as handle windowing integration events such
211 * as resizing, moving, maximizing, etc.
212 *
213 * The passed wl_surface should only contain actual application content,
214 * without any window decoration.
215 */
216struct libdecor_frame *
217libdecor_decorate(struct libdecor *context,
218 struct wl_surface *surface,
219 struct libdecor_frame_interface *iface,
220 void *user_data);
221
222/**
223 * Add a reference to the frame object.
224 */
225void
226libdecor_frame_ref(struct libdecor_frame *frame);
227
228/**
229 * Remove a reference to the frame object. When the reference count reaches
230 * zero, the frame object is destroyed.
231 */
232void
233libdecor_frame_unref(struct libdecor_frame *frame);
234
235/**
236 * Set the visibility of the frame.
237 *
238 * If an application wants to be borderless, it can set the frame visibility to
239 * false.
240 */
241void
242libdecor_frame_set_visibility(struct libdecor_frame *frame,
243 bool visible);
244
245/**
246 * Get the visibility of the frame.
247 */
248bool
249libdecor_frame_is_visible(struct libdecor_frame *frame);
250
251
252/**
253 * Set the parent of the window.
254 *
255 * This can be used to stack multiple toplevel windows above or under each
256 * other.
257 */
258void
259libdecor_frame_set_parent(struct libdecor_frame *frame,
260 struct libdecor_frame *parent);
261
262/**
263 * Set the title of the window.
264 */
265void
266libdecor_frame_set_title(struct libdecor_frame *frame,
267 const char *title);
268
269/**
270 * Get the title of the window.
271 */
272const char *
273libdecor_frame_get_title(struct libdecor_frame *frame);
274
275/**
276 * Set the application ID of the window.
277 */
278void
279libdecor_frame_set_app_id(struct libdecor_frame *frame,
280 const char *app_id);
281
282/**
283 * Set new capabilities of the window.
284 *
285 * This determines whether e.g. a window decoration should show a maximize
286 * button, etc.
287 *
288 * Setting a capability does not implicitly unset any other.
289 */
290void
291libdecor_frame_set_capabilities(struct libdecor_frame *frame,
292 enum libdecor_capabilities capabilities);
293
294/**
295 * Unset capabilities of the window.
296 *
297 * The opposite of libdecor_frame_set_capabilities.
298 */
299void
300libdecor_frame_unset_capabilities(struct libdecor_frame *frame,
301 enum libdecor_capabilities capabilities);
302
303/**
304 * Check whether the window has any of the given capabilities.
305 */
306bool
307libdecor_frame_has_capability(struct libdecor_frame *frame,
308 enum libdecor_capabilities capability);
309
310/**
311 * Show the window menu.
312 */
313void
314libdecor_frame_show_window_menu(struct libdecor_frame *frame,
315 struct wl_seat *wl_seat,
316 uint32_t serial,
317 int x,
318 int y);
319
320/**
321 * Issue a popup grab on the window. Call this when a xdg_popup is mapped, so
322 * that it can be properly dismissed by the decorations.
323 */
324void
325libdecor_frame_popup_grab(struct libdecor_frame *frame,
326 const char *seat_name);
327
328/**
329 * Release the popup grab. Call this when you unmap a popup.
330 */
331void
332libdecor_frame_popup_ungrab(struct libdecor_frame *frame,
333 const char *seat_name);
334
335/**
336 * Translate content surface local coordinates to toplevel window local
337 * coordinates.
338 *
339 * This can be used to translate surface coordinates to coordinates useful for
340 * e.g. showing the window menu, or positioning a popup.
341 */
342void
343libdecor_frame_translate_coordinate(struct libdecor_frame *frame,
344 int surface_x,
345 int surface_y,
346 int *frame_x,
347 int *frame_y);
348
349/**
350 * Set the max content size.
351 *
352 * This translates roughly to xdg_toplevel_set_max_size().
353 */
354void
355libdecor_frame_set_max_content_size(struct libdecor_frame *frame,
356 int content_width,
357 int content_height);
358
359/**
360 * Set the min content size.
361 *
362 * This translates roughly to xdg_toplevel_set_min_size().
363 */
364void
365libdecor_frame_set_min_content_size(struct libdecor_frame *frame,
366 int content_width,
367 int content_height);
368
369/**
370 * Initiate an interactive resize.
371 *
372 * This roughly translates to xdg_toplevel_resize().
373 */
374void
375libdecor_frame_resize(struct libdecor_frame *frame,
376 struct wl_seat *wl_seat,
377 uint32_t serial,
378 enum libdecor_resize_edge edge);
379
380/**
381 * Initiate an interactive move.
382 *
383 * This roughly translates to xdg_toplevel_move().
384 */
385void
386libdecor_frame_move(struct libdecor_frame *frame,
387 struct wl_seat *wl_seat,
388 uint32_t serial);
389
390/**
391 * Commit a new window state. This can be called on application driven resizes
392 * when the window is floating, or in response to received configurations, i.e.
393 * from e.g. interactive resizes or state changes.
394 */
395void
396libdecor_frame_commit(struct libdecor_frame *frame,
397 struct libdecor_state *state,
398 struct libdecor_configuration *configuration);
399
400/**
401 * Minimize the window.
402 *
403 * Roughly translates to xdg_toplevel_set_minimized().
404 */
405void
406libdecor_frame_set_minimized(struct libdecor_frame *frame);
407
408/**
409 * Maximize the window.
410 *
411 * Roughly translates to xdg_toplevel_set_maximized().
412 */
413void
414libdecor_frame_set_maximized(struct libdecor_frame *frame);
415
416/**
417 * Unmaximize the window.
418 *
419 * Roughly translates to xdg_toplevel_unset_maximized().
420 */
421void
422libdecor_frame_unset_maximized(struct libdecor_frame *frame);
423
424/**
425 * Fullscreen the window.
426 *
427 * Roughly translates to xdg_toplevel_set_fullscreen().
428 */
429void
430libdecor_frame_set_fullscreen(struct libdecor_frame *frame,
431 struct wl_output *output);
432
433/**
434 * Unfullscreen the window.
435 *
436 * Roughly translates to xdg_toplevel_unset_unfullscreen().
437 */
438void
439libdecor_frame_unset_fullscreen(struct libdecor_frame *frame);
440
441/**
442 * Return true if the window is floating.
443 *
444 * A window is floating when it's not maximized, tiled, fullscreen, or in any
445 * similar way with a fixed size and state.
446 */
447bool
448libdecor_frame_is_floating(struct libdecor_frame *frame);
449
450/**
451 * Close the window.
452 *
453 * Roughly translates to xdg_toplevel_close().
454 */
455void
456libdecor_frame_close(struct libdecor_frame *frame);
457
458/**
459 * Map the window.
460 *
461 * This will eventually result in the initial configure event.
462 */
463void
464libdecor_frame_map(struct libdecor_frame *frame);
465
466/**
467 * Get the associated xdg_surface for content wl_surface.
468 */
469struct xdg_surface *
470libdecor_frame_get_xdg_surface(struct libdecor_frame *frame);
471
472/**
473 * Get the associated xdg_toplevel for the content wl_surface.
474 */
475struct xdg_toplevel *
476libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame);
477
478/**
479 * Create a new content surface state.
480 */
481struct libdecor_state *
482libdecor_state_new(int width,
483 int height);
484
485/**
486 * Free a content surface state.
487 */
488void
489libdecor_state_free(struct libdecor_state *state);
490
491/**
492 * Get the expected size of the content for this configuration.
493 *
494 * If the configuration doesn't contain a size, false is returned.
495 */
496bool
497libdecor_configuration_get_content_size(struct libdecor_configuration *configuration,
498 struct libdecor_frame *frame,
499 int *width,
500 int *height);
501
502/**
503 * Get the window state for this configuration.
504 *
505 * If the configuration doesn't contain any associated window state, false is
506 * returned, and the application should assume the window state remains
507 * unchanged.
508 */
509bool
510libdecor_configuration_get_window_state(struct libdecor_configuration *configuration,
511 enum libdecor_window_state *window_state);
512
513#ifdef __cplusplus
514}
515#endif
516
517#endif /* LIBDECOR_H */
518