1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
//! Wayland Window, a minimalistic decoration-drawing library for //! wayland applications. //! //! This crate is only usable in conjuction of the //! [`wayland-client`](https://crates.io/crates/wayland-client) crate. //! //! ## Creating a decorated shell surface //! //! Creating a decorated window is as simple as wrapping it in a //! `DecoratedSurface`: //! //! ```ignore //! use wayland_window::DecoratedSurface; //! let decorated = DecoratedSurface::new(my_surface, width, height, ®istry, &seat); //! ``` //! //! As you can see, you need to pass the `Registry` and a `Seat` as well. It is required //! for the library to be able to create the surfaces to draw the borders, and register //! the callback to detect user input in the borders, for resizeing and move. These callback //! will be registered on the seat you passed as argument. (So if you are on a setup with more //! than one pointer, only one of them will be able to resize the window). //! //! ## Processing the events //! //! The `DecoratedSurface` object will not resize your window itself, as it cannot do it. //! //! When the user clicks on a border and starts a resize, the server will start to generate a //! number of `configure` events on the shell surface. You'll need to register a callback on //! it to handle them: //! //! ```ignore //! decorated.get_shell().set_configure_callback(move |edge, width, height| { //! /* ... */ //! }); //! ``` //! //! The wayland server can (and will) generate a ton of `configure` events during a single //! `Display::dispatch()` if the user is currently resizing the window. You are only required to //! process the last one, and if you try to handle them all your aplication will be very //! laggy. //! //! The proper way is to use the callback to only store them in a container, overwriting the //! the previous one each time, and manually checking if one has been received in the main loop //! of your program, like this: //! //! ```ignore //! // create a shared storage: (width, heigh, need_resize ?) //! let need_resize = Arc::new(Mutex::new((0, 0, false))); //! // clone it and put it in the callback //! let my_need_resize = need_resize.clone(); //! decorated.w.get_shell().set_configure_callback(move |_edge, width, height| { //! let mut guard = my_newsize.lock().unwrap(); //! // we overwrite it each time, to only keep the last one //! *guard = (width, height, true); //! }); //! // then handle all this in the main loop: //! loop { //! display.dispatch(); //! let guard = need_resize.lock().unwrap(); //! let (width, height, resize) = *guard; //! if resize { //! /* handle the resizing here */ //! } //! // reset the storage //! *guard = (0, 0, false); //! } //! ``` //! //! ## Resizing the surface //! //! When resizing your main surface, you need to tell the `DecoratedSurface` that it //! must update its dimensions. This is very simple: //! //! ```ignore //! /* update the buffer of decorated */ //! decorated.resize(width, height); //! decorated.get_shell().commit(); //! ``` //! //! If you do this as a response of a `configure` event, note the following points: //! //! - You do not have to respect the exact sizes provided by the compositor, it is //! just a hint. You can even ignore it if you don't want the window to be resized. //! - In case you chose to ignore the resize, it can be appropiate to still resize your //! window to its current size (update the buffer to the compositor), as the compositer //! might have resized your window without telling you. //! - The size hint provided by the compositor counts the borders size, to get the real //! size hint for your interior surface, use the function `substract_borders(..)` provided //! by this library. extern crate byteorder; extern crate tempfile; extern crate wayland_client as wayland; mod decorated_surface; pub use decorated_surface::{DecoratedSurface, substract_borders, SurfaceGuard};