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 34 extern "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 43 struct xdg_toplevel; 44 45 /** \class libdecor 46 * 47 * \brief A libdecor context instance. 48 */ 49 struct libdecor; 50 51 /** \class libdecor_frame 52 * 53 * \brief A frame used for decorating a Wayland surface. 54 */ 55 struct libdecor_frame; 56 57 /** \class libdecor_configuration 58 * 59 * \brief An object representing a toplevel window configuration. 60 */ 61 struct libdecor_configuration; 62 63 /** \class libdecor_state 64 * 65 * \brief An object corresponding to a configured content state. 66 */ 67 struct libdecor_state; 68 69 enum libdecor_error { 70 LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE, 71 LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION, 72 }; 73 74 enum 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 85 enum 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 97 enum 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 105 struct 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 */ 129 struct 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 */ 178 void 179 libdecor_unref(struct libdecor *context); 180 181 /** 182 * Create a new libdecor context for the given wl_display. 183 */ 184 struct libdecor * 185 libdecor_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 */ 193 int 194 libdecor_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 */ 201 int 202 libdecor_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 */ 216 struct libdecor_frame * 217 libdecor_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 */ 225 void 226 libdecor_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 */ 232 void 233 libdecor_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 */ 241 void 242 libdecor_frame_set_visibility(struct libdecor_frame *frame, 243 bool visible); 244 245 /** 246 * Get the visibility of the frame. 247 */ 248 bool 249 libdecor_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 */ 258 void 259 libdecor_frame_set_parent(struct libdecor_frame *frame, 260 struct libdecor_frame *parent); 261 262 /** 263 * Set the title of the window. 264 */ 265 void 266 libdecor_frame_set_title(struct libdecor_frame *frame, 267 const char *title); 268 269 /** 270 * Get the title of the window. 271 */ 272 const char * 273 libdecor_frame_get_title(struct libdecor_frame *frame); 274 275 /** 276 * Set the application ID of the window. 277 */ 278 void 279 libdecor_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 */ 290 void 291 libdecor_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 */ 299 void 300 libdecor_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 */ 306 bool 307 libdecor_frame_has_capability(struct libdecor_frame *frame, 308 enum libdecor_capabilities capability); 309 310 /** 311 * Show the window menu. 312 */ 313 void 314 libdecor_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 */ 324 void 325 libdecor_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 */ 331 void 332 libdecor_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 */ 342 void 343 libdecor_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 */ 354 void 355 libdecor_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 */ 364 void 365 libdecor_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 */ 374 void 375 libdecor_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 */ 385 void 386 libdecor_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 */ 395 void 396 libdecor_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 */ 405 void 406 libdecor_frame_set_minimized(struct libdecor_frame *frame); 407 408 /** 409 * Maximize the window. 410 * 411 * Roughly translates to xdg_toplevel_set_maximized(). 412 */ 413 void 414 libdecor_frame_set_maximized(struct libdecor_frame *frame); 415 416 /** 417 * Unmaximize the window. 418 * 419 * Roughly translates to xdg_toplevel_unset_maximized(). 420 */ 421 void 422 libdecor_frame_unset_maximized(struct libdecor_frame *frame); 423 424 /** 425 * Fullscreen the window. 426 * 427 * Roughly translates to xdg_toplevel_set_fullscreen(). 428 */ 429 void 430 libdecor_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 */ 438 void 439 libdecor_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 */ 447 bool 448 libdecor_frame_is_floating(struct libdecor_frame *frame); 449 450 /** 451 * Close the window. 452 * 453 * Roughly translates to xdg_toplevel_close(). 454 */ 455 void 456 libdecor_frame_close(struct libdecor_frame *frame); 457 458 /** 459 * Map the window. 460 * 461 * This will eventually result in the initial configure event. 462 */ 463 void 464 libdecor_frame_map(struct libdecor_frame *frame); 465 466 /** 467 * Get the associated xdg_surface for content wl_surface. 468 */ 469 struct xdg_surface * 470 libdecor_frame_get_xdg_surface(struct libdecor_frame *frame); 471 472 /** 473 * Get the associated xdg_toplevel for the content wl_surface. 474 */ 475 struct xdg_toplevel * 476 libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame); 477 478 /** 479 * Create a new content surface state. 480 */ 481 struct libdecor_state * 482 libdecor_state_new(int width, 483 int height); 484 485 /** 486 * Free a content surface state. 487 */ 488 void 489 libdecor_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 */ 496 bool 497 libdecor_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 */ 509 bool 510 libdecor_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