swayfx/sway/desktop/render.c

2343 lines
79 KiB
C
Raw Normal View History

#include <stdio.h>
2018-07-07 19:30:52 +10:00
#include <assert.h>
2019-11-14 05:23:36 +11:00
#include <GLES2/gl2.h>
2018-07-07 19:30:52 +10:00
#include <stdlib.h>
#include <strings.h>
#include <time.h>
#include <wayland-server-core.h>
2019-11-14 05:23:36 +11:00
#include <wlr/render/gles2.h>
2018-07-07 19:30:52 +10:00
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_buffer.h>
2023-04-07 14:26:23 +10:00
#include <wlr/types/wlr_compositor.h>
rebase: Sway 1.8 (#78) * build: bump wlroots dependency to 0.16.0 * swaymsg: replace if with switch in pretty_print * swaymsg: add GET_TREE pretty-printing * swaybar: fix errno handling in status_handle_readable If getline fails once, it was not reset before the next getline call. errno is only overwritten by getline on error. * Add cairo_image_surface_create error handling cairo_image_surface_create can fail, e.g. when running out of memory or when the size is too big. Avoid crashing in this case. Closes: https://github.com/swaywm/sway/issues/6531 * build: bump version to 1.8-dev Historically we've been sticking with the last release number in the master branch. However that's a bit confusing, people can't easily figure out whether they're using a release or a work-in-progress snapshot. Only the commit hash appended to the version number may help, but that's not very explicit and disappears when using a tarball. We could bump the version in master to the next release number. However during the RC cycle there would be a downgrade from 1.8 to 1.8-rc1. Also it would be hard to tell the difference between a stable release and an old snapshot. This patch introduces a new pre-release identifier, "dev". It's alphabetically before "rc" so it should be correctly sorted by semver comparisons. "dev" is upgraded to "rc" (and then to stable) when doing a release. The master branch always uses a "dev" version, only release branches use "rc" or stable versions. * [IPC] Add repeat delay/rate info to keyboard Closes #6735 wlroots already has the info in the struct so let's access it and print it out. * input/seat: unset has_focus when focus_stack becomes empty We currently track the focus of a seat in two ways: we use a list called focus_stack to track the order in which nodes have been focused, with the first node representing what's currently focused, and we use a variable called has_focus to indicate whether anything has focus--i.e. whether we should actually treat that first node as focused at any given time. In a number of places, we treat has_focus as implying that a focused node exists. If it's true, we attempt to dereference the return value of seat_get_focus(), our helper function for getting the first node in focus_list, with no further checks. But this isn't quite correct with the current implementation of seat_get_focus(): not only does it return NULL when has_focus is false, it also returns NULL when focus_stack contains no items. In most cases, focus_stack never becomes empty and so this doesn't matter at all. Since focus_stack stores a history of focused nodes, we rarely remove nodes from it. The exception to this is when a node itself goes away. In that case, we call seat_node_destroy() to remove it from focus_stack and free it. But we don't unset has_focus if we've removed the final node! This lets us get into a state where has_focus is true but seat_get_focus() returns NULL, leading to a segfault when we try to dereference it. Fix the issue both by updating has_focus in seat_node_destroy() and by adding an assertion in seat_get_focus() that ensures focus_stack and has_focus are in sync, which will make it easier to track down similar issues in the future. Fixes #6395. [1] There's some discussion in #1585 from when this was implemented about whether has_focus is actually necessary; it's possible we could remove it entirely, but for the moment this is the architecture we have. * swaybar: fix tray_padding vs min-height re: scale Co-authored-by: xdavidwu <xdavidwuph@gmail.com> * swaybar: fix tray item icon scaling, positioning * container: Fix crash when view unmaps + maps quickly Followup on 4e4898e90f. If a view quickly maps and unmaps repeatedly, there will be multiple destroyed containers with same view in a single transaction. Each of these containers will then try to destroy this view, resulting in use after free. The container should only destroy the view if the view still belongs to the container. Simple reproducer: couple XMapWindow + XUnmapWindow in a loop followed by XDestroyWindow. See #6605 * commands/move: Fix crash when pos_y is omitted Fixes #6737 * Destroy sub-surfaces with parent layer-shell surface Closes: https://github.com/swaywm/sway/issues/6337 * Add safety assert in parse_movement_unit Let's add this just in case a caller passes argc == 0. References: https://github.com/swaywm/sway/issues/6737#issuecomment-1008082540 * meson: check: false on run_command Future meson releases will change the default and warns when the implicit default is used, breaking builds. Explicitly set check: false to maintain behavior and silence warnings. * Print deprecation notice when running SUID SUID privilege drop is needed for the "builtin"-backend of libseat, which copied our old "direct" backend behavior for the sake of compatibility and ease of transition. libseat now has a better alternative in the form of seatd-launch. It uses the normal seatd daemon and libseat backend and takes care of SUID for us. Add a soft deprecation warning to highlight our future intent of removing this code. The deprecation cycle is needed to avoid surprises when sway no longer drops privileges. * xdg-shell: use toplevel geometry to adjust the popup box `popup_unconstrain` uses view coordinates to init the output box for popups. However wlroots expects the box to be set in a toplevel surface coordinate system, which is not always equal to view. The difference between those is a window geometry set via xdg-shell. GTK4 reserves some space for client-side decoration and thus has a window with top left corner not matching to (0, 0) of a surface. The box calculated without taking that into account was slightly shifted compared to the actual output and allowed to position part of the popup off screen. * build: fix building with basu 02b412a introduced the use of list for sdbus deps, however it was assuming that all packages which were in a list has a version higher than 239. That is true for libsystemd and libelogind, since they use the same versions, however basu is using version numbers which are way lower than what libsystemd/libelogind are using, so basu only build is failing. * Upgrade for wlroots surface refactoring See [1] for details. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3412 * commands/focus: drop trailing whitespace * input/cursor: count pointer gestures as idle activity Fixes https://github.com/swaywm/sway/issues/6765. * input/cursor: treat swipe begin as idle activity too Accidentally overlooked in fd53f80. * treat fullscreen windows as 'tiled' for commands/focus * transaction: destroying nodes aren't hidden Commit 37d7bc69986f ("transaction: Only wait for ack from visible views") introduced a check which uses view_is_visible() to check if a view is still visible on the screen. However view_is_visible() will early return in case the node is in the destroying state. This is incorrect for transactions, since a destroying view which is visible will trigger configure events for other clients. This bug was visible when repeatedly opening and closing two views side by side, since we ignore the destroying node we get a frame where the still open view is shown with the old configure values and the rest is the desktop background. The next frame is than correct again. Fix this by considering destroying views as visible, we correctly wait for them and send the configure events to other views in time, fixing the background flicker. Fixes #6473 * build: execute wlroots subproject before finding deps wlroots often requires dependencies more recent than Sway's. Executing the wlroots subproject first will give Meson a chance to find these newer dependencies, possibly via subprojects. The subproject will override the "wlroots" dependency when executed, so we don't need to use get_variable anymore. References: https://github.com/swaywm/sway/pull/6498#issuecomment-1001746017 * tray: do not render passive items https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/#org.freedesktop.statusnotifieritem.status * cmd/swap: error on swapping a container with itself * input/cursor: pass through pointer hold gestures This just follows swaywm/wlroots#3047, so `wl_pointer_gestures_v1` clients can be notified of these events. * swaynag: remove buffer destruction condition An address of a variable can never be NULL, so checking it doesn't make sense; and `destroy_buffer()` can operate on already destroyed buffers anyway. Fixes #6780 * Use bools for CLI flags * xwayland: listen to `request_activate` event When REAPER submenu is closed `XCB_CLIENT_MESSAGE` with type `NET_ACTIVE_WINDOW` is sent to set focus to parent menu. Closes: https://github.com/swaywm/sway/issues/6324 * chore: chase wlr_output_layout_get_box() update https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3439 * Chase wlroots xdg-shell refactor * Minor update to focus_on_window_activation Removed xwayland limitation since wayland clients are supported via xdg-activation. * Translated README into Italian * readme: add link to Italian translation * readme: sort language list alphabetically * readme: use relative links for translations * xdg-shell: use wlr_xdg_toplevel in sway_view Improved type safety. Closes: https://github.com/swaywm/sway/issues/6813 * xdg-shell: use wlr_xdg_popup in sway_xdg_popup Improved type safety. * Fix snprintf compiler warning * Remove all sprintf calls Replace them with snprintf, which ensures buffer overflows won't happen. * sway/commands: add missing wlr_keyboard interface include in xkb_switch_layout * sway/input: use wlr_input_device from input device base * Remove some erroneous apostrophes in comments * Don't enter seatop_move_floating when fullscreen Currently, a floating window that's been fullscreened can send us xdg_toplevel::move, and we'll enter seatop_move_floating, which lets us drag the surface around while it's fullscreen. We don't want this--fullscreen surfaces should always be aligned to the screen--so add the same check that seatop_default already does when entering this mode. Tested with Weston's weston-fullscreen demo, which sends a move request if you click anywhere on its surface. * swaynag: die on all allocation failures * sway/input: don't pass possibly invalid modifiers pointer active_keyboard may be NULL, in which case an invalid pointer could be passed to wlr_input_method_keyboard_grab_v2_send_modifiers. This procedure call is unnecessary since wlroots commit 372a52ec "input method: send modifiers in set_keyboard", so the call can simply be removed. Fixes #6836. * sway/input: destroy sway_switch properly Fix: #6861 Added seat_device_destroy function to seat_device_destroy function. * commands/focus: fix segfault when no container is already focused. Fixes #6690. * Remove WLR_SWITCH_STATE_TOGGLE usage Ref [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/4792446ee8f50104bd207d9ccd8558a7e4eb4514 * Replace pcre with pcre2 Closes: https://github.com/swaywm/sway/issues/6838 * swaybar: remove swaybar_output.input_region No need to keep the region around, we can immediately destroy it after the wl_surface.set_input_region request. * swaybar: set opaque region When the background color is fully opaque, set the surface's opaque region to the whole surface. * Updating criteria checking with PCRE2 * swaynag: allocate button_details with details They are used together, so it doesn't make sense to allocate them separately. * swaynag: statically allocate button_close, and move declaration Every swaynag has a close button, so it doesn't make sense to allocate it dynamically. The declaration is moved later to when it is actually needed. * swaynag: remove unnecessary zero of swaynag struct Global variables are initialized to 0. * swaynag: remove redundant status variables in main Instead, we just use `status` for all failures. * remove unnecessary strlen call * sway/input/cursor: take device mm size from wlr_tablet * sway/input/seat: take output name from specialized input device * sway/input: follow up wlroots input device events renaming * sway/input: fix bad position of wlr_drag * sway/input: wlr_seat_keyboard() now takes wlr_keyboard * bash-completion: localize variables * sway/main: move constants off the stack This makes stack traces from gdb slightly easier to read. * Fix farsi label * Avoid format-truncation warning The existing code gives this error when compiled with GCC 12: ../sway/server.c: In function ‘server_init’: ../sway/server.c:217:75: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 8 [-Werror=format-truncation=] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~ ../sway/server.c:217:66: note: directive argument in the range [-2147483647, 32] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~ ../sway/server.c:217:17: note: ‘snprintf’ output between 10 and 20 bytes into a destination of size 16 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because i is never negative, this is a false positive, but it is easy to change i to unsigned to silence the error. * Shuffle variables to satisfy -Werror=restrict This also fixes an invalid strlen invocation on uninitialized memory. * layer_shell: keep output non-NULL wherever possible Our layer shell implementation assigns every layer surface to an output on creation. It tracks this output using the output field on the underlying wlr_layer_surface_v1 structure. As such, much of the existing code assumes that output is always non-NULL and omits NULL checks accordingly. However, there are currently two cases where we destroy a sway_layer_surface and output is NULL. The first is when we can't find an output to assign the surface to and destroy it immediately after creation. The second is when we destroy a surface in response to its output getting destroyed, as we set output to NULL in handle_output_destroy() before we call wlr_layer_surface_v1_destroy(), which is what calls the appropriate unmap and destroy callbacks. The former case doesn't cause any problems, since we haven't even allocated a sway_layer_surface at that point or registered any callbacks. The latter case, however, currently triggers a crash (#6120) if a popup is visible, since our popup_handle_unmap() implementation can't handle a NULL output. To fix this issue, keep output set until right before we free the sway_layer_surface. All we need to do is remove some of the cleanup logic from handle_output_destroy(), since as of commit c9060bcc12d0 ("layer-shell: replace close() with destroy()") that same logic is guaranteed to be happen later when wlroots calls handle_destroy() as part of wlr_layer_surface_v1_destroy(). This lets us remove some NULL checks from other unmap/destroy callbacks, which is nice. We also don't need to check that the wlr_output points to a valid sway_output anymore, since we unset that pointer after disabling the output as of commit a0bbe67076b8 ("Address emersions comments on output re-enabling") Just to be safe, I've added assertions that the wlr_output is non-NULL wherever we use it. Fixes #6120. * Chase wlroots X11 hints update * Add Swedish README * Support cursor capture in grimshot Refactor argument parser Bring back `sh` compatibility Default to NOTIFY=no * Update grimshot.1.scd Fixed typo. The object is **files**, which is plural. **image** modifies files; it's not countable. * xkb_switch_layout: fix relative layout switches Fixes #6011 * Implement ext-session-lock-v1 * Avoid inspecting a NULL view in seat_set_focus Fixes #6968 * swaynag: do error checking and rename read_from_stdin read_from_stdin not only read from stdin, but trimming trailing newlines, so rename it to reflect this. * swaynag: improve robustness when loading config * swaynag: combine consecutive declaration/assignments * config: Remove unused mouse binding structure Mouse bindings are handled alongside normal bindings. Remove the unused separate data structure definition to avoid confusion. Signed-off-by: Michael Weiser <michael.weiser@gmx.de> * Replace strncpy with memcpy strncpy is useless here, is dangerous because it doesn't guarantee that the string is NUL-terminated and causes the following warning: ../sway/criteria.c: In function ‘criteria_parse’: ../sway/criteria.c:712:25: error: ‘strncpy’ destination unchanged after copying no bytes [-Werror=stringop-truncation] 712 | strncpy(value, valuestart, head - valuestart); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Add descriptions for `stacking` and `tabbed` layouts Resolves #5918 * man: Fix trailing spaces * server: request xdg-shell v2 Wlroots does not yet support the newer xdg-shell versions and now requires the compositor to set the supported xdg-shell version during creation. Set this to v2 for sway as well. Fixes https://github.com/swaywm/sway/issues/7001 * realtime: request SCHED_RR using CAP_SYS_NICE Try to gain SCHED_RR (round-robin) realtime scheduling privileges before starting the server. This requires CAP_SYS_NICE on Linux systems. We additionally register a pthread_atfork callback which resets the scheduling class back to SCHED_OTHER (the Linux system default). Due to CAP_SYS_NICE, setting RLIMIT_RTPRIO has no effect on the process as documented within man 7 sched (from Linux): Privileged (CAP_SYS_NICE) threads ignore the RLIMIT_RTPRIO limit; as with older kernels, they can make arbitrary changes to scheduling policy and priority. See getrlimit(2) for further information on RLIMIT_RTPRIO Note that this requires the sway distribution packagers to set the CAP_SYS_NICE capability on the sway binary. Supersedes #6992 * ext-session-lock: disable direct scan-out when locked * Polish the language in README.zh-CN.md & sync with English one Co-Authored-By: Urey. Xue <urey.s.knowledge@gmail.com> * De-duplicate IPC output descriptions * Handle NULL output make/model/serial * chore: chase wlroots xdg-shell update * xdg-shell: schedule a configure on maximize request This commit reverts 03879290dbee26127f6867ef60bc2a7f9a6c8c5f and fc84bcb7fb0ffa29b1f9bed287762241a3473803. * Add a Hindi (हिन्दी) translation to the README Hindi is one of the most prominent languages of the Indian Subcontinent. This commit adds the translation of the README into the Hindi language. Some of the words are still written in English because there wasn't an appropriate technical term of the word in the language. Co-authored-by: Surendrajat <surendrajat@protonmail.com> * sway: add bindgesture command Co-authored-by: Michael Weiser <michael.weiser@gmx.de> * build: link with -pthread Fixes the following FreeBSD error: ld: error: undefined symbol: pthread_getschedparam >>> referenced by realtime.c:25 (../sway/realtime.c:25) >>> sway/sway.p/realtime.c.o:(set_rr_scheduling) Fixes: a3a82efbf6b5 ("realtime: request SCHED_RR using CAP_SYS_NICE") * ipc: remove chatty debug log messages These aren't particularly useful, and clobber the debug logs. * Refuse to start when SUID is detected This ensures that those surprised by the deprecation of SUID operation receive an error rather than accidentally having sway run as root. This detection will be removed in a future release. * swaynag: move close_button up to fix SIGSEGV When swaynag_parse_options encounters '--dismiss-button' (or its shorthand '-s'), it sets the text of the first button in the swaynag.buttons list, which is expected to exist and to be the dismiss button, to the one passed by the user. Commit 4780afb68b4ee2cdf0e4925f40cf885819f8a74a ("swaynag: statically allocate button_close, and move declaration") moved the list initialization to after swaynag_parse_options is called which made that code fail. For example, the command 'swaynag --dismiss-button Dismiss' crashes and 'swaynag --message Message --button Yes "" --dismiss-button Dismiss' shows the wrong buttons. Move it back to before swaynag_parse_options is called. * config/output: use wlr_output_commit_state This makes the code more robust because we don't potentially leave bad state in wlr_output.pending behind anymore. This also fixes a bug. Closes: https://github.com/swaywm/sway/issues/7043 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3610 * Allocate enough space for `cmd_results->error` * Remove access to wlr_input_device union References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3626 Closes: https://github.com/swaywm/sway/issues/7077 * Rename dpms output command to power The "dpms" command refers to VESA Display Power Management Signaling, a deprecated standard. It's superseded by VESA DPM. Instead of tying out command name to a particular standard, use the neutral term "power". * Strip quotes in bindsym --input-device=... If the input device is quoted, which is common when using variables in the config file, those quotes must be ignored here, or the input device will be ignored. Fixes #7029. * Avoid unecessary string copy * Reject font values that are invalid for pango Use pango to parse font configuration early, and reject the command as invalid if the value is invalid for pango. Since we're already parsing the font into a `PangoFontDescription`, keep that instance around and avoid re-parsing the font each time we render text. Fixes: https://github.com/swaywm/sway/issues/6805 * Reuse parsed PangoFontDescription Avoids parsing the configured font each time text is rendered. * ipc: add "power" to output reply * config.in: switch to `output power` * Remove internal references to DPMS While at it, use an int for the config field, just like we do for all other fields. * fix: remove redundant empty statement in main.c This semi-colon looks like a typo. Luckily, it has no effect on the code as it's treated as an empty statement leading the switch case. Really straightforward nitpick change, was just something I was confused by when reading over the code. * input: chase delta_discrete semantics change * swaymsg: fix floating_nodes being ignored Fix floating_nodes being ignored in pretty_print_tree. * ipc: make get_deco_rect check config->hide_lone_tab Without this, the `IPC_GET_TREE` ipc call would return false information about the container's `deco_rect` and `rect` properties if `hide_edge_borders --i3` was in effect. * grimshot: fix tilde expansion within quotes * Enable single-pixel-buffer-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3428 * sway-output.5: improve display of parameter Since "width" and "height" are separate parameters, show them as such. * man: sway(5) move fixes * ipc: drop WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN case This has been removed from wlroots. * config/output: test adaptive sync Required for [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3637 * Fix crash in xdg_activation_v1.c wlr_xdg_surface_from_wlr_surface() can return a NULL pointer, so check for NULL before dereferencing it. * sway: Add non-desktop-output type Currently, when encountering a non-desktop display, sway offers the output for leasing and returns without storing it in a sway specific output type like `struct sway_output`. Additionally, running `swaymsg -t get_outputs` doesn't show non-desktop outputs. This commit stores the non-desktop outputs into a struct called `sway_output_non_desktop`, and adds them to a list on `sway_root` * sway: add non-desktop outputs to json when running `swaymsg -t get_outputs` * swaymsg: show non-desktop property when pretty printing outputs * man: Add XWayland information * ipc: expose mode picture aspect ratio * swaymsg: show mode picture aspect ratio * build: simplify protocol paths No need for arrays here. * sway/commands/output: Add command for unplugging non-physical outputs * Improve Japanese translation * allow pointer_constraints on layer_shell surfaces * check for NULL * use seat directly * Use keyboard_state.focused_surface directly * input: focus floating container when clicked on border Fixes #7209. * input: focus container when scrolling on titlebar Fixes #6503. * Fix leaks in criteria_destroy() * Avoid double free in criteria_destroy() * Add support for ext-idle-notify-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3753 * input: tweak focus behavior to allow focusing parent containers Sway focuses the inactive child when focusing split containers. However, there is currently no way to focus the parent container itself by mouse. A user must use the keyboard to do so. This commit maintains the current behavior, but makes it such that a second click on the split container titlebar (i.e., after its children are visible) focuses the split container itself. * Fix keymap being NULL and segfaulting on dev add Moved `libinput_config` to the callers of `sway_input_configure_libinput_device` so that we send the event after the added event. * Rework session lock keyboard focus handling When removing outputs, it is possible to end up in a situation where none of the session lock client's surfaces have keyboard focus, resulting in it not receiving keyboard events. Track the focused surface and update it as needed on surface destroy. * Fix focus tracking when session lock is active Remove the incorrect attempt to block focus changes when an input grab is present and replace it with the same logic used for layer_shell-based screen lockers: restore the focus after changing it. This fixes a use-after-free of seat->workspace if outputs are destroyed while a screen lock is enabled. * container_floating_set_default_size: Store workspace size box on the stack * Support libinput's 1.21 new dwtp option Support the new dwtp (disable while trackpointing) option introduced in libinput 1.21, allowing users to control whether the trackpoint (like those in Thinkpads, but not only) should be disabled while using the keyboard/touchpad. See: https://gitlab.freedesktop.org/libinput/libinput/-/issues/731 * tree: support formatting null titles Any windows that have never had a title set visually behave closer to that of an empty title, but are unformattable, as the code bails out early on a NULL title. * criteria: allow matching on empty (NULL) titles * criteria: allow matching for NULL string criteria * ci: install hwdata * Use wl_signal_emit_mutable() This function fixes segfaults when emitting a signal potentially removes arbitrary listeners. * Use wlr_damage_ring wlr_output_damage is to be replaced with wlr_damage_ring, so use that. * lock: fix crash on output destroy Closes: https://github.com/swaywm/sway/issues/7120 * container_get_siblings: handle NULL workspace * ci: checkout wlroots 0.16.0 * workspace_create: Don't allow NULL name (cherry picked from commit 34933bb84350fe805d82276ea02d5732546e9993) * output: set damage ring bounds to pixel values Fixes: https://github.com/swaywm/sway/issues/7254 (cherry picked from commit 85005b52fe5b832e4ea914fa28048b0c5c803769) * Use shm_open instead of mkstemp shm_open is more reliable because it does not require a writeable filesystem folder, unlike mkstemp. (cherry picked from commit e2bc8866f46701e9c825ad7fa5baac02b2e4898f) * build: drop wayland-scanner fallback (cherry picked from commit 366f6ef3d31688631dc453028e108f98a1d7ab57) * build: unify server & client protocol generation No need to make a difference here, let's just generate header files for both. (cherry picked from commit 5be5a038da8a3789a19945719f2a27233291445d) * build: drop "server" from target name for protocol code (cherry picked from commit e5475d9310941ce88ed016ce1515b36e3a440252) * build: drop intermediate libraries for protocols (cherry picked from commit af8a5a8918ef42336194fb1077b008a736de7af9) * root: move the workspace matching code to its own file This removes the pid_workspace bits from tree/root before it gets too interesting. No functional change. (cherry picked from commit eb5021ef990fb29ff86544aea58d687ad62c757a) * node: prettify node type names (cherry picked from commit 1c4b94ae3ca94b972410c80a61404a347af1ee68) * launcher: track workspaces by node This removes the need to rename the pid_workspaces when a workspace is renamed. It also opens the possibility of tracking other node types. Tracking containers would allow application to be placed correctly in the container tree even if the user has moved their focus elsewhere since it was launched. (cherry picked from commit 3b49f2782e8faf68766269b9c7390b16e25ae824) * launcher: use xdga tokens This reuses wlroots token tracking for workspace matching. It doesn't export any xdga tokens for clients yet. (cherry picked from commit bd66f4943da1c96edc3ba49573e27b42b688c543) * launcher: rename pid_workspace to launcher_ctx Soon we will match views with more than just a pid. (cherry picked from commit d75c9f9722389d441fd24bd490c5cf12c4bef39a) * view: associate launch contexts with views Views now maintain a reference to a launch context which, as a last resort, is populated at map time with a context associated with its pid. This opens the possibility of populating it before map via another source, e.g. xdga-tokens or configuration. (cherry picked from commit 864b3a9a18f236f92f1898bb44ab977ceaebfd68) * launcher: initialize launcher_ctxs once on startup (cherry picked from commit 66568508c06267445489d655c91c94a34d6d9ffe) * launcher: fudge the interface a bit We want to create a context before knowing the pid it will match with. (cherry picked from commit bdeb9f95651f6c99cc2f4cfb59020ddee202cf36) * launcher: export xdga tokens and use them for workspace matching (cherry picked from commit 30ad4dc4a5a41ce7c7aa85096a6e18f374172983) * launcher: export X startup ids and use them for workspace matching (cherry picked from commit 28fda4c0d38907fab94dc7d82c9dcf0754748b4e) * swaybar: Prioritize hotspot events to bar bindings This is consistent with i3bar's behaviour, and for example, allows binding a command to button1, while still being able to click on tray icons or other zones on the bar's status line which may have their own bindings. E.g., in Sway, without this commit, this config. makes tray icons unclickable: bar { # ... bindsym button1 exec swaynag -m You_clicked_the_tray._Want_some_help? } But the same configuration in i3 (with i3-nagbar) keeps tray items clickable. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 53f9dbd424dc173a85c9f4cd30802259d38b1ef4) * swaybar: Make hotspots block bar release bindings The previous commit prioritized hotspots before bar bindings for press events, which matches i3's behaviour. However, since hotspots don't need to do any processing on release events, those were not handled, and simply fell through to `bindsym --release` bar bindings (if any). This is counter-intuitive, and doesn't match i3's behaviour. Instead in case a hotspot handles the press event, it should also handle the release event, doing nothing, but blocking the event from triggering a --release bar binding. E.g., in Sway, without this commit, this config. shows a text on tray clicks: bar { # ... bindsym --release button1 exec swaynag -m I_got_the_release_event. } But the same configuration in i3 (with i3-nagbar) doesn't show the text. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 94b69acf0d7b26ee5af2172300cb18473508da76) * build: drop unused wayland-egl dependency (cherry picked from commit 37e4a3d6370dc6ba2b0877d588845c06781e880e) * build: bump version to 1.8-rc1 * Fix build on Debian Stable (cherry picked from commit dca0bb5749bc16f91ab964fc1b06ebb9a453368f) * build: fix have_xwayland when xcb-icccm is not found xcb-icccm is required to build Xwayland support. Backported from commit d41f11e6bd8cef80f02dda4c66d4a31611aed753. * build: bump version to 1.8-rc2 * seat: Avoid sending redundant keymaps on reload When we reload the config, we reset every input device and re-apply configuration from the config file. This means that the keyboard keymap is updated at least once during config reload, more if the config file contains keyboard configuration. When they keyboard keymap changes and is updated through wlr_seat, the keymap ends up sent to every keyboard bound in every client, seemingly multiple times. On an x230 of mine with a keyboard layout set in the config file, I see 42 keymap events sent to foot on config reload. Reduce events from keyboard configurations by skipping all but the currently active keyboard for the seat, and by clearing the active keyboard during input manager device reset. After this change, I only see a single just-in-time keymap event. Fixes: https://github.com/swaywm/sway/issues/6654 * criteria: be lenient on window_role and instance too * build: bump version to 1.8-rc3 * commands/move: Warp cursor after moving workspace to another output This makes sway's behavior consistent with i3 when `mouse_warping` is set to any value besides `none`. Fixes #7027. (cherry picked from commit e3c63bf58d0744dfb436f0f38442ce3735e40f47) * seat: Set keyboard if seat keyboard is NULL sway sends wl_keyboard.enter on seat focus change and when a keyboard active on a seat is configured. If all keyboards are removed and a keyboard is added back without changing the focused client, no new notify event would be sent despite having keyboard focus. This could lead to key events without notify, which is a protocol violation. As a quick fix, when configuring a keyboard on a seat where no keyboard is currently active, activate the keyboard so that a focused surface will receive a notify event. Regressed by: e1b268af98edeb09e570e8855ef64f0719cbafe2 Closes: https://github.com/swaywm/sway/issues/7330 (cherry picked from commit 1ade0ce753dc5f588584f444ce80d27c3b1e4300) * build: bump version to 1.8-rc4 * swaynag: fix NULL font description The font description was only set if provided on the CLI. It was left NULL for the defaults and when reading from the config file. Closes: https://github.com/swaywm/sway/issues/7186 (cherry picked from commit fd0af78e43f4dd67a404f475c676b25ae38a4b82) * build: bump version to 1.8 * Removed other README languages * Fixed build issues * Removed alpha from render_data struct * Updated PKGBUILDs and COPR spec * Update sway/desktop/render.c Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com> * Fixed deco_data not being initialized properly * Replaced wlr_egl_(make|unset)_current with eglMakeCurrent * Added matrix_projection into fx_renderer Signed-off-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net> Co-authored-by: Simon Ser <contact@emersion.fr> Co-authored-by: Seth Barberee <seth.barberee@gmail.com> Co-authored-by: Thomas Hebb <tommyhebb@gmail.com> Co-authored-by: Nathan Schulte <nmschulte@gmail.com> Co-authored-by: xdavidwu <xdavidwuph@gmail.com> Co-authored-by: David Rosca <nowrep@gmail.com> Co-authored-by: David96 <david@hameipe.de> Co-authored-by: Kenny Levinsen <kl@kl.wtf> Co-authored-by: Aleksei Bavshin <alebastr89@gmail.com> Co-authored-by: Kirill Chibisov <contact@kchibisov.com> Co-authored-by: Tudor Brindus <me@tbrindus.ca> Co-authored-by: Patrick Hilhorst <git@hilhorst.be> Co-authored-by: Rouven Czerwinski <rouven@czerwinskis.de> Co-authored-by: Tobias Bengfort <tobias.bengfort@posteo.de> Co-authored-by: Ronan Pigott <rpigott@berkeley.edu> Co-authored-by: Kirill Primak <vyivel@eclair.cafe> Co-authored-by: Tuomas Yrjölä <mail@yrhki.fi> Co-authored-by: Kirill Primak <vyivel@posteo.net> Co-authored-by: Alexander Browne <elcste@users.noreply.github.com> Co-authored-by: Marco Rubin <20150305+Rubo3@users.noreply.github.com> Co-authored-by: Muhamed Hobi <woohoomoo2u@gmail.com> Co-authored-by: Simon Zeni <simon@bl4ckb0ne.ca> Co-authored-by: Nihal Jere <nihal@nihaljere.xyz> Co-authored-by: Alexander Gramiak <agrambot@gmail.com> Co-authored-by: Moon Sungjoon <sumoon@seoulsaram.org> Co-authored-by: Nicolas Avrutin <nicolas@avrutin.net> Co-authored-by: ndren <andreien@ctemplar.com> Co-authored-by: Bill Li <billli11hkb@gmail.com> Co-authored-by: Leonardo Hernández Hernández <leohdz172@protonmail.com> Co-authored-by: Oğuz Ersen <oguz@ersen.moe> Co-authored-by: Manuel Stoeckl <code@mstoeckl.com> Co-authored-by: Yasin Silavi <59373143+sttatusx@users.noreply.github.com> Co-authored-by: Daniel De Graaf <code@danieldg.net> Co-authored-by: kraftwerk28 <kefirchik3@gmail.com> Co-authored-by: Eskil <67291226+eschillus@users.noreply.github.com> Co-authored-by: Alice Carroll <git@alice-carroll.pet> Co-authored-by: Alan <51193876+Pound-Hash@users.noreply.github.com> Co-authored-by: Victor Makarov <vitja.makarov@gmail.com> Co-authored-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: -k <slowdive@me.com> Co-authored-by: Hongyi <61831273+FrozenArcher@users.noreply.github.com> Co-authored-by: Urey. Xue <urey.s.knowledge@gmail.com> Co-authored-by: LordRishav <75823494+LordRishav@users.noreply.github.com> Co-authored-by: Surendrajat <surendrajat@protonmail.com> Co-authored-by: Florian Franzen <Florian.Franzen@gmail.com> Co-authored-by: Greg Depoire--Ferrer <greg@gregdf.com> Co-authored-by: Thomas Jost <schnouki@schnouki.net> Co-authored-by: Hugo Osvaldo Barrera <hugo@barrera.io> Co-authored-by: zkldi <ktchidev@gmail.com> Co-authored-by: llyyr <llyyr.public@gmail.com> Co-authored-by: Baltazár Radics <baltazar.radics@gmail.com> Co-authored-by: Martin Michlmayr <tbm@cyrius.com> Co-authored-by: Filip Szczepański <jazz2rulez@gmail.com> Co-authored-by: Alex Maese <memaese@hotmail.com> Co-authored-by: マリウス <marius@xn--gckvb8fzb.com> Co-authored-by: Andri Yngvason <andri@yngvason.is> Co-authored-by: ohno418 <yutaro.ono.418@gmail.com> Co-authored-by: Ferdinand Schober <ferdinand.schober@fau.de> Co-authored-by: cparm <armelcadetpetit@gmail.com> Co-authored-by: Yaroslav de la Peña Smirnov <yps@yaroslavps.com> Co-authored-by: Alexander Orzechowski <orzechowski.alexander@gmail.com> Co-authored-by: pudiva chip líquida <pudiva@skylittlesystem.org> Co-authored-by: Puck Meerburg <puck@puckipedia.com> Co-authored-by: Callum Andrew <calcium@mailbox.org> Co-authored-by: Ronan Pigott <ronan@rjp.ie> Co-authored-by: Joan Bruguera <joanbrugueram@gmail.com> Co-authored-by: nerdopolis <bluescreen_avenger@verizon.net> Co-authored-by: Ankit Pandey <anpandey@protonmail.com> Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com>
2023-01-05 09:32:43 +11:00
#include <wlr/types/wlr_damage_ring.h>
2018-07-07 19:30:52 +10:00
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
2023-04-07 14:26:23 +10:00
#include <wlr/types/wlr_output_layout.h>
#include <wlr/util/box.h>
2018-07-07 19:30:52 +10:00
#include <wlr/util/region.h>
2023-04-07 14:26:23 +10:00
#include "config.h"
2023-04-07 14:26:23 +10:00
#include "log.h"
2018-07-07 19:30:52 +10:00
#include "sway/config.h"
#include "sway/desktop/fx_renderer/fx_framebuffer.h"
#include "sway/desktop/fx_renderer/fx_renderer.h"
2018-07-07 19:30:52 +10:00
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/root.h"
2018-07-07 19:30:52 +10:00
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
struct decoration_data get_undecorated_decoration_data() {
return (struct decoration_data) {
.alpha = 1.0f,
2022-12-07 16:10:11 +11:00
.dim = 0.0f,
.dim_color = config->dim_inactive_colors.unfocused,
.corner_radius = 0,
.saturation = 1.0f,
.has_titlebar = false,
.blur = false,
.discard_transparent = false,
.shadow = false,
.on_focused_workspace = true,
};
}
2023-04-28 08:50:36 +10:00
// TODO: Remove this ugly abomination with a complete border rework...
enum corner_location get_rotated_corner(enum corner_location corner_location,
enum wl_output_transform transform) {
if (corner_location == ALL || corner_location == NONE) {
return corner_location;
}
switch (transform) {
case WL_OUTPUT_TRANSFORM_NORMAL:
return corner_location;
case WL_OUTPUT_TRANSFORM_90:
return (corner_location + 1) % 4;
case WL_OUTPUT_TRANSFORM_180:
return (corner_location + 2) % 4;
case WL_OUTPUT_TRANSFORM_270:
return (corner_location + 3) % 4;
case WL_OUTPUT_TRANSFORM_FLIPPED:
return (corner_location + (1 - 2 * (corner_location % 2))) % 4;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
return (corner_location + (4 - 2 * (corner_location % 2))) % 4;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
return (corner_location + (3 - 2 * (corner_location % 2))) % 4;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
return (corner_location + (2 - 2 * (corner_location % 2))) % 4;
}
return corner_location;
}
static struct wlr_box get_monitor_box(struct wlr_output *output) {
int width, height;
wlr_output_transformed_resolution(output, &width, &height);
struct wlr_box monitor_box = { 0, 0, width, height };
return monitor_box;
}
// Adjust the box position when switching the workspace
static void adjust_box_to_workspace_offset(struct wlr_box *box,
struct decoration_data *deco_data, struct sway_output *output) {
float scroll_percent = output->workspace_scroll.percent;
2024-01-23 02:39:44 +11:00
int ws_dimen;
int *box_coord;
switch (output->workspace_scroll.direction) {
2024-01-23 02:39:44 +11:00
case SWIPE_GESTURE_DIRECTION_NONE:
return;
case SWIPE_GESTURE_DIRECTION_HORIZONTAL:
ws_dimen = output->width;
2024-01-23 02:39:44 +11:00
box_coord = &box->x;
break;
case SWIPE_GESTURE_DIRECTION_VERTICAL:
ws_dimen = output->height;
2024-01-23 02:39:44 +11:00
box_coord = &box->y;
break;
}
*box_coord -= ws_dimen * scroll_percent;
if (!deco_data->on_focused_workspace) {
if (scroll_percent > 0) {
2024-01-23 02:39:44 +11:00
*box_coord += ws_dimen;
} else if (scroll_percent < 0) {
2024-01-23 02:39:44 +11:00
*box_coord -= ws_dimen;
}
}
}
// Clips the rendered damage to the workspace region.
// Fixes containers being rendered across workspaces while switching.
static void adjust_damage_to_workspace_bounds(pixman_region32_t *damage,
struct decoration_data *deco_data, struct sway_output *output) {
float scale = output->wlr_output->scale;
float scroll_percent = output->workspace_scroll.percent;
2024-01-23 02:39:44 +11:00
int x = 0, y = 0;
int ws_dimen;
int *coord;
switch (output->workspace_scroll.direction) {
2024-01-23 02:39:44 +11:00
case SWIPE_GESTURE_DIRECTION_NONE:
return;
case SWIPE_GESTURE_DIRECTION_HORIZONTAL:
ws_dimen = output->width;
2024-01-23 02:39:44 +11:00
coord = &x;
break;
case SWIPE_GESTURE_DIRECTION_VERTICAL:
ws_dimen = output->height;
2024-01-23 02:39:44 +11:00
coord = &y;
break;
}
2024-01-23 02:39:44 +11:00
*coord = round(-ws_dimen * scroll_percent);
if (!deco_data->on_focused_workspace) {
if (scroll_percent > 0) {
2024-01-23 02:39:44 +11:00
*coord += ws_dimen;
} else if (scroll_percent < 0) {
2024-01-23 02:39:44 +11:00
*coord -= ws_dimen;
}
}
struct wlr_box monitor_box = get_monitor_box(output->wlr_output);
pixman_region32_intersect_rect(damage, damage,
monitor_box.x, monitor_box.y,
monitor_box.width, monitor_box.height);
2024-01-23 02:39:44 +11:00
pixman_region32_translate(damage, x * scale, y * scale);
}
/**
* Apply scale to a width or height.
*
* One does not simply multiply the width by the scale. We allow fractional
* scaling, which means the resulting scaled width might be a decimal.
* So we round it.
*
* But even this can produce undesirable results depending on the X or Y offset
* of the box. For example, with a scale of 1.5, a box with width=1 should not
* scale to 2px if its X coordinate is 1, because the X coordinate would have
* scaled to 2px.
*/
static int scale_length(int length, int offset, float scale) {
return round((offset + length) * scale) - round(offset * scale);
}
2018-07-07 19:30:52 +10:00
static void scissor_output(struct wlr_output *wlr_output,
pixman_box32_t *rect) {
2022-08-13 16:14:23 +10:00
struct sway_output *output = wlr_output->data;
struct fx_renderer *renderer = output->renderer;
2018-07-07 19:30:52 +10:00
assert(renderer);
struct wlr_box box = {
.x = rect->x1,
.y = rect->y1,
.width = rect->x2 - rect->x1,
.height = rect->y2 - rect->y1,
};
int ow, oh;
wlr_output_transformed_resolution(wlr_output, &ow, &oh);
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
2018-12-23 00:53:05 +11:00
wlr_box_transform(&box, &box, transform, ow, oh);
2018-07-07 19:30:52 +10:00
2022-08-13 16:14:23 +10:00
fx_renderer_scissor(&box);
2018-07-07 19:30:52 +10:00
}
2019-11-14 05:23:36 +11:00
static void set_scale_filter(struct wlr_output *wlr_output,
struct fx_texture *texture, enum scale_filter_mode scale_filter) {
glBindTexture(texture->target, texture->id);
2019-11-14 05:23:36 +11:00
switch (scale_filter) {
case SCALE_FILTER_LINEAR:
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2019-11-14 05:23:36 +11:00
break;
case SCALE_FILTER_NEAREST:
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2019-11-14 05:23:36 +11:00
break;
case SCALE_FILTER_DEFAULT:
case SCALE_FILTER_SMART:
assert(false); // unreachable
}
}
pixman_region32_t create_damage(const struct wlr_box damage_box, pixman_region32_t *output_damage) {
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, damage_box.x, damage_box.y,
damage_box.width, damage_box.height);
pixman_region32_intersect(&damage, &damage, output_damage);
return damage;
}
2018-07-07 19:30:52 +10:00
static void render_texture(struct wlr_output *wlr_output,
pixman_region32_t *output_damage, struct fx_texture *texture,
const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
const float matrix[static 9], struct decoration_data deco_data) {
struct sway_output *output = wlr_output->data;
struct fx_renderer *renderer = output->renderer;
pixman_region32_t damage = create_damage(*dst_box, output_damage);
2018-07-07 19:30:52 +10:00
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
2023-04-28 08:50:36 +10:00
// ensure the box is updated as per the output orientation
struct wlr_box transformed_box;
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
wlr_box_transform(&transformed_box, dst_box,
wlr_output_transform_invert(wlr_output->transform), width, height);
2018-07-07 19:30:52 +10:00
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
set_scale_filter(wlr_output, texture, output->scale_filter);
if (src_box != NULL) {
2023-04-28 08:50:36 +10:00
fx_render_subtexture_with_matrix(renderer, texture, src_box, &transformed_box,
matrix, deco_data);
} else {
2023-04-28 08:50:36 +10:00
fx_render_texture_with_matrix(renderer, texture, &transformed_box, matrix, deco_data);
}
2018-07-07 19:30:52 +10:00
}
damage_finish:
pixman_region32_fini(&damage);
}
/* Renders the blur for each damaged rect and swaps the buffer */
void render_blur_segments(struct fx_renderer *renderer,
const float matrix[static 9], pixman_region32_t* damage,
struct fx_framebuffer **buffer, struct blur_shader* shader,
const struct wlr_box *box, int blur_radius) {
if (*buffer == &renderer->effects_buffer) {
fx_framebuffer_bind(&renderer->effects_buffer_swapped);
} else {
fx_framebuffer_bind(&renderer->effects_buffer);
}
if (pixman_region32_not_empty(damage)) {
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
const pixman_box32_t box = rects[i];
struct wlr_box new_box = { box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1 };
fx_renderer_scissor(&new_box);
fx_render_blur(renderer, matrix, buffer, shader, &new_box, blur_radius);
}
}
if (*buffer != &renderer->effects_buffer) {
*buffer = &renderer->effects_buffer;
} else {
*buffer = &renderer->effects_buffer_swapped;
}
}
2023-04-28 08:50:36 +10:00
// Blurs the main_buffer content and returns the blurred framebuffer
struct fx_framebuffer *get_main_buffer_blur(struct fx_renderer *renderer, struct sway_output *output,
pixman_region32_t *original_damage, const struct wlr_box *box) {
2023-04-28 08:50:36 +10:00
struct wlr_output *wlr_output = output->wlr_output;
struct wlr_box monitor_box = get_monitor_box(wlr_output);
2023-04-28 08:50:36 +10:00
const enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
float matrix[9];
2023-04-28 08:50:36 +10:00
wlr_matrix_project_box(matrix, &monitor_box, transform, 0, wlr_output->transform_matrix);
float gl_matrix[9];
wlr_matrix_multiply(gl_matrix, renderer->projection, matrix);
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_copy(&damage, original_damage);
wlr_region_transform(&damage, &damage, transform, monitor_box.width, monitor_box.height);
wlr_region_expand(&damage, &damage, config_get_blur_size());
// Initially blur main_buffer content into the effects_buffers
struct fx_framebuffer *current_buffer = &renderer->wlr_buffer;
// Bind to blur framebuffer
fx_framebuffer_bind(&renderer->effects_buffer);
glBindTexture(renderer->wlr_buffer.texture.target, renderer->wlr_buffer.texture.id);
// damage region will be scaled, make a temp
pixman_region32_t tempDamage;
pixman_region32_init(&tempDamage);
int blur_radius = config->blur_params.radius;
int blur_passes = config->blur_params.num_passes;
// Downscale
for (int i = 0; i < blur_passes; ++i) {
wlr_region_scale(&tempDamage, &damage, 1.0f / (1 << (i + 1)));
render_blur_segments(renderer, gl_matrix, &tempDamage, &current_buffer,
&renderer->shaders.blur1, box, blur_radius);
}
// Upscale
for (int i = blur_passes - 1; i >= 0; --i) {
// when upsampling we make the region twice as big
wlr_region_scale(&tempDamage, &damage, 1.0f / (1 << i));
render_blur_segments(renderer, gl_matrix, &tempDamage, &current_buffer,
&renderer->shaders.blur2, box, blur_radius);
}
2024-01-04 04:38:44 +11:00
float blur_noise = config->blur_params.noise;
float blur_brightness = config->blur_params.brightness;
float blur_contrast = config->blur_params.contrast;
float blur_saturation = config->blur_params.saturation;
2024-01-05 18:47:43 +11:00
// Render additional blur effects like saturation, noise, contrast, etc...
if (config_should_parameters_blur_effects() && pixman_region32_not_empty(&damage)) {
if (current_buffer == &renderer->effects_buffer) {
fx_framebuffer_bind(&renderer->effects_buffer_swapped);
} else {
fx_framebuffer_bind(&renderer->effects_buffer);
}
2024-01-04 04:38:44 +11:00
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
const pixman_box32_t box = rects[i];
struct wlr_box new_box = { box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1 };
fx_renderer_scissor(&new_box);
fx_render_blur_effects(renderer, gl_matrix, &current_buffer, blur_noise,
blur_brightness, blur_contrast, blur_saturation);
}
2024-01-05 18:47:43 +11:00
if (current_buffer != &renderer->effects_buffer) {
current_buffer = &renderer->effects_buffer;
} else {
current_buffer = &renderer->effects_buffer_swapped;
}
2024-01-04 04:38:44 +11:00
}
pixman_region32_fini(&tempDamage);
pixman_region32_fini(&damage);
// Bind back to the default buffer
fx_framebuffer_bind(&renderer->wlr_buffer);
return current_buffer;
}
struct blur_stencil_data {
struct fx_texture *stencil_texture;
const struct wlr_fbox *stencil_src_box;
float *stencil_matrix;
};
void render_blur(bool optimized, struct sway_output *output,
pixman_region32_t *output_damage, const struct wlr_box *dst_box,
pixman_region32_t *opaque_region, struct decoration_data *deco_data,
struct blur_stencil_data *stencil_data) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
// Check if damage is inside of box rect
pixman_region32_t damage = create_damage(*dst_box, output_damage);
pixman_region32_t translucent_region;
pixman_region32_init(&translucent_region);
if (!pixman_region32_not_empty(&damage)) {
goto damage_finish;
}
// Gets the translucent region
pixman_box32_t surface_box = { 0, 0, dst_box->width, dst_box->height };
pixman_region32_copy(&translucent_region, opaque_region);
pixman_region32_inverse(&translucent_region, &translucent_region, &surface_box);
if (!pixman_region32_not_empty(&translucent_region)) {
goto damage_finish;
}
struct fx_framebuffer *buffer = &renderer->blur_buffer;
2023-05-20 03:24:37 +10:00
if (!buffer->texture.id || !optimized) {
pixman_region32_translate(&translucent_region, dst_box->x, dst_box->y);
pixman_region32_intersect(&translucent_region, &translucent_region, &damage);
// Render the blur into its own buffer
buffer = get_main_buffer_blur(renderer, output, &translucent_region, dst_box);
}
// Get a stencil of the window ignoring transparent regions
if (deco_data->discard_transparent) {
fx_renderer_scissor(NULL);
fx_renderer_stencil_mask_init();
render_texture(wlr_output, output_damage, stencil_data->stencil_texture, stencil_data->stencil_src_box,
dst_box, stencil_data->stencil_matrix, *deco_data);
fx_renderer_stencil_mask_close(true);
}
// Draw the blurred texture
struct wlr_box monitor_box = get_monitor_box(wlr_output);
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
float matrix[9];
wlr_matrix_project_box(matrix, &monitor_box, transform, 0.0, wlr_output->transform_matrix);
struct decoration_data blur_deco_data = get_undecorated_decoration_data();
blur_deco_data.corner_radius = deco_data->corner_radius;
blur_deco_data.has_titlebar = deco_data->has_titlebar;
render_texture(wlr_output, &damage, &buffer->texture, NULL, dst_box, matrix, blur_deco_data);
// Finish stenciling
if (deco_data->discard_transparent) {
fx_renderer_stencil_mask_fini();
}
damage_finish:
pixman_region32_fini(&damage);
pixman_region32_fini(&translucent_region);
}
// _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local
void render_box_shadow(struct sway_output *output, pixman_region32_t *output_damage,
2023-12-22 17:08:09 +11:00
const struct wlr_box *_box, const float color[static 4], float blur_sigma,
float corner_radius, float offset_x, float offset_y) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box));
2023-12-22 17:08:09 +11:00
box.x -= blur_sigma - offset_x;
box.y -= blur_sigma - offset_y;
box.width += 2 * blur_sigma;
box.height += 2 * blur_sigma;
pixman_region32_t damage = create_damage(box, output_damage);
// don't damage area behind window since we dont render it anyway
struct wlr_box inner_box;
memcpy(&inner_box, _box, sizeof(struct wlr_box));
inner_box.x += corner_radius;
inner_box.y += corner_radius;
inner_box.width -= 2 * corner_radius;
inner_box.height -= 2 * corner_radius;
pixman_region32_t inner_damage = create_damage(inner_box, output_damage);
pixman_region32_subtract(&damage, &damage, &inner_damage);
2023-12-22 17:08:09 +11:00
pixman_region32_fini(&inner_damage);
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
float matrix[9];
wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
wlr_output->transform_matrix);
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
2023-12-22 17:08:09 +11:00
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
// ensure the shadow_box is updated as per the output orientation
struct wlr_box transformed_shadow_box;
wlr_box_transform(&transformed_shadow_box, &box, transform, width, height);
// ensure the box is updated as per the output orientation
struct wlr_box transformed_box;
wlr_box_transform(&transformed_box, _box, transform, width, height);
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
2023-12-22 17:08:09 +11:00
fx_render_box_shadow(renderer, &transformed_shadow_box, &transformed_box,
color, matrix, corner_radius, blur_sigma);
}
damage_finish:
pixman_region32_fini(&damage);
}
static void render_surface_iterator(struct sway_output *output,
struct sway_view *view, struct wlr_surface *surface,
struct wlr_box *_box, void *_data) {
struct render_data *data = _data;
struct wlr_output *wlr_output = output->wlr_output;
pixman_region32_t *output_damage = data->damage;
struct wlr_texture *texture = wlr_surface_get_texture(surface);
if (!texture) {
return;
}
struct wlr_box proj_box = *_box;
2023-04-28 08:50:36 +10:00
if (view) {
adjust_box_to_workspace_offset(&proj_box, &data->deco_data, output);
}
scale_box(&proj_box, wlr_output->scale);
float matrix[9];
enum wl_output_transform transform = wlr_output_transform_invert(surface->current.transform);
wlr_matrix_project_box(matrix, &proj_box, transform, 0.0, wlr_output->transform_matrix);
struct wlr_box dst_box = *_box;
struct wlr_box *clip_box = data->clip_box;
if (clip_box != NULL) {
dst_box.width = fmin(dst_box.width, clip_box->width);
dst_box.height = fmin(dst_box.height, clip_box->height);
dst_box.x = fmax(dst_box.x, clip_box->x);
dst_box.y = fmax(dst_box.y, clip_box->y);
}
if (view) {
adjust_box_to_workspace_offset(&dst_box, &data->deco_data, output);
}
scale_box(&dst_box, wlr_output->scale);
struct decoration_data deco_data = data->deco_data;
deco_data.corner_radius *= wlr_output->scale;
struct wlr_fbox src_box;
wlr_surface_get_buffer_source_box(surface, &src_box);
struct fx_texture fx_texture = fx_texture_from_wlr_texture(texture);
2023-05-20 03:24:37 +10:00
// render blur
bool is_subsurface = view ? view->surface != surface : false;
if (deco_data.blur && config_should_parameters_blur() && !is_subsurface) {
pixman_region32_t opaque_region;
pixman_region32_init(&opaque_region);
bool has_alpha = false;
if (deco_data.alpha < 1.0 || deco_data.dim_color[3] < 1.0) {
has_alpha = true;
pixman_region32_union_rect(&opaque_region, &opaque_region, 0, 0, 0, 0);
} else {
has_alpha = !surface->opaque;
pixman_region32_copy(&opaque_region, &surface->opaque_region);
}
if (has_alpha) {
struct wlr_box monitor_box = get_monitor_box(wlr_output);
wlr_box_transform(&monitor_box, &monitor_box,
wlr_output_transform_invert(wlr_output->transform), monitor_box.width, monitor_box.height);
struct blur_stencil_data stencil_data = { &fx_texture, &src_box, matrix };
bool should_optimize_blur = view ? !container_is_floating_or_child(view->container) || config->blur_xray : false;
render_blur(should_optimize_blur, output, output_damage, &dst_box,
&opaque_region, &deco_data, &stencil_data);
}
pixman_region32_fini(&opaque_region);
}
deco_data.discard_transparent = false;
// Render surface texture
render_texture(wlr_output, output_damage, &fx_texture, &src_box, &dst_box,
matrix, deco_data);
wlr_presentation_surface_sampled_on_output(server.presentation, surface,
wlr_output);
}
// view will be NULL every time
static void render_layer_iterator(struct sway_output *output,
struct sway_view *view, struct wlr_surface *surface,
struct wlr_box *_box, void *_data) {
struct render_data *data = _data;
struct decoration_data deco_data = data->deco_data;
// Ignore effects if this is a subsurface
if (!wlr_surface_is_layer_surface(surface)) {
deco_data = get_undecorated_decoration_data();
}
// render the layer's surface
render_surface_iterator(output, view, surface, _box, _data);
// render shadow
if (deco_data.shadow && config_should_parameters_shadow()) {
int corner_radius = deco_data.corner_radius *= output->wlr_output->scale;
2023-12-22 17:08:09 +11:00
int offset_x = config->shadow_offset_x * output->wlr_output->scale;
int offset_y = config->shadow_offset_y * output->wlr_output->scale;
scale_box(_box, output->wlr_output->scale);
render_box_shadow(output, data->damage, _box, config->shadow_color,
2023-12-22 17:08:09 +11:00
config->shadow_blur_sigma, corner_radius, offset_x, offset_y);
}
}
static void render_layer_toplevel(struct sway_output *output,
2018-07-07 19:30:52 +10:00
pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = {
.damage = damage,
.deco_data = get_undecorated_decoration_data(),
2018-07-07 19:30:52 +10:00
};
output_layer_for_each_toplevel_surface(output, layer_surfaces,
render_layer_iterator, &data);
}
static void render_layer_popups(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = {
.damage = damage,
.deco_data = get_undecorated_decoration_data(),
};
output_layer_for_each_popup_surface(output, layer_surfaces,
render_layer_iterator, &data);
2018-07-07 19:30:52 +10:00
}
2018-11-18 10:33:06 +11:00
#if HAVE_XWAYLAND
2018-07-07 19:30:52 +10:00
static void render_unmanaged(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *unmanaged) {
struct render_data data = {
.damage = damage,
.deco_data = get_undecorated_decoration_data(),
2018-07-07 19:30:52 +10:00
};
output_unmanaged_for_each_surface(output, unmanaged,
render_surface_iterator, &data);
2018-07-07 19:30:52 +10:00
}
#endif
2018-07-07 19:30:52 +10:00
static void render_drag_icons(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *drag_icons) {
struct render_data data = {
.damage = damage,
.deco_data = get_undecorated_decoration_data(),
2018-07-07 19:30:52 +10:00
};
output_drag_icons_for_each_surface(output, drag_icons,
render_surface_iterator, &data);
2018-07-07 19:30:52 +10:00
}
void render_whole_output(struct fx_renderer *renderer, struct wlr_output *wlr_output,
2023-05-15 15:11:09 +10:00
pixman_region32_t *output_damage, struct fx_texture *texture) {
struct wlr_box monitor_box = get_monitor_box(wlr_output);
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
float matrix[9];
wlr_matrix_project_box(matrix, &monitor_box, transform, 0.0, wlr_output->transform_matrix);
2023-05-15 15:11:09 +10:00
render_texture(wlr_output, output_damage, texture, NULL, &monitor_box, matrix, get_undecorated_decoration_data());
}
void render_output_blur(struct sway_output *output, pixman_region32_t *damage) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
struct wlr_box monitor_box = get_monitor_box(wlr_output);
pixman_region32_t fake_damage;
pixman_region32_init_rect(&fake_damage, 0, 0, monitor_box.width, monitor_box.height);
// Render the blur
struct fx_framebuffer *buffer = get_main_buffer_blur(renderer, output, &fake_damage, &monitor_box);
// Render the newly blurred content into the blur_buffer
fx_framebuffer_update(&renderer->blur_buffer,
output->renderer->viewport_width, output->renderer->viewport_height);
fx_framebuffer_bind(&renderer->blur_buffer);
// Clear the damaged region of the blur_buffer
float clear_color[] = { 0, 0, 0, 0 };
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
fx_renderer_clear(clear_color);
}
render_whole_output(renderer, wlr_output, &fake_damage, &buffer->texture);
fx_framebuffer_bind(&renderer->wlr_buffer);
pixman_region32_fini(&fake_damage);
renderer->blur_buffer_dirty = false;
}
// _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local
void render_rect(struct sway_output *output,
2018-07-07 19:30:52 +10:00
pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
2018-07-07 19:30:52 +10:00
struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box));
box.x -= output->lx * wlr_output->scale;
box.y -= output->ly * wlr_output->scale;
2018-07-07 19:30:52 +10:00
pixman_region32_t damage = create_damage(box, output_damage);
2018-07-07 19:30:52 +10:00
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
2022-11-11 17:19:02 +11:00
fx_render_rect(renderer, &box, color, wlr_output->transform_matrix);
}
damage_finish:
pixman_region32_fini(&damage);
}
void render_rounded_rect(struct sway_output *output, pixman_region32_t *output_damage,
const struct wlr_box *_box, float color[static 4], int corner_radius,
enum corner_location corner_location) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
2022-11-11 17:19:02 +11:00
struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box));
box.x -= output->lx * wlr_output->scale;
box.y -= output->ly * wlr_output->scale;
pixman_region32_t damage = create_damage(box, output_damage);
2022-11-11 17:19:02 +11:00
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
2023-04-28 08:50:36 +10:00
float matrix[9];
wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
wlr_output->transform_matrix);
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
// ensure the box is updated as per the output orientation
struct wlr_box transformed_box;
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
wlr_box_transform(&transformed_box, &box, transform, width, height);
corner_location = get_rotated_corner(corner_location, transform);
2022-11-11 17:19:02 +11:00
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
2023-04-28 08:50:36 +10:00
fx_render_rounded_rect(renderer, &transformed_box, color, matrix,
2022-11-11 17:19:02 +11:00
corner_radius, corner_location);
2018-07-07 19:30:52 +10:00
}
damage_finish:
pixman_region32_fini(&damage);
}
// _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local
void render_border_corner(struct sway_output *output, pixman_region32_t *output_damage,
2022-11-11 17:19:02 +11:00
const struct wlr_box *_box, const float color[static 4], int corner_radius,
int border_thickness, enum corner_location corner_location) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box));
box.x -= output->lx * wlr_output->scale;
box.y -= output->ly * wlr_output->scale;
pixman_region32_t damage = create_damage(box, output_damage);
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
2023-04-28 08:50:36 +10:00
float matrix[9];
wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
wlr_output->transform_matrix);
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
// ensure the box is updated as per the output orientation
struct wlr_box transformed_box;
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
wlr_box_transform(&transformed_box, &box, transform, width, height);
corner_location = get_rotated_corner(corner_location, transform);
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
2023-04-28 08:50:36 +10:00
fx_render_border_corner(renderer, &transformed_box, color, matrix,
corner_location, corner_radius, border_thickness);
}
damage_finish:
pixman_region32_fini(&damage);
}
void premultiply_alpha(float color[4], float opacity) {
2018-07-07 19:30:52 +10:00
color[3] *= opacity;
color[0] *= color[3];
color[1] *= color[3];
color[2] *= color[3];
}
2022-11-11 17:19:02 +11:00
static void render_view_toplevels(struct sway_view *view, struct sway_output *output,
pixman_region32_t *damage, struct decoration_data deco_data) {
2018-07-07 19:30:52 +10:00
struct render_data data = {
.damage = damage,
.deco_data = deco_data,
2018-07-07 19:30:52 +10:00
};
// Clip the window to its view size, ignoring CSD
struct wlr_box clip_box;
struct sway_container_state state = view->container->current;
clip_box.x = state.x - output->lx;
clip_box.y = state.y - output->ly;
clip_box.width = state.width;
clip_box.height = state.height;
bool smart = config->hide_edge_borders_smart == ESMART_ON ||
(config->hide_edge_borders_smart == ESMART_NO_GAPS &&
!gaps_to_edge(view));
if (state.fullscreen_mode == FULLSCREEN_NONE
&& (state.border == B_PIXEL || state.border == B_NORMAL)
&& !smart) {
clip_box.x += state.border_thickness;
clip_box.width -= state.border_thickness * 2;
if (deco_data.has_titlebar) {
// Shift the box downward to compensate for the titlebar
int titlebar_thickness = container_titlebar_height();
clip_box.y += titlebar_thickness;
clip_box.height -= state.border_thickness + titlebar_thickness;
} else {
// Regular border
clip_box.y += state.border_thickness;
clip_box.height -= state.border_thickness * 2;
}
}
data.clip_box = &clip_box;
output_view_for_each_surface(output, view, render_surface_iterator, &data);
}
static void render_view_popups(struct sway_view *view, struct sway_output *output,
pixman_region32_t *damage, struct decoration_data deco_data) {
struct render_data data = {
.damage = damage,
.deco_data = deco_data,
};
output_view_for_each_popup_surface(output, view,
render_surface_iterator, &data);
2018-07-07 19:30:52 +10:00
}
2022-11-11 17:19:02 +11:00
static void render_saved_view(struct sway_view *view, struct sway_output *output,
pixman_region32_t *damage, struct decoration_data deco_data) {
2018-07-07 19:30:52 +10:00
struct wlr_output *wlr_output = output->wlr_output;
if (wl_list_empty(&view->saved_buffers)) {
2018-07-07 19:30:52 +10:00
return;
}
struct sway_saved_buffer *saved_buf;
wl_list_for_each(saved_buf, &view->saved_buffers, link) {
if (!saved_buf->buffer->texture) {
continue;
}
2018-07-07 19:30:52 +10:00
struct wlr_box proj_box = {
.x = saved_buf->x - view->saved_geometry.x - output->lx,
.y = saved_buf->y - view->saved_geometry.y - output->ly,
.width = saved_buf->width,
.height = saved_buf->height,
};
struct wlr_box output_box = {
.width = output->width,
.height = output->height,
};
struct wlr_box intersection;
bool intersects = wlr_box_intersection(&intersection, &output_box, &proj_box);
if (!intersects) {
continue;
}
2018-07-07 19:30:52 +10:00
struct wlr_box dst_box = proj_box;
scale_box(&proj_box, wlr_output->scale);
2018-07-07 19:30:52 +10:00
float matrix[9];
enum wl_output_transform transform = wlr_output_transform_invert(saved_buf->transform);
wlr_matrix_project_box(matrix, &proj_box, transform, 0, wlr_output->transform_matrix);
2018-07-07 19:30:52 +10:00
struct sway_container_state state = view->container->current;
dst_box.x = state.x - output->lx;
dst_box.y = state.y - output->ly;
dst_box.width = state.width;
dst_box.height = state.height;
if (state.border == B_PIXEL || state.border == B_NORMAL) {
dst_box.x += state.border_thickness;
dst_box.width -= state.border_thickness * 2;
if (deco_data.has_titlebar) {
// Shift the box downward to compensate for the titlebar
int titlebar_thickness = container_titlebar_height();
dst_box.y += titlebar_thickness;
dst_box.height -= state.border_thickness + titlebar_thickness;
} else {
// Regular border
dst_box.y += state.border_thickness;
dst_box.height -= state.border_thickness * 2;
}
}
scale_box(&dst_box, wlr_output->scale);
deco_data.corner_radius *= wlr_output->scale;
struct fx_texture fx_texture = fx_texture_from_wlr_texture(saved_buf->buffer->texture);
// render blur
if (deco_data.blur && config_should_parameters_blur()) {
struct wlr_gles2_texture_attribs attribs;
wlr_gles2_texture_get_attribs(saved_buf->buffer->texture, &attribs);
if (deco_data.alpha < 1.0 || attribs.has_alpha) {
pixman_region32_t opaque_region;
pixman_region32_init(&opaque_region);
pixman_region32_union_rect(&opaque_region, &opaque_region, 0, 0, 0, 0);
struct wlr_box monitor_box = get_monitor_box(wlr_output);
wlr_box_transform(&monitor_box, &monitor_box,
wlr_output_transform_invert(wlr_output->transform), monitor_box.width, monitor_box.height);
struct blur_stencil_data stencil_data = { &fx_texture, &saved_buf->source_box, matrix };
bool should_optimize_blur = !container_is_floating_or_child(view->container) || config->blur_xray;
render_blur(should_optimize_blur, output, damage, &dst_box, &opaque_region,
&deco_data, &stencil_data);
pixman_region32_fini(&opaque_region);
}
}
deco_data.discard_transparent = false;
// Render saved surface texture
render_texture(wlr_output, damage, &fx_texture,
&saved_buf->source_box, &dst_box, matrix, deco_data);
}
// FIXME: we should set the surface that this saved buffer originates from
// as sampled here.
// https://github.com/swaywm/sway/pull/4465#discussion_r321082059
2018-07-07 19:30:52 +10:00
}
/**
* Render a view's surface, shadow, and left/bottom/right borders.
2018-07-07 19:30:52 +10:00
*/
static void render_view(struct sway_output *output, pixman_region32_t *damage,
struct sway_container *con, struct border_colors *colors,
struct decoration_data deco_data) {
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct sway_view *view = con->view;
struct sway_container_state *state = &con->current;
pixman_region32_t output_damage;
pixman_region32_init(&output_damage);
pixman_region32_copy(&output_damage, damage);
adjust_damage_to_workspace_bounds(&output_damage, &deco_data, output);
// render view
if (!wl_list_empty(&view->saved_buffers)) {
render_saved_view(view, output, &output_damage, deco_data);
} else if (view->surface) {
render_view_toplevels(view, output, &output_damage, deco_data);
2018-07-07 19:30:52 +10:00
}
if (state->border == B_CSD && !config->shadows_on_csd_enabled) {
goto end;
return;
}
2023-04-19 09:04:00 +10:00
float output_scale = output->wlr_output->scale;
struct wlr_box box;
// render shadow
if (con->shadow_enabled && config->shadow_blur_sigma > 0 && config->shadow_color[3] > 0.0) {
box.x = floor(state->x) - output->lx;
box.y = floor(state->y) - output->ly;
2023-04-19 09:04:00 +10:00
box.width = state->width;
box.height = state->height;
adjust_box_to_workspace_offset(&box, &deco_data, output);
2023-04-19 09:04:00 +10:00
scale_box(&box, output_scale);
int scaled_corner_radius = deco_data.corner_radius == 0 ?
0 : (deco_data.corner_radius + state->border_thickness) * output_scale;
float* shadow_color = view_is_urgent(view) || state->focused ?
config->shadow_color : config->shadow_inactive_color;
2023-12-22 17:08:09 +11:00
int offset_x = config->shadow_offset_x * output->wlr_output->scale;
int offset_y = config->shadow_offset_y * output->wlr_output->scale;
render_box_shadow(output, &output_damage, &box, shadow_color, config->shadow_blur_sigma,
2023-12-22 17:08:09 +11:00
scaled_corner_radius, offset_x, offset_y);
}
if (state->border == B_NONE || state->border == B_CSD) {
goto end;
return;
}
2018-07-07 19:30:52 +10:00
float color[4];
if (state->border_left) {
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, deco_data.alpha);
box.x = floor(state->x);
box.y = floor(state->content_y);
box.width = state->border_thickness;
box.height = state->content_height;
adjust_box_to_workspace_offset(&box, &deco_data, output);
// adjust sizing for rounded border corners
if (deco_data.corner_radius) {
if (!deco_data.has_titlebar) {
box.y += deco_data.corner_radius;
box.height -= 2 * deco_data.corner_radius;
} else {
box.height -= deco_data.corner_radius;
}
}
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
}
2018-07-07 19:30:52 +10:00
list_t *siblings = container_get_current_siblings(con);
enum sway_container_layout layout =
container_current_parent_layout(con);
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (state->border_right) {
if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_HORIZ) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
2018-07-07 19:30:52 +10:00
}
premultiply_alpha(color, deco_data.alpha);
box.x = floor(state->content_x + state->content_width);
box.y = floor(state->content_y);
box.width = state->border_thickness;
box.height = state->content_height;
adjust_box_to_workspace_offset(&box, &deco_data, output);
// adjust sizing for rounded border corners
if (deco_data.corner_radius) {
if (!deco_data.has_titlebar) {
box.y += deco_data.corner_radius;
box.height -= 2 * deco_data.corner_radius;
} else {
box.height -= deco_data.corner_radius;
}
}
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
}
2018-07-07 19:30:52 +10:00
if (state->border_bottom) {
if (!container_is_current_floating(con) && siblings->length == 1 && layout == L_VERT) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
2018-07-07 19:30:52 +10:00
}
premultiply_alpha(color, deco_data.alpha);
box.x = floor(state->x);
box.y = floor(state->content_y + state->content_height);
box.width = state->width;
box.height = state->border_thickness;
adjust_box_to_workspace_offset(&box, &deco_data, output);
// adjust sizing for rounded border corners
if (deco_data.corner_radius) {
box.x += deco_data.corner_radius + state->border_thickness;
box.width -= 2 * (deco_data.corner_radius + state->border_thickness);
}
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
// rounded bottom left & bottom right border corners
if (deco_data.corner_radius) {
int size = 2 * (deco_data.corner_radius + state->border_thickness);
int scaled_thickness = state->border_thickness * output_scale;
int scaled_corner_radius = deco_data.corner_radius * output_scale;
if (state->border_left) {
box.width = size;
box.height = size;
box.x = floor(state->x);
box.y = floor(state->y + state->height - size);
adjust_box_to_workspace_offset(&box, &deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
scaled_corner_radius, scaled_thickness, BOTTOM_LEFT);
}
if (state->border_right) {
box.width = size;
box.height = size;
box.x = floor(state->x + state->width - size);
box.y = floor(state->y + state->height - size);
adjust_box_to_workspace_offset(&box, &deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
scaled_corner_radius, scaled_thickness, BOTTOM_RIGHT);
}
}
2018-07-07 19:30:52 +10:00
}
end:
pixman_region32_fini(&output_damage);
2018-07-07 19:30:52 +10:00
}
/**
* Render a titlebar.
*
* Care must be taken not to render over the same pixel multiple times,
* otherwise the colors will be incorrect when using opacity.
*
* The height is: 1px border, 3px padding, font height, 3px padding, 1px border
* The left side is: 1px border, 2px padding, title
2018-07-07 19:30:52 +10:00
*/
static void render_titlebar(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, int x, int y,
int width, struct border_colors *colors, struct decoration_data con_deco_data,
enum corner_location corner_location, struct wlr_texture *title_texture,
struct wlr_texture *marks_texture) {
2018-07-07 19:30:52 +10:00
struct wlr_box box;
float color[4];
float output_scale = output->wlr_output->scale;
double output_x = output->lx;
double output_y = output->ly;
int titlebar_border_thickness = config->titlebar_border_thickness;
int titlebar_h_padding = config->titlebar_h_padding;
int titlebar_v_padding = config->titlebar_v_padding;
enum alignment title_align = config->title_align;
// value by which all heights should be adjusted to counteract removed bottom border
int bottom_border_compensation = config->titlebar_separator ? 0 : titlebar_border_thickness;
2022-11-11 17:19:02 +11:00
pixman_region32_t output_damage;
pixman_region32_init(&output_damage);
pixman_region32_copy(&output_damage, damage);
adjust_damage_to_workspace_bounds(&output_damage, &con_deco_data, output);
float alpha = con_deco_data.alpha;
int corner_radius = con_deco_data.corner_radius;
if (corner_location == NONE) {
corner_radius = 0;
}
2018-07-07 19:30:52 +10:00
// Single pixel bar above title
memcpy(&color, colors->border, sizeof(float) * 4);
premultiply_alpha(color, alpha);
box.x = x;
2018-07-07 19:30:52 +10:00
box.y = y;
box.width = width;
if (corner_radius) {
if (corner_location != TOP_RIGHT) {
box.x += corner_radius;
}
if (corner_location == ALL) {
box.width -= corner_radius * 2;
} else {
box.width -= corner_radius;
}
} else {
box.x += titlebar_border_thickness;
box.width -= titlebar_border_thickness * 2;
}
box.height = titlebar_border_thickness;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
2018-07-07 19:30:52 +10:00
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
// Single pixel bar below title
if (config->titlebar_separator) {
box.x = x;
box.y = y + container_titlebar_height() - titlebar_border_thickness;
box.width = width;
box.height = titlebar_border_thickness;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
}
2018-07-07 19:30:52 +10:00
2022-11-11 17:19:02 +11:00
// Single pixel bar left edge
box.x = x;
box.y = y;
box.width = titlebar_border_thickness;
box.height = container_titlebar_height() + bottom_border_compensation;
if (corner_radius && corner_location != TOP_RIGHT) {
box.height -= corner_radius;
box.y += corner_radius;
}
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
2022-11-11 17:19:02 +11:00
// Single pixel bar right edge
box.x = x + width - titlebar_border_thickness;
box.y = y;
box.width = titlebar_border_thickness;
box.height = container_titlebar_height() + bottom_border_compensation;
if (corner_radius && corner_location != TOP_LEFT) {
box.height -= corner_radius;
box.y += corner_radius;
}
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
2022-11-11 17:19:02 +11:00
// if corner_radius: single pixel corners
if (corner_radius) {
// left corner
if (corner_location != TOP_RIGHT) {
box.x = x;
box.y = y;
box.width = corner_radius * 2;
box.height = corner_radius * 2;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
corner_radius, titlebar_border_thickness, TOP_LEFT);
}
2022-11-11 17:19:02 +11:00
// right corner
if (corner_location != TOP_LEFT) {
box.x = x + width - corner_radius * 2;
box.y = y;
box.width = corner_radius * 2;
box.height = corner_radius * 2;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
corner_radius, titlebar_border_thickness, TOP_RIGHT);
}
2022-11-11 17:19:02 +11:00
}
int inner_x = x - output_x + titlebar_h_padding;
int bg_y = y + titlebar_border_thickness;
size_t inner_width = width - titlebar_h_padding * 2;
// output-buffer local
int ob_inner_x = round(inner_x * output_scale);
int ob_inner_width = scale_length(inner_width, inner_x, output_scale);
int ob_bg_height = scale_length(
(titlebar_v_padding - titlebar_border_thickness) * 2 +
config->font_height, bg_y, output_scale);
2018-07-07 19:30:52 +10:00
// title marks textures should have no eyecandy
struct decoration_data deco_data = get_undecorated_decoration_data();
deco_data.alpha = alpha;
2018-07-07 19:30:52 +10:00
// Marks
int ob_marks_x = 0; // output-buffer-local
int ob_marks_width = 0; // output-buffer-local
2018-07-07 19:30:52 +10:00
if (config->show_marks && marks_texture) {
struct wlr_box texture_box = {
.width = marks_texture->width,
.height = marks_texture->height,
};
ob_marks_width = texture_box.width;
// The marks texture might be shorter than the config->font_height, in
// which case we need to pad it as evenly as possible above and below.
int ob_padding_total = ob_bg_height - texture_box.height;
int ob_padding_above = floor(ob_padding_total / 2.0);
int ob_padding_below = ceil(ob_padding_total / 2.0);
// Render texture. If the title is on the right, the marks will be on
// the left. Otherwise, they will be on the right.
if (title_align == ALIGN_RIGHT || texture_box.width > ob_inner_width) {
texture_box.x = ob_inner_x;
} else {
texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
}
ob_marks_x = texture_box.x;
texture_box.y = round((bg_y - output_y) * output_scale) +
ob_padding_above;
2018-07-07 19:30:52 +10:00
float matrix[9];
wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix);
if (ob_inner_width < texture_box.width) {
texture_box.width = ob_inner_width;
2018-07-07 19:30:52 +10:00
}
struct fx_texture fx_texture = fx_texture_from_wlr_texture(marks_texture);
render_texture(output->wlr_output, &output_damage, &fx_texture,
NULL, &texture_box, matrix, deco_data);
2018-07-07 19:30:52 +10:00
// Padding above
memcpy(&color, colors->background, sizeof(float) * 4);
premultiply_alpha(color, alpha);
box.x = texture_box.x + round(output_x * output_scale);
box.y = round((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width;
box.height = ob_padding_above;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
render_rect(output, &output_damage, &box, color);
// Padding below
box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below + bottom_border_compensation;
adjust_box_to_workspace_offset(&box, &con_deco_data, output);
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
}
// Title text
int ob_title_x = 0; // output-buffer-local
int ob_title_width = 0; // output-buffer-local
2018-07-07 19:30:52 +10:00
if (title_texture) {
struct wlr_box texture_box = {
.width = title_texture->width,
.height = title_texture->height,
};
// The effective output may be NULL when con is not on any output.
// This can happen because we render all children of containers,
// even those that are out of the bounds of any output.
struct sway_output *effective = container_get_effective_output(con);
float title_scale = effective ? effective->wlr_output->scale : output_scale;
texture_box.width = texture_box.width * output_scale / title_scale;
texture_box.height = texture_box.height * output_scale / title_scale;
ob_title_width = texture_box.width;
// The title texture might be shorter than the config->font_height,
// in which case we need to pad it above and below.
int ob_padding_above = round((titlebar_v_padding -
titlebar_border_thickness) * output_scale);
int ob_padding_below = ob_bg_height - ob_padding_above -
texture_box.height;
// Render texture
if (texture_box.width > ob_inner_width - ob_marks_width) {
texture_box.x = (title_align == ALIGN_RIGHT && ob_marks_width)
? ob_marks_x + ob_marks_width : ob_inner_x;
} else if (title_align == ALIGN_LEFT) {
texture_box.x = ob_inner_x;
} else if (title_align == ALIGN_CENTER) {
// If there are marks visible, center between the edge and marks.
// Otherwise, center in the inner area.
if (ob_marks_width) {
texture_box.x = (ob_inner_x + ob_marks_x) / 2
- texture_box.width / 2;
} else {
texture_box.x = ob_inner_x + ob_inner_width / 2
- texture_box.width / 2;
}
} else {
texture_box.x = ob_inner_x + ob_inner_width - texture_box.width;
}
ob_title_x = texture_box.x;
texture_box.y =
round((bg_y - output_y) * output_scale) + ob_padding_above;
2018-07-07 19:30:52 +10:00
float matrix[9];
wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix);
if (ob_inner_width - ob_marks_width < texture_box.width) {
texture_box.width = ob_inner_width - ob_marks_width;
2018-07-07 19:30:52 +10:00
}
struct fx_texture fx_texture = fx_texture_from_wlr_texture(title_texture);
render_texture(output->wlr_output, &output_damage, &fx_texture,
NULL, &texture_box, matrix, deco_data);
2018-07-07 19:30:52 +10:00
// Padding above
memcpy(&color, colors->background, sizeof(float) * 4);
premultiply_alpha(color, alpha);
box.x = texture_box.x + round(output_x * output_scale);
box.y = round((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width;
box.height = ob_padding_above;
render_rect(output, &output_damage, &box, color);
// Padding below
box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below + bottom_border_compensation;
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
}
// Determine the left + right extends of the textures (output-buffer local)
int ob_left_x, ob_left_width, ob_right_x, ob_right_width;
if (ob_title_width == 0 && ob_marks_width == 0) {
ob_left_x = ob_inner_x;
ob_left_width = 0;
ob_right_x = ob_inner_x;
ob_right_width = 0;
} else if (ob_title_x < ob_marks_x) {
ob_left_x = ob_title_x;
ob_left_width = ob_title_width;
ob_right_x = ob_marks_x;
ob_right_width = ob_marks_width;
} else {
ob_left_x = ob_marks_x;
ob_left_width = ob_marks_width;
ob_right_x = ob_title_x;
ob_right_width = ob_title_width;
}
if (ob_left_x < ob_inner_x) {
ob_left_x = ob_inner_x;
} else if (ob_left_x + ob_left_width > ob_right_x + ob_right_width) {
ob_right_x = ob_left_x;
ob_right_width = ob_left_width;
}
2018-07-07 19:30:52 +10:00
// Filler between title and marks
box.width = ob_right_x - ob_left_x - ob_left_width;
2018-07-07 19:30:52 +10:00
if (box.width > 0) {
box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
box.y = round(bg_y * output_scale);
box.height = ob_bg_height + bottom_border_compensation;
render_rect(output, &output_damage, &box, color);
2018-07-07 19:30:52 +10:00
}
// Padding on left side
box.x = x + titlebar_border_thickness;
box.y = y + titlebar_border_thickness;
box.width = titlebar_h_padding - titlebar_border_thickness;
box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
config->font_height + bottom_border_compensation;
2018-07-07 19:30:52 +10:00
scale_box(&box, output_scale);
int left_x = ob_left_x + round(output_x * output_scale);
if (box.x + box.width < left_x) {
box.width += left_x - box.x - box.width;
}
if (corner_radius && corner_location != TOP_RIGHT) {
render_rounded_rect(output, &output_damage, &box, color, corner_radius, TOP_LEFT);
2022-11-11 17:19:02 +11:00
} else {
render_rect(output, &output_damage, &box, color);
2022-11-11 17:19:02 +11:00
}
2018-07-07 19:30:52 +10:00
// Padding on right side
box.x = x + width - titlebar_h_padding;
box.y = y + titlebar_border_thickness;
box.width = titlebar_h_padding - titlebar_border_thickness;
box.height = (titlebar_v_padding - titlebar_border_thickness) * 2 +
config->font_height + bottom_border_compensation;
2018-07-07 19:30:52 +10:00
scale_box(&box, output_scale);
int right_rx = ob_right_x + ob_right_width + round(output_x * output_scale);
if (right_rx < box.x) {
box.width += box.x - right_rx;
box.x = right_rx;
}
if (corner_radius && corner_location != TOP_LEFT) {
render_rounded_rect(output, &output_damage, &box, color, corner_radius, TOP_RIGHT);
2022-11-11 17:19:02 +11:00
} else {
render_rect(output, &output_damage, &box, color);
2022-11-11 17:19:02 +11:00
}
pixman_region32_fini(&output_damage);
2018-07-07 19:30:52 +10:00
}
/**
* Render the top border line for a view using "border pixel".
*/
static void render_top_border(struct sway_output *output,
pixman_region32_t *damage, struct sway_container_state *state,
struct border_colors *colors, struct decoration_data border_deco_data) {
2018-07-07 19:30:52 +10:00
if (!state->border_top) {
return;
}
struct wlr_box box;
float color[4];
float output_scale = output->wlr_output->scale;
pixman_region32_t output_damage;
pixman_region32_init(&output_damage);
pixman_region32_copy(&output_damage, damage);
adjust_damage_to_workspace_bounds(&output_damage, &border_deco_data, output);
float alpha = border_deco_data.alpha;
int corner_radius = border_deco_data.corner_radius;
2018-07-07 19:30:52 +10:00
// Child border - top edge
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, alpha);
box.x = floor(state->x);
box.y = floor(state->y);
box.width = state->width;
2018-07-07 19:30:52 +10:00
box.height = state->border_thickness;
// adjust sizing for rounded border corners
if (corner_radius) {
box.x += corner_radius + state->border_thickness;
box.width -= 2 * (corner_radius + state->border_thickness);
}
adjust_box_to_workspace_offset(&box, &border_deco_data, output);
2018-07-07 19:30:52 +10:00
scale_box(&box, output_scale);
render_rect(output, &output_damage, &box, color);
// render rounded top corner borders if corner_radius is set > 0
if (corner_radius) {
int size = 2 * (corner_radius + state->border_thickness);
int scaled_thickness = state->border_thickness * output_scale;
int scaled_corner_radius = corner_radius * output_scale;
// top left
if (state->border_left) {
box.width = size;
box.height = size;
box.x = floor(state->x);
box.y = floor(state->y);
adjust_box_to_workspace_offset(&box, &border_deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
scaled_corner_radius, scaled_thickness, TOP_LEFT);
}
// top right
if (state->border_right) {
box.width = size;
box.height = size;
box.x = floor(state->x + state->width - size);
box.y = floor(state->y);
adjust_box_to_workspace_offset(&box, &border_deco_data, output);
scale_box(&box, output_scale);
render_border_corner(output, &output_damage, &box, color,
scaled_corner_radius, scaled_thickness, TOP_RIGHT);
}
}
pixman_region32_fini(&output_damage);
2018-07-07 19:30:52 +10:00
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct parent_data {
enum sway_container_layout layout;
struct wlr_box box;
list_t *children;
bool focused;
struct sway_container *active_child;
bool on_focused_workspace;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
};
2018-07-07 19:30:52 +10:00
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, bool parent_focused,
bool is_current_ws);
2018-07-07 19:30:52 +10:00
/**
* Render a container's children using a L_HORIZ or L_VERT layout.
*
* Wrap child views in borders and leave child containers borderless because
* they'll apply their own borders to their children.
*/
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
static void render_containers_linear(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i];
if (container_is_scratchpad_hidden(child)) {
continue;
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (child->view) {
struct sway_view *view = child->view;
2018-07-07 19:30:52 +10:00
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
struct sway_container_state *state = &child->current;
if (view_is_urgent(view)) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
marks_texture = child->marks_urgent;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
} else if (state->focused || parent->focused) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = child->marks_focused;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
} else if (child == parent->active_child) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = child->marks_focused_inactive;
2018-07-07 19:30:52 +10:00
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = child->marks_unfocused;
2018-07-07 19:30:52 +10:00
}
bool has_titlebar = state->border == B_NORMAL;
struct decoration_data deco_data = {
.alpha = child->alpha,
2022-12-07 16:10:11 +11:00
.dim_color = view_is_urgent(view)
2023-04-16 03:44:56 +10:00
? config->dim_inactive_colors.urgent
: config->dim_inactive_colors.unfocused,
.dim = child->current.focused || parent->focused ? 0.0f : child->dim,
// no corner radius if no gaps (allows smart_gaps to work as expected)
.corner_radius = config->smart_corner_radius &&
output->current.active_workspace->current_gaps.top == 0
? 0 : child->corner_radius,
.saturation = child->saturation,
.has_titlebar = has_titlebar,
.blur = child->blur_enabled,
.discard_transparent = false,
.shadow = child->shadow_enabled,
.on_focused_workspace = parent->on_focused_workspace,
};
render_view(output, damage, child, colors, deco_data);
if (has_titlebar) {
render_titlebar(output, damage, child, floor(state->x), floor(state->y),
state->width, colors, deco_data, ALL, title_texture, marks_texture);
} else if (state->border == B_PIXEL) {
render_top_border(output, damage, state, colors, deco_data);
2018-07-07 19:30:52 +10:00
}
} else {
render_container(output, damage, child,
parent->focused || child->current.focused,
parent->on_focused_workspace);
2018-07-07 19:30:52 +10:00
}
}
}
2021-12-11 02:09:29 +11:00
static bool container_is_focused(struct sway_container *con, void *data) {
return con->current.focused;
}
static bool container_has_focused_child(struct sway_container *con) {
return container_find_child(con, container_is_focused, NULL);
}
2018-07-07 19:30:52 +10:00
/**
* Render a container's children using the L_TABBED layout.
*/
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
static void render_containers_tabbed(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) {
2018-07-07 19:30:52 +10:00
return;
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct sway_container *current = parent->active_child;
struct border_colors *current_colors = &config->border_colors.unfocused;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
int tab_width = parent->box.width / parent->children->length;
struct decoration_data deco_data = {
.alpha = current->alpha,
.dim_color = current->view && view_is_urgent(current->view)
? config->dim_inactive_colors.urgent
: config->dim_inactive_colors.unfocused,
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
// no corner radius if no gaps (allows smart_gaps to work as expected)
.corner_radius = config->smart_corner_radius &&
output->current.active_workspace->current_gaps.top == 0
? 0 : current->corner_radius,
.saturation = current->saturation,
.has_titlebar = true,
.blur = current->blur_enabled,
.discard_transparent = false,
.shadow = current->shadow_enabled,
.on_focused_workspace = parent->on_focused_workspace,
};
2018-07-07 19:30:52 +10:00
// Render tabs
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i];
struct sway_view *view = child->view;
2018-07-07 19:30:52 +10:00
struct sway_container_state *cstate = &child->current;
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
bool urgent = view ?
view_is_urgent(view) : container_has_urgent_child(child);
2018-07-07 19:30:52 +10:00
if (urgent) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
marks_texture = child->marks_urgent;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
} else if (cstate->focused || parent->focused) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = child->marks_focused;
2021-12-11 02:09:29 +11:00
} else if (config->has_focused_tab_title && container_has_focused_child(child)) {
colors = &config->border_colors.focused_tab_title;
title_texture = child->title_focused_tab_title;
marks_texture = child->marks_focused_tab_title;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
} else if (child == parent->active_child) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = child->marks_focused_inactive;
2018-07-07 19:30:52 +10:00
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = child->marks_unfocused;
2018-07-07 19:30:52 +10:00
}
int x = floor(cstate->x + tab_width * i);
2018-07-07 19:30:52 +10:00
// Make last tab use the remaining width of the parent
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (i == parent->children->length - 1) {
tab_width = parent->box.width - tab_width * i;
2018-07-07 19:30:52 +10:00
}
// only round outer corners
enum corner_location corner_location = NONE;
if (i == 0) {
if (i == parent->children->length - 1) {
corner_location = ALL;
} else {
corner_location = TOP_LEFT;
}
} else if (i == parent->children->length - 1) {
corner_location = TOP_RIGHT;
}
render_titlebar(output, damage, child, x, parent->box.y, tab_width, colors,
deco_data, corner_location, title_texture, marks_texture);
2018-07-07 19:30:52 +10:00
if (child == current) {
current_colors = colors;
}
}
// Render surface and left/right/bottom borders
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (current->view) {
render_view(output, damage, current, current_colors, deco_data);
} else {
render_container(output, damage, current,
parent->focused || current->current.focused,
parent->on_focused_workspace);
2018-07-07 19:30:52 +10:00
}
}
/**
* Render a container's children using the L_STACKED layout.
*/
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
static void render_containers_stacked(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) {
2018-07-07 19:30:52 +10:00
return;
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct sway_container *current = parent->active_child;
struct border_colors *current_colors = &config->border_colors.unfocused;
size_t titlebar_height = container_titlebar_height();
struct decoration_data deco_data = {
.alpha = current->alpha,
.dim_color = current->view && view_is_urgent(current->view)
? config->dim_inactive_colors.urgent
: config->dim_inactive_colors.unfocused,
.dim = current->current.focused || parent->focused ? 0.0f : current->dim,
.saturation = current->saturation,
.corner_radius = config->smart_corner_radius &&
output->current.active_workspace->current_gaps.top == 0
? 0 : current->corner_radius,
.has_titlebar = true,
.blur = current->blur_enabled,
.discard_transparent = false,
.shadow = current->shadow_enabled,
.on_focused_workspace = parent->on_focused_workspace,
};
2018-07-07 19:30:52 +10:00
// Render titles
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i];
struct sway_view *view = child->view;
2018-07-07 19:30:52 +10:00
struct sway_container_state *cstate = &child->current;
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
bool urgent = view ?
view_is_urgent(view) : container_has_urgent_child(child);
2018-07-07 19:30:52 +10:00
if (urgent) {
colors = &config->border_colors.urgent;
title_texture = child->title_urgent;
marks_texture = child->marks_urgent;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
} else if (cstate->focused || parent->focused) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = child->marks_focused;
2021-12-11 02:09:29 +11:00
} else if (config->has_focused_tab_title && container_has_focused_child(child)) {
colors = &config->border_colors.focused_tab_title;
title_texture = child->title_focused_tab_title;
marks_texture = child->marks_focused_tab_title;
} else if (child == parent->active_child) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = child->marks_focused_inactive;
2018-07-07 19:30:52 +10:00
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = child->marks_unfocused;
2018-07-07 19:30:52 +10:00
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
int y = parent->box.y + titlebar_height * i;
struct decoration_data titlebar_deco_data = deco_data;
titlebar_deco_data.corner_radius = i != 0 ? 0 : deco_data.corner_radius;
render_titlebar(output, damage, child, parent->box.x, y, parent->box.width,
colors, titlebar_deco_data, ALL, title_texture, marks_texture);
2018-07-07 19:30:52 +10:00
if (child == current) {
current_colors = colors;
}
}
// Render surface and left/right/bottom borders
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (current->view) {
render_view(output, damage, current, current_colors, deco_data);
} else {
render_container(output, damage, current,
parent->focused || current->current.focused,
parent->on_focused_workspace);
2018-07-07 19:30:52 +10:00
}
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
static void render_containers(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
if (config->hide_lone_tab && parent->children->length == 1) {
struct sway_container *child = parent->children->items[0];
if (child->view) {
render_containers_linear(output,damage, parent);
return;
}
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
switch (parent->layout) {
2018-07-07 19:30:52 +10:00
case L_NONE:
case L_HORIZ:
case L_VERT:
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
render_containers_linear(output, damage, parent);
2018-07-07 19:30:52 +10:00
break;
case L_STACKED:
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
render_containers_stacked(output, damage, parent);
2018-07-07 19:30:52 +10:00
break;
case L_TABBED:
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
render_containers_tabbed(output, damage, parent);
2018-07-07 19:30:52 +10:00
break;
}
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, bool focused,
bool is_focused_ws) {
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct parent_data data = {
.layout = con->current.layout,
.box = {
.x = floor(con->current.x),
.y = floor(con->current.y),
.width = con->current.width,
.height = con->current.height,
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
},
.children = con->current.children,
.focused = focused,
.active_child = con->current.focused_inactive_child,
.on_focused_workspace = is_focused_ws,
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
};
render_containers(output, damage, &data);
}
static void render_workspace(struct sway_output *output,
2024-01-22 23:43:54 +11:00
pixman_region32_t *damage, struct sway_workspace *ws, bool focused,
struct sway_workspace *other_ws) {
struct sway_workspace *workspaces[2] = { other_ws, ws };
for (int i = 0; i < 2; i++) {
struct sway_workspace *workspace = workspaces[i];
if (!workspace || !workspace->current.tiling) {
continue;
}
struct parent_data data = {
.layout = workspace->current.layout,
.box = {
.x = floor(workspace->current.x),
.y = floor(workspace->current.y),
.width = workspace->current.width,
.height = workspace->current.height,
},
.children = workspace->current.tiling,
.focused = ws == workspace ? focused : false,
.active_child = workspace->current.focused_inactive_child,
.on_focused_workspace = ws == workspace,
};
render_containers(output, damage, &data);
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
}
2018-07-07 19:30:52 +10:00
static void render_floating_container(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_container *con,
bool is_focused_ws) {
struct sway_container_state *state = &con->current;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
if (con->view) {
struct sway_view *view = con->view;
2018-07-07 19:30:52 +10:00
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
if (view_is_urgent(view)) {
colors = &config->border_colors.urgent;
title_texture = con->title_urgent;
marks_texture = con->marks_urgent;
} else if (state->focused) {
2018-07-07 19:30:52 +10:00
colors = &config->border_colors.focused;
title_texture = con->title_focused;
marks_texture = con->marks_focused;
2018-07-07 19:30:52 +10:00
} else {
colors = &config->border_colors.unfocused;
title_texture = con->title_unfocused;
marks_texture = con->marks_unfocused;
2018-07-07 19:30:52 +10:00
}
bool has_titlebar = state->border == B_NORMAL;
struct decoration_data deco_data = {
.alpha = con->alpha,
2022-12-07 16:10:11 +11:00
.dim_color = view_is_urgent(view)
2023-04-16 03:44:56 +10:00
? config->dim_inactive_colors.urgent
: config->dim_inactive_colors.unfocused,
.dim = con->current.focused ? 0.0f : con->dim,
.saturation = con->saturation,
.corner_radius = con->corner_radius,
.has_titlebar = has_titlebar,
.blur = con->blur_enabled,
.discard_transparent = false,
.shadow = con->shadow_enabled,
.on_focused_workspace = is_focused_ws,
};
render_view(soutput, damage, con, colors, deco_data);
if (has_titlebar) {
render_titlebar(soutput, damage, con, floor(state->x), floor(state->y),
state->width, colors, deco_data, ALL, title_texture, marks_texture);
} else if (state->border == B_PIXEL) {
render_top_border(soutput, damage, state, colors, deco_data);
2018-07-07 19:30:52 +10:00
}
} else {
render_container(soutput, damage, con, state->focused, is_focused_ws);
2018-07-07 19:30:52 +10:00
}
}
static void render_floating(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_workspace *other_ws,
bool has_fullscreen) {
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
for (int i = 0; i < root->outputs->length; ++i) {
struct sway_output *output = root->outputs->items[i];
// Don't render floating windows across outputs when switching workspaces
2024-01-23 02:39:44 +11:00
if (output->workspace_scroll.percent != 0 && output != soutput) {
continue;
}
struct sway_workspace *visible_ws = output->current.active_workspace;
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
for (int j = 0; j < output->current.workspaces->length; ++j) {
struct sway_workspace *ws = output->current.workspaces->items[j];
2024-01-23 02:39:44 +11:00
float scroll_percent = soutput->workspace_scroll.percent;
// Only render visible workspace when not scrolling
bool ws_is_visible = workspace_is_visible(ws);
if (!ws_is_visible && scroll_percent == 0) {
continue;
}
// Only render affected workspaces
if ((ws != other_ws && ws != visible_ws) ||
(ws_is_visible && has_fullscreen)) {
2018-07-07 19:30:52 +10:00
continue;
}
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
for (int k = 0; k < ws->current.floating->length; ++k) {
struct sway_container *floater = ws->current.floating->items[k];
if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
continue;
}
render_floating_container(soutput, damage, floater, ws == visible_ws);
2018-07-07 19:30:52 +10:00
}
}
}
}
static void render_seatops(struct sway_output *output,
pixman_region32_t *damage) {
struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) {
seatop_render(seat, output, damage);
}
}
static void render_fullscreen_con(pixman_region32_t *damage,
struct sway_output *output, struct sway_container *fullscreen_con,
2024-01-22 23:43:12 +11:00
struct sway_workspace *workspace, bool clear_whole_screen) {
struct wlr_output *wlr_output = output->wlr_output;
2024-01-22 23:43:12 +11:00
struct decoration_data deco_data = get_undecorated_decoration_data();
deco_data.saturation = fullscreen_con->saturation;
deco_data.on_focused_workspace = workspace == output->current.active_workspace;
// Only clear the transformed fullscreen bounds
pixman_region32_t dmg;
2024-01-23 05:17:31 +11:00
pixman_region32_init(&dmg);
2024-01-22 23:43:12 +11:00
if (!clear_whole_screen) {
pixman_region32_copy(&dmg, damage);
adjust_damage_to_workspace_bounds(&dmg, &deco_data, output);
2024-01-22 23:43:12 +11:00
damage = &dmg;
}
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
fx_renderer_clear(clear_color);
}
if (fullscreen_con->view) {
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
render_saved_view(fullscreen_con->view, output, damage, deco_data);
} else if (fullscreen_con->view->surface) {
render_view_toplevels(fullscreen_con->view, output, damage, deco_data);
}
} else {
render_container(output, damage, fullscreen_con, fullscreen_con->current.focused,
2024-01-22 23:43:12 +11:00
deco_data.on_focused_workspace);
}
for (int i = 0; i < workspace->current.floating->length; ++i) {
struct sway_container *floater =
workspace->current.floating->items[i];
if (container_is_transient_for(floater, fullscreen_con)) {
2024-01-22 23:43:12 +11:00
render_floating_container(output, damage, floater, deco_data.on_focused_workspace);
}
}
#if HAVE_XWAYLAND
render_unmanaged(output, damage, &root->xwayland_unmanaged);
#endif
2024-01-22 23:43:12 +11:00
pixman_region32_fini(&dmg);
}
2018-07-07 19:30:52 +10:00
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage) {
struct wlr_output *wlr_output = output->wlr_output;
struct fx_renderer *renderer = output->renderer;
2018-09-19 19:03:25 +10:00
struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) {
return;
}
// Get the sibling workspaces
struct sway_workspace *other_ws = NULL;
2024-01-23 02:39:44 +11:00
if (output->workspace_scroll.percent < 0) {
other_ws = workspace_output_prev_wrap(workspace,
config->workspace_gesture_wrap_around);
} else if (output->workspace_scroll.percent > 0) {
other_ws = workspace_output_next_wrap(workspace,
config->workspace_gesture_wrap_around);
}
struct sway_container *fullscreen_con = root->fullscreen_global;
if (!fullscreen_con) {
fullscreen_con = workspace->current.fullscreen;
}
// Also check if the sibling workspace has a fullscreen container
bool has_fullscreen = fullscreen_con != NULL;
bool other_ws_has_fullscreen = false;
if (other_ws) {
other_ws_has_fullscreen = other_ws->current.fullscreen;
if (!has_fullscreen) {
has_fullscreen = other_ws_has_fullscreen;
}
}
// TODO: generate the monitor box in fx_renderer (since it already has a wlr_output)
2023-04-28 08:50:36 +10:00
struct wlr_box monitor_box = get_monitor_box(wlr_output);
wlr_box_transform(&monitor_box, &monitor_box,
wlr_output_transform_invert(wlr_output->transform),
monitor_box.width, monitor_box.height);
fx_renderer_begin(renderer, monitor_box.width, monitor_box.height);
int output_width, output_height;
wlr_output_transformed_resolution(wlr_output, &output_width, &output_height);
2024-01-23 02:39:44 +11:00
if (debug.damage == DAMAGE_RERENDER || output->workspace_scroll.percent != 0) {
pixman_region32_union_rect(damage, damage, 0, 0, output_width, output_height);
2021-09-07 22:47:27 +10:00
}
if (!pixman_region32_not_empty(damage)) {
// Output isn't damaged but needs buffer swap
goto renderer_end;
2018-07-07 19:30:52 +10:00
}
if (debug.damage == DAMAGE_HIGHLIGHT) {
2022-08-13 16:14:23 +10:00
fx_renderer_clear((float[]){1, 1, 0, 1});
}
rebase: Sway 1.8 (#78) * build: bump wlroots dependency to 0.16.0 * swaymsg: replace if with switch in pretty_print * swaymsg: add GET_TREE pretty-printing * swaybar: fix errno handling in status_handle_readable If getline fails once, it was not reset before the next getline call. errno is only overwritten by getline on error. * Add cairo_image_surface_create error handling cairo_image_surface_create can fail, e.g. when running out of memory or when the size is too big. Avoid crashing in this case. Closes: https://github.com/swaywm/sway/issues/6531 * build: bump version to 1.8-dev Historically we've been sticking with the last release number in the master branch. However that's a bit confusing, people can't easily figure out whether they're using a release or a work-in-progress snapshot. Only the commit hash appended to the version number may help, but that's not very explicit and disappears when using a tarball. We could bump the version in master to the next release number. However during the RC cycle there would be a downgrade from 1.8 to 1.8-rc1. Also it would be hard to tell the difference between a stable release and an old snapshot. This patch introduces a new pre-release identifier, "dev". It's alphabetically before "rc" so it should be correctly sorted by semver comparisons. "dev" is upgraded to "rc" (and then to stable) when doing a release. The master branch always uses a "dev" version, only release branches use "rc" or stable versions. * [IPC] Add repeat delay/rate info to keyboard Closes #6735 wlroots already has the info in the struct so let's access it and print it out. * input/seat: unset has_focus when focus_stack becomes empty We currently track the focus of a seat in two ways: we use a list called focus_stack to track the order in which nodes have been focused, with the first node representing what's currently focused, and we use a variable called has_focus to indicate whether anything has focus--i.e. whether we should actually treat that first node as focused at any given time. In a number of places, we treat has_focus as implying that a focused node exists. If it's true, we attempt to dereference the return value of seat_get_focus(), our helper function for getting the first node in focus_list, with no further checks. But this isn't quite correct with the current implementation of seat_get_focus(): not only does it return NULL when has_focus is false, it also returns NULL when focus_stack contains no items. In most cases, focus_stack never becomes empty and so this doesn't matter at all. Since focus_stack stores a history of focused nodes, we rarely remove nodes from it. The exception to this is when a node itself goes away. In that case, we call seat_node_destroy() to remove it from focus_stack and free it. But we don't unset has_focus if we've removed the final node! This lets us get into a state where has_focus is true but seat_get_focus() returns NULL, leading to a segfault when we try to dereference it. Fix the issue both by updating has_focus in seat_node_destroy() and by adding an assertion in seat_get_focus() that ensures focus_stack and has_focus are in sync, which will make it easier to track down similar issues in the future. Fixes #6395. [1] There's some discussion in #1585 from when this was implemented about whether has_focus is actually necessary; it's possible we could remove it entirely, but for the moment this is the architecture we have. * swaybar: fix tray_padding vs min-height re: scale Co-authored-by: xdavidwu <xdavidwuph@gmail.com> * swaybar: fix tray item icon scaling, positioning * container: Fix crash when view unmaps + maps quickly Followup on 4e4898e90f. If a view quickly maps and unmaps repeatedly, there will be multiple destroyed containers with same view in a single transaction. Each of these containers will then try to destroy this view, resulting in use after free. The container should only destroy the view if the view still belongs to the container. Simple reproducer: couple XMapWindow + XUnmapWindow in a loop followed by XDestroyWindow. See #6605 * commands/move: Fix crash when pos_y is omitted Fixes #6737 * Destroy sub-surfaces with parent layer-shell surface Closes: https://github.com/swaywm/sway/issues/6337 * Add safety assert in parse_movement_unit Let's add this just in case a caller passes argc == 0. References: https://github.com/swaywm/sway/issues/6737#issuecomment-1008082540 * meson: check: false on run_command Future meson releases will change the default and warns when the implicit default is used, breaking builds. Explicitly set check: false to maintain behavior and silence warnings. * Print deprecation notice when running SUID SUID privilege drop is needed for the "builtin"-backend of libseat, which copied our old "direct" backend behavior for the sake of compatibility and ease of transition. libseat now has a better alternative in the form of seatd-launch. It uses the normal seatd daemon and libseat backend and takes care of SUID for us. Add a soft deprecation warning to highlight our future intent of removing this code. The deprecation cycle is needed to avoid surprises when sway no longer drops privileges. * xdg-shell: use toplevel geometry to adjust the popup box `popup_unconstrain` uses view coordinates to init the output box for popups. However wlroots expects the box to be set in a toplevel surface coordinate system, which is not always equal to view. The difference between those is a window geometry set via xdg-shell. GTK4 reserves some space for client-side decoration and thus has a window with top left corner not matching to (0, 0) of a surface. The box calculated without taking that into account was slightly shifted compared to the actual output and allowed to position part of the popup off screen. * build: fix building with basu 02b412a introduced the use of list for sdbus deps, however it was assuming that all packages which were in a list has a version higher than 239. That is true for libsystemd and libelogind, since they use the same versions, however basu is using version numbers which are way lower than what libsystemd/libelogind are using, so basu only build is failing. * Upgrade for wlroots surface refactoring See [1] for details. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3412 * commands/focus: drop trailing whitespace * input/cursor: count pointer gestures as idle activity Fixes https://github.com/swaywm/sway/issues/6765. * input/cursor: treat swipe begin as idle activity too Accidentally overlooked in fd53f80. * treat fullscreen windows as 'tiled' for commands/focus * transaction: destroying nodes aren't hidden Commit 37d7bc69986f ("transaction: Only wait for ack from visible views") introduced a check which uses view_is_visible() to check if a view is still visible on the screen. However view_is_visible() will early return in case the node is in the destroying state. This is incorrect for transactions, since a destroying view which is visible will trigger configure events for other clients. This bug was visible when repeatedly opening and closing two views side by side, since we ignore the destroying node we get a frame where the still open view is shown with the old configure values and the rest is the desktop background. The next frame is than correct again. Fix this by considering destroying views as visible, we correctly wait for them and send the configure events to other views in time, fixing the background flicker. Fixes #6473 * build: execute wlroots subproject before finding deps wlroots often requires dependencies more recent than Sway's. Executing the wlroots subproject first will give Meson a chance to find these newer dependencies, possibly via subprojects. The subproject will override the "wlroots" dependency when executed, so we don't need to use get_variable anymore. References: https://github.com/swaywm/sway/pull/6498#issuecomment-1001746017 * tray: do not render passive items https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/#org.freedesktop.statusnotifieritem.status * cmd/swap: error on swapping a container with itself * input/cursor: pass through pointer hold gestures This just follows swaywm/wlroots#3047, so `wl_pointer_gestures_v1` clients can be notified of these events. * swaynag: remove buffer destruction condition An address of a variable can never be NULL, so checking it doesn't make sense; and `destroy_buffer()` can operate on already destroyed buffers anyway. Fixes #6780 * Use bools for CLI flags * xwayland: listen to `request_activate` event When REAPER submenu is closed `XCB_CLIENT_MESSAGE` with type `NET_ACTIVE_WINDOW` is sent to set focus to parent menu. Closes: https://github.com/swaywm/sway/issues/6324 * chore: chase wlr_output_layout_get_box() update https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3439 * Chase wlroots xdg-shell refactor * Minor update to focus_on_window_activation Removed xwayland limitation since wayland clients are supported via xdg-activation. * Translated README into Italian * readme: add link to Italian translation * readme: sort language list alphabetically * readme: use relative links for translations * xdg-shell: use wlr_xdg_toplevel in sway_view Improved type safety. Closes: https://github.com/swaywm/sway/issues/6813 * xdg-shell: use wlr_xdg_popup in sway_xdg_popup Improved type safety. * Fix snprintf compiler warning * Remove all sprintf calls Replace them with snprintf, which ensures buffer overflows won't happen. * sway/commands: add missing wlr_keyboard interface include in xkb_switch_layout * sway/input: use wlr_input_device from input device base * Remove some erroneous apostrophes in comments * Don't enter seatop_move_floating when fullscreen Currently, a floating window that's been fullscreened can send us xdg_toplevel::move, and we'll enter seatop_move_floating, which lets us drag the surface around while it's fullscreen. We don't want this--fullscreen surfaces should always be aligned to the screen--so add the same check that seatop_default already does when entering this mode. Tested with Weston's weston-fullscreen demo, which sends a move request if you click anywhere on its surface. * swaynag: die on all allocation failures * sway/input: don't pass possibly invalid modifiers pointer active_keyboard may be NULL, in which case an invalid pointer could be passed to wlr_input_method_keyboard_grab_v2_send_modifiers. This procedure call is unnecessary since wlroots commit 372a52ec "input method: send modifiers in set_keyboard", so the call can simply be removed. Fixes #6836. * sway/input: destroy sway_switch properly Fix: #6861 Added seat_device_destroy function to seat_device_destroy function. * commands/focus: fix segfault when no container is already focused. Fixes #6690. * Remove WLR_SWITCH_STATE_TOGGLE usage Ref [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/4792446ee8f50104bd207d9ccd8558a7e4eb4514 * Replace pcre with pcre2 Closes: https://github.com/swaywm/sway/issues/6838 * swaybar: remove swaybar_output.input_region No need to keep the region around, we can immediately destroy it after the wl_surface.set_input_region request. * swaybar: set opaque region When the background color is fully opaque, set the surface's opaque region to the whole surface. * Updating criteria checking with PCRE2 * swaynag: allocate button_details with details They are used together, so it doesn't make sense to allocate them separately. * swaynag: statically allocate button_close, and move declaration Every swaynag has a close button, so it doesn't make sense to allocate it dynamically. The declaration is moved later to when it is actually needed. * swaynag: remove unnecessary zero of swaynag struct Global variables are initialized to 0. * swaynag: remove redundant status variables in main Instead, we just use `status` for all failures. * remove unnecessary strlen call * sway/input/cursor: take device mm size from wlr_tablet * sway/input/seat: take output name from specialized input device * sway/input: follow up wlroots input device events renaming * sway/input: fix bad position of wlr_drag * sway/input: wlr_seat_keyboard() now takes wlr_keyboard * bash-completion: localize variables * sway/main: move constants off the stack This makes stack traces from gdb slightly easier to read. * Fix farsi label * Avoid format-truncation warning The existing code gives this error when compiled with GCC 12: ../sway/server.c: In function ‘server_init’: ../sway/server.c:217:75: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 8 [-Werror=format-truncation=] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~ ../sway/server.c:217:66: note: directive argument in the range [-2147483647, 32] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~ ../sway/server.c:217:17: note: ‘snprintf’ output between 10 and 20 bytes into a destination of size 16 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because i is never negative, this is a false positive, but it is easy to change i to unsigned to silence the error. * Shuffle variables to satisfy -Werror=restrict This also fixes an invalid strlen invocation on uninitialized memory. * layer_shell: keep output non-NULL wherever possible Our layer shell implementation assigns every layer surface to an output on creation. It tracks this output using the output field on the underlying wlr_layer_surface_v1 structure. As such, much of the existing code assumes that output is always non-NULL and omits NULL checks accordingly. However, there are currently two cases where we destroy a sway_layer_surface and output is NULL. The first is when we can't find an output to assign the surface to and destroy it immediately after creation. The second is when we destroy a surface in response to its output getting destroyed, as we set output to NULL in handle_output_destroy() before we call wlr_layer_surface_v1_destroy(), which is what calls the appropriate unmap and destroy callbacks. The former case doesn't cause any problems, since we haven't even allocated a sway_layer_surface at that point or registered any callbacks. The latter case, however, currently triggers a crash (#6120) if a popup is visible, since our popup_handle_unmap() implementation can't handle a NULL output. To fix this issue, keep output set until right before we free the sway_layer_surface. All we need to do is remove some of the cleanup logic from handle_output_destroy(), since as of commit c9060bcc12d0 ("layer-shell: replace close() with destroy()") that same logic is guaranteed to be happen later when wlroots calls handle_destroy() as part of wlr_layer_surface_v1_destroy(). This lets us remove some NULL checks from other unmap/destroy callbacks, which is nice. We also don't need to check that the wlr_output points to a valid sway_output anymore, since we unset that pointer after disabling the output as of commit a0bbe67076b8 ("Address emersions comments on output re-enabling") Just to be safe, I've added assertions that the wlr_output is non-NULL wherever we use it. Fixes #6120. * Chase wlroots X11 hints update * Add Swedish README * Support cursor capture in grimshot Refactor argument parser Bring back `sh` compatibility Default to NOTIFY=no * Update grimshot.1.scd Fixed typo. The object is **files**, which is plural. **image** modifies files; it's not countable. * xkb_switch_layout: fix relative layout switches Fixes #6011 * Implement ext-session-lock-v1 * Avoid inspecting a NULL view in seat_set_focus Fixes #6968 * swaynag: do error checking and rename read_from_stdin read_from_stdin not only read from stdin, but trimming trailing newlines, so rename it to reflect this. * swaynag: improve robustness when loading config * swaynag: combine consecutive declaration/assignments * config: Remove unused mouse binding structure Mouse bindings are handled alongside normal bindings. Remove the unused separate data structure definition to avoid confusion. Signed-off-by: Michael Weiser <michael.weiser@gmx.de> * Replace strncpy with memcpy strncpy is useless here, is dangerous because it doesn't guarantee that the string is NUL-terminated and causes the following warning: ../sway/criteria.c: In function ‘criteria_parse’: ../sway/criteria.c:712:25: error: ‘strncpy’ destination unchanged after copying no bytes [-Werror=stringop-truncation] 712 | strncpy(value, valuestart, head - valuestart); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Add descriptions for `stacking` and `tabbed` layouts Resolves #5918 * man: Fix trailing spaces * server: request xdg-shell v2 Wlroots does not yet support the newer xdg-shell versions and now requires the compositor to set the supported xdg-shell version during creation. Set this to v2 for sway as well. Fixes https://github.com/swaywm/sway/issues/7001 * realtime: request SCHED_RR using CAP_SYS_NICE Try to gain SCHED_RR (round-robin) realtime scheduling privileges before starting the server. This requires CAP_SYS_NICE on Linux systems. We additionally register a pthread_atfork callback which resets the scheduling class back to SCHED_OTHER (the Linux system default). Due to CAP_SYS_NICE, setting RLIMIT_RTPRIO has no effect on the process as documented within man 7 sched (from Linux): Privileged (CAP_SYS_NICE) threads ignore the RLIMIT_RTPRIO limit; as with older kernels, they can make arbitrary changes to scheduling policy and priority. See getrlimit(2) for further information on RLIMIT_RTPRIO Note that this requires the sway distribution packagers to set the CAP_SYS_NICE capability on the sway binary. Supersedes #6992 * ext-session-lock: disable direct scan-out when locked * Polish the language in README.zh-CN.md & sync with English one Co-Authored-By: Urey. Xue <urey.s.knowledge@gmail.com> * De-duplicate IPC output descriptions * Handle NULL output make/model/serial * chore: chase wlroots xdg-shell update * xdg-shell: schedule a configure on maximize request This commit reverts 03879290dbee26127f6867ef60bc2a7f9a6c8c5f and fc84bcb7fb0ffa29b1f9bed287762241a3473803. * Add a Hindi (हिन्दी) translation to the README Hindi is one of the most prominent languages of the Indian Subcontinent. This commit adds the translation of the README into the Hindi language. Some of the words are still written in English because there wasn't an appropriate technical term of the word in the language. Co-authored-by: Surendrajat <surendrajat@protonmail.com> * sway: add bindgesture command Co-authored-by: Michael Weiser <michael.weiser@gmx.de> * build: link with -pthread Fixes the following FreeBSD error: ld: error: undefined symbol: pthread_getschedparam >>> referenced by realtime.c:25 (../sway/realtime.c:25) >>> sway/sway.p/realtime.c.o:(set_rr_scheduling) Fixes: a3a82efbf6b5 ("realtime: request SCHED_RR using CAP_SYS_NICE") * ipc: remove chatty debug log messages These aren't particularly useful, and clobber the debug logs. * Refuse to start when SUID is detected This ensures that those surprised by the deprecation of SUID operation receive an error rather than accidentally having sway run as root. This detection will be removed in a future release. * swaynag: move close_button up to fix SIGSEGV When swaynag_parse_options encounters '--dismiss-button' (or its shorthand '-s'), it sets the text of the first button in the swaynag.buttons list, which is expected to exist and to be the dismiss button, to the one passed by the user. Commit 4780afb68b4ee2cdf0e4925f40cf885819f8a74a ("swaynag: statically allocate button_close, and move declaration") moved the list initialization to after swaynag_parse_options is called which made that code fail. For example, the command 'swaynag --dismiss-button Dismiss' crashes and 'swaynag --message Message --button Yes "" --dismiss-button Dismiss' shows the wrong buttons. Move it back to before swaynag_parse_options is called. * config/output: use wlr_output_commit_state This makes the code more robust because we don't potentially leave bad state in wlr_output.pending behind anymore. This also fixes a bug. Closes: https://github.com/swaywm/sway/issues/7043 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3610 * Allocate enough space for `cmd_results->error` * Remove access to wlr_input_device union References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3626 Closes: https://github.com/swaywm/sway/issues/7077 * Rename dpms output command to power The "dpms" command refers to VESA Display Power Management Signaling, a deprecated standard. It's superseded by VESA DPM. Instead of tying out command name to a particular standard, use the neutral term "power". * Strip quotes in bindsym --input-device=... If the input device is quoted, which is common when using variables in the config file, those quotes must be ignored here, or the input device will be ignored. Fixes #7029. * Avoid unecessary string copy * Reject font values that are invalid for pango Use pango to parse font configuration early, and reject the command as invalid if the value is invalid for pango. Since we're already parsing the font into a `PangoFontDescription`, keep that instance around and avoid re-parsing the font each time we render text. Fixes: https://github.com/swaywm/sway/issues/6805 * Reuse parsed PangoFontDescription Avoids parsing the configured font each time text is rendered. * ipc: add "power" to output reply * config.in: switch to `output power` * Remove internal references to DPMS While at it, use an int for the config field, just like we do for all other fields. * fix: remove redundant empty statement in main.c This semi-colon looks like a typo. Luckily, it has no effect on the code as it's treated as an empty statement leading the switch case. Really straightforward nitpick change, was just something I was confused by when reading over the code. * input: chase delta_discrete semantics change * swaymsg: fix floating_nodes being ignored Fix floating_nodes being ignored in pretty_print_tree. * ipc: make get_deco_rect check config->hide_lone_tab Without this, the `IPC_GET_TREE` ipc call would return false information about the container's `deco_rect` and `rect` properties if `hide_edge_borders --i3` was in effect. * grimshot: fix tilde expansion within quotes * Enable single-pixel-buffer-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3428 * sway-output.5: improve display of parameter Since "width" and "height" are separate parameters, show them as such. * man: sway(5) move fixes * ipc: drop WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN case This has been removed from wlroots. * config/output: test adaptive sync Required for [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3637 * Fix crash in xdg_activation_v1.c wlr_xdg_surface_from_wlr_surface() can return a NULL pointer, so check for NULL before dereferencing it. * sway: Add non-desktop-output type Currently, when encountering a non-desktop display, sway offers the output for leasing and returns without storing it in a sway specific output type like `struct sway_output`. Additionally, running `swaymsg -t get_outputs` doesn't show non-desktop outputs. This commit stores the non-desktop outputs into a struct called `sway_output_non_desktop`, and adds them to a list on `sway_root` * sway: add non-desktop outputs to json when running `swaymsg -t get_outputs` * swaymsg: show non-desktop property when pretty printing outputs * man: Add XWayland information * ipc: expose mode picture aspect ratio * swaymsg: show mode picture aspect ratio * build: simplify protocol paths No need for arrays here. * sway/commands/output: Add command for unplugging non-physical outputs * Improve Japanese translation * allow pointer_constraints on layer_shell surfaces * check for NULL * use seat directly * Use keyboard_state.focused_surface directly * input: focus floating container when clicked on border Fixes #7209. * input: focus container when scrolling on titlebar Fixes #6503. * Fix leaks in criteria_destroy() * Avoid double free in criteria_destroy() * Add support for ext-idle-notify-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3753 * input: tweak focus behavior to allow focusing parent containers Sway focuses the inactive child when focusing split containers. However, there is currently no way to focus the parent container itself by mouse. A user must use the keyboard to do so. This commit maintains the current behavior, but makes it such that a second click on the split container titlebar (i.e., after its children are visible) focuses the split container itself. * Fix keymap being NULL and segfaulting on dev add Moved `libinput_config` to the callers of `sway_input_configure_libinput_device` so that we send the event after the added event. * Rework session lock keyboard focus handling When removing outputs, it is possible to end up in a situation where none of the session lock client's surfaces have keyboard focus, resulting in it not receiving keyboard events. Track the focused surface and update it as needed on surface destroy. * Fix focus tracking when session lock is active Remove the incorrect attempt to block focus changes when an input grab is present and replace it with the same logic used for layer_shell-based screen lockers: restore the focus after changing it. This fixes a use-after-free of seat->workspace if outputs are destroyed while a screen lock is enabled. * container_floating_set_default_size: Store workspace size box on the stack * Support libinput's 1.21 new dwtp option Support the new dwtp (disable while trackpointing) option introduced in libinput 1.21, allowing users to control whether the trackpoint (like those in Thinkpads, but not only) should be disabled while using the keyboard/touchpad. See: https://gitlab.freedesktop.org/libinput/libinput/-/issues/731 * tree: support formatting null titles Any windows that have never had a title set visually behave closer to that of an empty title, but are unformattable, as the code bails out early on a NULL title. * criteria: allow matching on empty (NULL) titles * criteria: allow matching for NULL string criteria * ci: install hwdata * Use wl_signal_emit_mutable() This function fixes segfaults when emitting a signal potentially removes arbitrary listeners. * Use wlr_damage_ring wlr_output_damage is to be replaced with wlr_damage_ring, so use that. * lock: fix crash on output destroy Closes: https://github.com/swaywm/sway/issues/7120 * container_get_siblings: handle NULL workspace * ci: checkout wlroots 0.16.0 * workspace_create: Don't allow NULL name (cherry picked from commit 34933bb84350fe805d82276ea02d5732546e9993) * output: set damage ring bounds to pixel values Fixes: https://github.com/swaywm/sway/issues/7254 (cherry picked from commit 85005b52fe5b832e4ea914fa28048b0c5c803769) * Use shm_open instead of mkstemp shm_open is more reliable because it does not require a writeable filesystem folder, unlike mkstemp. (cherry picked from commit e2bc8866f46701e9c825ad7fa5baac02b2e4898f) * build: drop wayland-scanner fallback (cherry picked from commit 366f6ef3d31688631dc453028e108f98a1d7ab57) * build: unify server & client protocol generation No need to make a difference here, let's just generate header files for both. (cherry picked from commit 5be5a038da8a3789a19945719f2a27233291445d) * build: drop "server" from target name for protocol code (cherry picked from commit e5475d9310941ce88ed016ce1515b36e3a440252) * build: drop intermediate libraries for protocols (cherry picked from commit af8a5a8918ef42336194fb1077b008a736de7af9) * root: move the workspace matching code to its own file This removes the pid_workspace bits from tree/root before it gets too interesting. No functional change. (cherry picked from commit eb5021ef990fb29ff86544aea58d687ad62c757a) * node: prettify node type names (cherry picked from commit 1c4b94ae3ca94b972410c80a61404a347af1ee68) * launcher: track workspaces by node This removes the need to rename the pid_workspaces when a workspace is renamed. It also opens the possibility of tracking other node types. Tracking containers would allow application to be placed correctly in the container tree even if the user has moved their focus elsewhere since it was launched. (cherry picked from commit 3b49f2782e8faf68766269b9c7390b16e25ae824) * launcher: use xdga tokens This reuses wlroots token tracking for workspace matching. It doesn't export any xdga tokens for clients yet. (cherry picked from commit bd66f4943da1c96edc3ba49573e27b42b688c543) * launcher: rename pid_workspace to launcher_ctx Soon we will match views with more than just a pid. (cherry picked from commit d75c9f9722389d441fd24bd490c5cf12c4bef39a) * view: associate launch contexts with views Views now maintain a reference to a launch context which, as a last resort, is populated at map time with a context associated with its pid. This opens the possibility of populating it before map via another source, e.g. xdga-tokens or configuration. (cherry picked from commit 864b3a9a18f236f92f1898bb44ab977ceaebfd68) * launcher: initialize launcher_ctxs once on startup (cherry picked from commit 66568508c06267445489d655c91c94a34d6d9ffe) * launcher: fudge the interface a bit We want to create a context before knowing the pid it will match with. (cherry picked from commit bdeb9f95651f6c99cc2f4cfb59020ddee202cf36) * launcher: export xdga tokens and use them for workspace matching (cherry picked from commit 30ad4dc4a5a41ce7c7aa85096a6e18f374172983) * launcher: export X startup ids and use them for workspace matching (cherry picked from commit 28fda4c0d38907fab94dc7d82c9dcf0754748b4e) * swaybar: Prioritize hotspot events to bar bindings This is consistent with i3bar's behaviour, and for example, allows binding a command to button1, while still being able to click on tray icons or other zones on the bar's status line which may have their own bindings. E.g., in Sway, without this commit, this config. makes tray icons unclickable: bar { # ... bindsym button1 exec swaynag -m You_clicked_the_tray._Want_some_help? } But the same configuration in i3 (with i3-nagbar) keeps tray items clickable. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 53f9dbd424dc173a85c9f4cd30802259d38b1ef4) * swaybar: Make hotspots block bar release bindings The previous commit prioritized hotspots before bar bindings for press events, which matches i3's behaviour. However, since hotspots don't need to do any processing on release events, those were not handled, and simply fell through to `bindsym --release` bar bindings (if any). This is counter-intuitive, and doesn't match i3's behaviour. Instead in case a hotspot handles the press event, it should also handle the release event, doing nothing, but blocking the event from triggering a --release bar binding. E.g., in Sway, without this commit, this config. shows a text on tray clicks: bar { # ... bindsym --release button1 exec swaynag -m I_got_the_release_event. } But the same configuration in i3 (with i3-nagbar) doesn't show the text. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 94b69acf0d7b26ee5af2172300cb18473508da76) * build: drop unused wayland-egl dependency (cherry picked from commit 37e4a3d6370dc6ba2b0877d588845c06781e880e) * build: bump version to 1.8-rc1 * Fix build on Debian Stable (cherry picked from commit dca0bb5749bc16f91ab964fc1b06ebb9a453368f) * build: fix have_xwayland when xcb-icccm is not found xcb-icccm is required to build Xwayland support. Backported from commit d41f11e6bd8cef80f02dda4c66d4a31611aed753. * build: bump version to 1.8-rc2 * seat: Avoid sending redundant keymaps on reload When we reload the config, we reset every input device and re-apply configuration from the config file. This means that the keyboard keymap is updated at least once during config reload, more if the config file contains keyboard configuration. When they keyboard keymap changes and is updated through wlr_seat, the keymap ends up sent to every keyboard bound in every client, seemingly multiple times. On an x230 of mine with a keyboard layout set in the config file, I see 42 keymap events sent to foot on config reload. Reduce events from keyboard configurations by skipping all but the currently active keyboard for the seat, and by clearing the active keyboard during input manager device reset. After this change, I only see a single just-in-time keymap event. Fixes: https://github.com/swaywm/sway/issues/6654 * criteria: be lenient on window_role and instance too * build: bump version to 1.8-rc3 * commands/move: Warp cursor after moving workspace to another output This makes sway's behavior consistent with i3 when `mouse_warping` is set to any value besides `none`. Fixes #7027. (cherry picked from commit e3c63bf58d0744dfb436f0f38442ce3735e40f47) * seat: Set keyboard if seat keyboard is NULL sway sends wl_keyboard.enter on seat focus change and when a keyboard active on a seat is configured. If all keyboards are removed and a keyboard is added back without changing the focused client, no new notify event would be sent despite having keyboard focus. This could lead to key events without notify, which is a protocol violation. As a quick fix, when configuring a keyboard on a seat where no keyboard is currently active, activate the keyboard so that a focused surface will receive a notify event. Regressed by: e1b268af98edeb09e570e8855ef64f0719cbafe2 Closes: https://github.com/swaywm/sway/issues/7330 (cherry picked from commit 1ade0ce753dc5f588584f444ce80d27c3b1e4300) * build: bump version to 1.8-rc4 * swaynag: fix NULL font description The font description was only set if provided on the CLI. It was left NULL for the defaults and when reading from the config file. Closes: https://github.com/swaywm/sway/issues/7186 (cherry picked from commit fd0af78e43f4dd67a404f475c676b25ae38a4b82) * build: bump version to 1.8 * Removed other README languages * Fixed build issues * Removed alpha from render_data struct * Updated PKGBUILDs and COPR spec * Update sway/desktop/render.c Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com> * Fixed deco_data not being initialized properly * Replaced wlr_egl_(make|unset)_current with eglMakeCurrent * Added matrix_projection into fx_renderer Signed-off-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net> Co-authored-by: Simon Ser <contact@emersion.fr> Co-authored-by: Seth Barberee <seth.barberee@gmail.com> Co-authored-by: Thomas Hebb <tommyhebb@gmail.com> Co-authored-by: Nathan Schulte <nmschulte@gmail.com> Co-authored-by: xdavidwu <xdavidwuph@gmail.com> Co-authored-by: David Rosca <nowrep@gmail.com> Co-authored-by: David96 <david@hameipe.de> Co-authored-by: Kenny Levinsen <kl@kl.wtf> Co-authored-by: Aleksei Bavshin <alebastr89@gmail.com> Co-authored-by: Kirill Chibisov <contact@kchibisov.com> Co-authored-by: Tudor Brindus <me@tbrindus.ca> Co-authored-by: Patrick Hilhorst <git@hilhorst.be> Co-authored-by: Rouven Czerwinski <rouven@czerwinskis.de> Co-authored-by: Tobias Bengfort <tobias.bengfort@posteo.de> Co-authored-by: Ronan Pigott <rpigott@berkeley.edu> Co-authored-by: Kirill Primak <vyivel@eclair.cafe> Co-authored-by: Tuomas Yrjölä <mail@yrhki.fi> Co-authored-by: Kirill Primak <vyivel@posteo.net> Co-authored-by: Alexander Browne <elcste@users.noreply.github.com> Co-authored-by: Marco Rubin <20150305+Rubo3@users.noreply.github.com> Co-authored-by: Muhamed Hobi <woohoomoo2u@gmail.com> Co-authored-by: Simon Zeni <simon@bl4ckb0ne.ca> Co-authored-by: Nihal Jere <nihal@nihaljere.xyz> Co-authored-by: Alexander Gramiak <agrambot@gmail.com> Co-authored-by: Moon Sungjoon <sumoon@seoulsaram.org> Co-authored-by: Nicolas Avrutin <nicolas@avrutin.net> Co-authored-by: ndren <andreien@ctemplar.com> Co-authored-by: Bill Li <billli11hkb@gmail.com> Co-authored-by: Leonardo Hernández Hernández <leohdz172@protonmail.com> Co-authored-by: Oğuz Ersen <oguz@ersen.moe> Co-authored-by: Manuel Stoeckl <code@mstoeckl.com> Co-authored-by: Yasin Silavi <59373143+sttatusx@users.noreply.github.com> Co-authored-by: Daniel De Graaf <code@danieldg.net> Co-authored-by: kraftwerk28 <kefirchik3@gmail.com> Co-authored-by: Eskil <67291226+eschillus@users.noreply.github.com> Co-authored-by: Alice Carroll <git@alice-carroll.pet> Co-authored-by: Alan <51193876+Pound-Hash@users.noreply.github.com> Co-authored-by: Victor Makarov <vitja.makarov@gmail.com> Co-authored-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: -k <slowdive@me.com> Co-authored-by: Hongyi <61831273+FrozenArcher@users.noreply.github.com> Co-authored-by: Urey. Xue <urey.s.knowledge@gmail.com> Co-authored-by: LordRishav <75823494+LordRishav@users.noreply.github.com> Co-authored-by: Surendrajat <surendrajat@protonmail.com> Co-authored-by: Florian Franzen <Florian.Franzen@gmail.com> Co-authored-by: Greg Depoire--Ferrer <greg@gregdf.com> Co-authored-by: Thomas Jost <schnouki@schnouki.net> Co-authored-by: Hugo Osvaldo Barrera <hugo@barrera.io> Co-authored-by: zkldi <ktchidev@gmail.com> Co-authored-by: llyyr <llyyr.public@gmail.com> Co-authored-by: Baltazár Radics <baltazar.radics@gmail.com> Co-authored-by: Martin Michlmayr <tbm@cyrius.com> Co-authored-by: Filip Szczepański <jazz2rulez@gmail.com> Co-authored-by: Alex Maese <memaese@hotmail.com> Co-authored-by: マリウス <marius@xn--gckvb8fzb.com> Co-authored-by: Andri Yngvason <andri@yngvason.is> Co-authored-by: ohno418 <yutaro.ono.418@gmail.com> Co-authored-by: Ferdinand Schober <ferdinand.schober@fau.de> Co-authored-by: cparm <armelcadetpetit@gmail.com> Co-authored-by: Yaroslav de la Peña Smirnov <yps@yaroslavps.com> Co-authored-by: Alexander Orzechowski <orzechowski.alexander@gmail.com> Co-authored-by: pudiva chip líquida <pudiva@skylittlesystem.org> Co-authored-by: Puck Meerburg <puck@puckipedia.com> Co-authored-by: Callum Andrew <calcium@mailbox.org> Co-authored-by: Ronan Pigott <ronan@rjp.ie> Co-authored-by: Joan Bruguera <joanbrugueram@gmail.com> Co-authored-by: nerdopolis <bluescreen_avenger@verizon.net> Co-authored-by: Ankit Pandey <anpandey@protonmail.com> Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com>
2023-01-05 09:32:43 +11:00
if (server.session_lock.locked) {
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
if (server.session_lock.lock == NULL) {
// abandoned lock -> red BG
clear_color[0] = 1.f;
}
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
fx_renderer_clear(clear_color);
}
if (server.session_lock.lock != NULL) {
struct render_data data = {
.damage = damage,
.deco_data = get_undecorated_decoration_data(),
};
struct wlr_session_lock_surface_v1 *lock_surface;
wl_list_for_each(lock_surface, &server.session_lock.lock->surfaces, link) {
if (lock_surface->output != wlr_output) {
continue;
}
if (!lock_surface->mapped) {
continue;
}
output_surface_for_each_surface(output, lock_surface->surface,
0.0, 0.0, render_surface_iterator, &data);
}
}
goto renderer_end;
}
if (output_has_opaque_overlay_layer_surface(output)) {
goto render_overlay;
}
2024-01-23 02:39:44 +11:00
if (fullscreen_con && output->workspace_scroll.percent == 0) {
// Only draw fullscreen con if not transitioning between workspaces
render_fullscreen_con(damage, output, fullscreen_con, workspace, true);
2018-07-07 19:30:52 +10:00
} else {
pixman_region32_t blur_region;
pixman_region32_init(&blur_region);
bool workspace_has_blur = workspace_get_blur_info(workspace, &blur_region);
// Expand the damage to compensate for blur
if (workspace_has_blur) {
// Skip the blur artifact prevention if damaging the whole viewport
if (renderer->blur_buffer_dirty) {
// Needs to be extended before clearing
pixman_region32_union_rect(damage, damage,
0, 0, output_width, output_height);
} else {
// copy the surrounding content where the blur would display artifacts
// and draw it above the artifacts
// ensure that the damage isn't expanding past the output's size
int32_t damage_width = damage->extents.x2 - damage->extents.x1;
int32_t damage_height = damage->extents.y2 - damage->extents.y1;
if (damage_width > output_width || damage_height > output_height) {
pixman_region32_intersect_rect(damage, damage,
0, 0, output_width, output_height);
} else {
// Expand the original damage to compensate for surrounding
// blurred views to avoid sharp edges between damage regions
wlr_region_expand(damage, damage, config_get_blur_size());
}
pixman_region32_t extended_damage;
pixman_region32_init(&extended_damage);
pixman_region32_intersect(&extended_damage, damage, &blur_region);
// Expand the region to compensate for blur artifacts
wlr_region_expand(&extended_damage, &extended_damage, config_get_blur_size());
// Limit to the monitors viewport
pixman_region32_intersect_rect(&extended_damage, &extended_damage,
0, 0, output_width, output_height);
// capture the padding pixels around the blur where artifacts will be drawn
pixman_region32_subtract(&renderer->blur_padding_region,
&extended_damage, damage);
// Combine into the surface damage (we need to redraw the padding area as well)
pixman_region32_union(damage, damage, &extended_damage);
pixman_region32_fini(&extended_damage);
// Capture the padding pixels before blur for later use
fx_framebuffer_bind(&renderer->blur_saved_pixels_buffer);
// TODO: Investigate blitting instead
render_whole_output(renderer, wlr_output,
&renderer->blur_padding_region, &renderer->wlr_buffer.texture);
fx_framebuffer_bind(&renderer->wlr_buffer);
}
}
pixman_region32_fini(&blur_region);
2018-07-07 19:30:52 +10:00
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
2022-08-13 16:14:23 +10:00
fx_renderer_clear(clear_color);
2018-07-07 19:30:52 +10:00
}
render_layer_toplevel(output, damage,
2018-07-07 19:30:52 +10:00
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
render_layer_toplevel(output, damage,
2018-07-07 19:30:52 +10:00
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
// check if the background needs to be blurred
if (workspace_has_blur && renderer->blur_buffer_dirty) {
render_output_blur(output, damage);
}
render_workspace(output, damage, !fullscreen_con ? workspace : NULL,
workspace->current.focused,
!other_ws_has_fullscreen ? other_ws : NULL);
render_floating(output, damage,
!other_ws_has_fullscreen ? other_ws : NULL,
fullscreen_con != NULL);
2018-11-18 10:33:06 +11:00
#if HAVE_XWAYLAND
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
render_unmanaged(output, damage, &root->xwayland_unmanaged);
#endif
render_layer_toplevel(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
render_layer_popups(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
render_layer_popups(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
render_layer_popups(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
// Render the fullscreen containers on top
if (has_fullscreen) {
struct sway_workspace *workspaces[2] = { other_ws, workspace };
for (int i = 0; i < 2; i++) {
struct sway_workspace *ws = workspaces[i];
if (!ws) {
// Render a blank rect next to the fullscreen container if
// there's nothing to render
struct decoration_data deco_data = get_undecorated_decoration_data();
deco_data.on_focused_workspace = false;
struct wlr_box mon_box = { 0, 0, output->width, output->height };
adjust_box_to_workspace_offset(&mon_box, &deco_data, output);
scale_box(&mon_box, output->wlr_output->scale);
render_rect(output, damage, &mon_box, clear_color);
// Render a shadow to separate the edge and the fullscreen
// container
if (!config_should_parameters_shadow()) {
continue;
}
struct wlr_box shadow_box = { 0, 0, output->width, output->height };
deco_data.on_focused_workspace = true;
adjust_box_to_workspace_offset(&shadow_box, &deco_data, output);
scale_box(&shadow_box, output->wlr_output->scale);
// Render rect to fix minor pixel gaps between fullscreen
// container and shadow
render_rect(output, damage, &shadow_box, clear_color);
render_box_shadow(output, damage, &shadow_box,
config->shadow_color, config->shadow_blur_sigma, 0,
0, 0);
continue;
}
struct sway_container *f_con = ws == workspace ?
fullscreen_con : ws->current.fullscreen;
if (f_con) {
render_fullscreen_con(damage, output, f_con, ws, false);
}
}
}
2018-07-07 19:30:52 +10:00
}
render_seatops(output, damage);
struct sway_seat *seat = input_manager_current_seat();
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
struct sway_container *focus = seat_get_focused_container(seat);
if (focus && focus->view) {
struct decoration_data deco_data = {
.alpha = focus->alpha,
2022-12-07 16:10:11 +11:00
.dim_color = view_is_urgent(focus->view)
2023-04-16 03:44:56 +10:00
? config->dim_inactive_colors.urgent
: config->dim_inactive_colors.unfocused,
.dim = focus->current.focused ? 0.0f : focus->dim,
2023-01-23 18:35:46 +11:00
.corner_radius = 0,
.saturation = focus->saturation,
2023-01-23 18:35:46 +11:00
.has_titlebar = false,
.blur = false,
.discard_transparent = false,
.shadow = false,
.on_focused_workspace = true,
};
render_view_popups(focus->view, output, damage, deco_data);
}
render_overlay:
render_layer_toplevel(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
render_layer_popups(output, damage,
2018-07-07 19:30:52 +10:00
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
Implement type safe arguments and demote sway_container This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
2018-08-30 21:00:10 +10:00
render_drag_icons(output, damage, &root->drag_icons);
2018-07-07 19:30:52 +10:00
renderer_end:
// Not needed if we damaged the whole viewport
if (!renderer->blur_buffer_dirty) {
// Render the saved pixels over the blur artifacts
// TODO: Investigate blitting instead
render_whole_output(renderer, wlr_output, &renderer->blur_padding_region,
&renderer->blur_saved_pixels_buffer.texture);
}
fx_renderer_end(output->renderer);
fx_renderer_scissor(NULL);
// Draw the software cursors
2022-11-02 09:31:01 +11:00
wlr_renderer_begin(output->server->wlr_renderer, wlr_output->width, wlr_output->height);
wlr_output_render_software_cursors(wlr_output, damage);
2022-11-02 09:31:01 +11:00
wlr_renderer_end(output->server->wlr_renderer);
2018-12-01 21:01:08 +11:00
2019-04-28 00:49:37 +10:00
pixman_region32_t frame_damage;
pixman_region32_init(&frame_damage);
2018-12-01 21:01:08 +11:00
enum wl_output_transform transform = wlr_output_transform_invert(wlr_output->transform);
wlr_region_transform(&frame_damage, damage, transform, output_width, output_height);
2019-04-28 00:49:37 +10:00
if (debug.damage != DAMAGE_DEFAULT) {
2019-04-28 00:49:37 +10:00
pixman_region32_union_rect(&frame_damage, &frame_damage,
0, 0, wlr_output->width, wlr_output->height);
}
wlr_output_set_damage(wlr_output, &frame_damage);
pixman_region32_fini(&frame_damage);
2018-12-01 21:01:08 +11:00
2019-04-24 03:36:28 +10:00
if (!wlr_output_commit(wlr_output)) {
2018-07-07 19:30:52 +10:00
return;
}
rebase: Sway 1.8 (#78) * build: bump wlroots dependency to 0.16.0 * swaymsg: replace if with switch in pretty_print * swaymsg: add GET_TREE pretty-printing * swaybar: fix errno handling in status_handle_readable If getline fails once, it was not reset before the next getline call. errno is only overwritten by getline on error. * Add cairo_image_surface_create error handling cairo_image_surface_create can fail, e.g. when running out of memory or when the size is too big. Avoid crashing in this case. Closes: https://github.com/swaywm/sway/issues/6531 * build: bump version to 1.8-dev Historically we've been sticking with the last release number in the master branch. However that's a bit confusing, people can't easily figure out whether they're using a release or a work-in-progress snapshot. Only the commit hash appended to the version number may help, but that's not very explicit and disappears when using a tarball. We could bump the version in master to the next release number. However during the RC cycle there would be a downgrade from 1.8 to 1.8-rc1. Also it would be hard to tell the difference between a stable release and an old snapshot. This patch introduces a new pre-release identifier, "dev". It's alphabetically before "rc" so it should be correctly sorted by semver comparisons. "dev" is upgraded to "rc" (and then to stable) when doing a release. The master branch always uses a "dev" version, only release branches use "rc" or stable versions. * [IPC] Add repeat delay/rate info to keyboard Closes #6735 wlroots already has the info in the struct so let's access it and print it out. * input/seat: unset has_focus when focus_stack becomes empty We currently track the focus of a seat in two ways: we use a list called focus_stack to track the order in which nodes have been focused, with the first node representing what's currently focused, and we use a variable called has_focus to indicate whether anything has focus--i.e. whether we should actually treat that first node as focused at any given time. In a number of places, we treat has_focus as implying that a focused node exists. If it's true, we attempt to dereference the return value of seat_get_focus(), our helper function for getting the first node in focus_list, with no further checks. But this isn't quite correct with the current implementation of seat_get_focus(): not only does it return NULL when has_focus is false, it also returns NULL when focus_stack contains no items. In most cases, focus_stack never becomes empty and so this doesn't matter at all. Since focus_stack stores a history of focused nodes, we rarely remove nodes from it. The exception to this is when a node itself goes away. In that case, we call seat_node_destroy() to remove it from focus_stack and free it. But we don't unset has_focus if we've removed the final node! This lets us get into a state where has_focus is true but seat_get_focus() returns NULL, leading to a segfault when we try to dereference it. Fix the issue both by updating has_focus in seat_node_destroy() and by adding an assertion in seat_get_focus() that ensures focus_stack and has_focus are in sync, which will make it easier to track down similar issues in the future. Fixes #6395. [1] There's some discussion in #1585 from when this was implemented about whether has_focus is actually necessary; it's possible we could remove it entirely, but for the moment this is the architecture we have. * swaybar: fix tray_padding vs min-height re: scale Co-authored-by: xdavidwu <xdavidwuph@gmail.com> * swaybar: fix tray item icon scaling, positioning * container: Fix crash when view unmaps + maps quickly Followup on 4e4898e90f. If a view quickly maps and unmaps repeatedly, there will be multiple destroyed containers with same view in a single transaction. Each of these containers will then try to destroy this view, resulting in use after free. The container should only destroy the view if the view still belongs to the container. Simple reproducer: couple XMapWindow + XUnmapWindow in a loop followed by XDestroyWindow. See #6605 * commands/move: Fix crash when pos_y is omitted Fixes #6737 * Destroy sub-surfaces with parent layer-shell surface Closes: https://github.com/swaywm/sway/issues/6337 * Add safety assert in parse_movement_unit Let's add this just in case a caller passes argc == 0. References: https://github.com/swaywm/sway/issues/6737#issuecomment-1008082540 * meson: check: false on run_command Future meson releases will change the default and warns when the implicit default is used, breaking builds. Explicitly set check: false to maintain behavior and silence warnings. * Print deprecation notice when running SUID SUID privilege drop is needed for the "builtin"-backend of libseat, which copied our old "direct" backend behavior for the sake of compatibility and ease of transition. libseat now has a better alternative in the form of seatd-launch. It uses the normal seatd daemon and libseat backend and takes care of SUID for us. Add a soft deprecation warning to highlight our future intent of removing this code. The deprecation cycle is needed to avoid surprises when sway no longer drops privileges. * xdg-shell: use toplevel geometry to adjust the popup box `popup_unconstrain` uses view coordinates to init the output box for popups. However wlroots expects the box to be set in a toplevel surface coordinate system, which is not always equal to view. The difference between those is a window geometry set via xdg-shell. GTK4 reserves some space for client-side decoration and thus has a window with top left corner not matching to (0, 0) of a surface. The box calculated without taking that into account was slightly shifted compared to the actual output and allowed to position part of the popup off screen. * build: fix building with basu 02b412a introduced the use of list for sdbus deps, however it was assuming that all packages which were in a list has a version higher than 239. That is true for libsystemd and libelogind, since they use the same versions, however basu is using version numbers which are way lower than what libsystemd/libelogind are using, so basu only build is failing. * Upgrade for wlroots surface refactoring See [1] for details. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3412 * commands/focus: drop trailing whitespace * input/cursor: count pointer gestures as idle activity Fixes https://github.com/swaywm/sway/issues/6765. * input/cursor: treat swipe begin as idle activity too Accidentally overlooked in fd53f80. * treat fullscreen windows as 'tiled' for commands/focus * transaction: destroying nodes aren't hidden Commit 37d7bc69986f ("transaction: Only wait for ack from visible views") introduced a check which uses view_is_visible() to check if a view is still visible on the screen. However view_is_visible() will early return in case the node is in the destroying state. This is incorrect for transactions, since a destroying view which is visible will trigger configure events for other clients. This bug was visible when repeatedly opening and closing two views side by side, since we ignore the destroying node we get a frame where the still open view is shown with the old configure values and the rest is the desktop background. The next frame is than correct again. Fix this by considering destroying views as visible, we correctly wait for them and send the configure events to other views in time, fixing the background flicker. Fixes #6473 * build: execute wlroots subproject before finding deps wlroots often requires dependencies more recent than Sway's. Executing the wlroots subproject first will give Meson a chance to find these newer dependencies, possibly via subprojects. The subproject will override the "wlroots" dependency when executed, so we don't need to use get_variable anymore. References: https://github.com/swaywm/sway/pull/6498#issuecomment-1001746017 * tray: do not render passive items https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/#org.freedesktop.statusnotifieritem.status * cmd/swap: error on swapping a container with itself * input/cursor: pass through pointer hold gestures This just follows swaywm/wlroots#3047, so `wl_pointer_gestures_v1` clients can be notified of these events. * swaynag: remove buffer destruction condition An address of a variable can never be NULL, so checking it doesn't make sense; and `destroy_buffer()` can operate on already destroyed buffers anyway. Fixes #6780 * Use bools for CLI flags * xwayland: listen to `request_activate` event When REAPER submenu is closed `XCB_CLIENT_MESSAGE` with type `NET_ACTIVE_WINDOW` is sent to set focus to parent menu. Closes: https://github.com/swaywm/sway/issues/6324 * chore: chase wlr_output_layout_get_box() update https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3439 * Chase wlroots xdg-shell refactor * Minor update to focus_on_window_activation Removed xwayland limitation since wayland clients are supported via xdg-activation. * Translated README into Italian * readme: add link to Italian translation * readme: sort language list alphabetically * readme: use relative links for translations * xdg-shell: use wlr_xdg_toplevel in sway_view Improved type safety. Closes: https://github.com/swaywm/sway/issues/6813 * xdg-shell: use wlr_xdg_popup in sway_xdg_popup Improved type safety. * Fix snprintf compiler warning * Remove all sprintf calls Replace them with snprintf, which ensures buffer overflows won't happen. * sway/commands: add missing wlr_keyboard interface include in xkb_switch_layout * sway/input: use wlr_input_device from input device base * Remove some erroneous apostrophes in comments * Don't enter seatop_move_floating when fullscreen Currently, a floating window that's been fullscreened can send us xdg_toplevel::move, and we'll enter seatop_move_floating, which lets us drag the surface around while it's fullscreen. We don't want this--fullscreen surfaces should always be aligned to the screen--so add the same check that seatop_default already does when entering this mode. Tested with Weston's weston-fullscreen demo, which sends a move request if you click anywhere on its surface. * swaynag: die on all allocation failures * sway/input: don't pass possibly invalid modifiers pointer active_keyboard may be NULL, in which case an invalid pointer could be passed to wlr_input_method_keyboard_grab_v2_send_modifiers. This procedure call is unnecessary since wlroots commit 372a52ec "input method: send modifiers in set_keyboard", so the call can simply be removed. Fixes #6836. * sway/input: destroy sway_switch properly Fix: #6861 Added seat_device_destroy function to seat_device_destroy function. * commands/focus: fix segfault when no container is already focused. Fixes #6690. * Remove WLR_SWITCH_STATE_TOGGLE usage Ref [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/4792446ee8f50104bd207d9ccd8558a7e4eb4514 * Replace pcre with pcre2 Closes: https://github.com/swaywm/sway/issues/6838 * swaybar: remove swaybar_output.input_region No need to keep the region around, we can immediately destroy it after the wl_surface.set_input_region request. * swaybar: set opaque region When the background color is fully opaque, set the surface's opaque region to the whole surface. * Updating criteria checking with PCRE2 * swaynag: allocate button_details with details They are used together, so it doesn't make sense to allocate them separately. * swaynag: statically allocate button_close, and move declaration Every swaynag has a close button, so it doesn't make sense to allocate it dynamically. The declaration is moved later to when it is actually needed. * swaynag: remove unnecessary zero of swaynag struct Global variables are initialized to 0. * swaynag: remove redundant status variables in main Instead, we just use `status` for all failures. * remove unnecessary strlen call * sway/input/cursor: take device mm size from wlr_tablet * sway/input/seat: take output name from specialized input device * sway/input: follow up wlroots input device events renaming * sway/input: fix bad position of wlr_drag * sway/input: wlr_seat_keyboard() now takes wlr_keyboard * bash-completion: localize variables * sway/main: move constants off the stack This makes stack traces from gdb slightly easier to read. * Fix farsi label * Avoid format-truncation warning The existing code gives this error when compiled with GCC 12: ../sway/server.c: In function ‘server_init’: ../sway/server.c:217:75: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 8 [-Werror=format-truncation=] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~ ../sway/server.c:217:66: note: directive argument in the range [-2147483647, 32] 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~ ../sway/server.c:217:17: note: ‘snprintf’ output between 10 and 20 bytes into a destination of size 16 217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because i is never negative, this is a false positive, but it is easy to change i to unsigned to silence the error. * Shuffle variables to satisfy -Werror=restrict This also fixes an invalid strlen invocation on uninitialized memory. * layer_shell: keep output non-NULL wherever possible Our layer shell implementation assigns every layer surface to an output on creation. It tracks this output using the output field on the underlying wlr_layer_surface_v1 structure. As such, much of the existing code assumes that output is always non-NULL and omits NULL checks accordingly. However, there are currently two cases where we destroy a sway_layer_surface and output is NULL. The first is when we can't find an output to assign the surface to and destroy it immediately after creation. The second is when we destroy a surface in response to its output getting destroyed, as we set output to NULL in handle_output_destroy() before we call wlr_layer_surface_v1_destroy(), which is what calls the appropriate unmap and destroy callbacks. The former case doesn't cause any problems, since we haven't even allocated a sway_layer_surface at that point or registered any callbacks. The latter case, however, currently triggers a crash (#6120) if a popup is visible, since our popup_handle_unmap() implementation can't handle a NULL output. To fix this issue, keep output set until right before we free the sway_layer_surface. All we need to do is remove some of the cleanup logic from handle_output_destroy(), since as of commit c9060bcc12d0 ("layer-shell: replace close() with destroy()") that same logic is guaranteed to be happen later when wlroots calls handle_destroy() as part of wlr_layer_surface_v1_destroy(). This lets us remove some NULL checks from other unmap/destroy callbacks, which is nice. We also don't need to check that the wlr_output points to a valid sway_output anymore, since we unset that pointer after disabling the output as of commit a0bbe67076b8 ("Address emersions comments on output re-enabling") Just to be safe, I've added assertions that the wlr_output is non-NULL wherever we use it. Fixes #6120. * Chase wlroots X11 hints update * Add Swedish README * Support cursor capture in grimshot Refactor argument parser Bring back `sh` compatibility Default to NOTIFY=no * Update grimshot.1.scd Fixed typo. The object is **files**, which is plural. **image** modifies files; it's not countable. * xkb_switch_layout: fix relative layout switches Fixes #6011 * Implement ext-session-lock-v1 * Avoid inspecting a NULL view in seat_set_focus Fixes #6968 * swaynag: do error checking and rename read_from_stdin read_from_stdin not only read from stdin, but trimming trailing newlines, so rename it to reflect this. * swaynag: improve robustness when loading config * swaynag: combine consecutive declaration/assignments * config: Remove unused mouse binding structure Mouse bindings are handled alongside normal bindings. Remove the unused separate data structure definition to avoid confusion. Signed-off-by: Michael Weiser <michael.weiser@gmx.de> * Replace strncpy with memcpy strncpy is useless here, is dangerous because it doesn't guarantee that the string is NUL-terminated and causes the following warning: ../sway/criteria.c: In function ‘criteria_parse’: ../sway/criteria.c:712:25: error: ‘strncpy’ destination unchanged after copying no bytes [-Werror=stringop-truncation] 712 | strncpy(value, valuestart, head - valuestart); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Add descriptions for `stacking` and `tabbed` layouts Resolves #5918 * man: Fix trailing spaces * server: request xdg-shell v2 Wlroots does not yet support the newer xdg-shell versions and now requires the compositor to set the supported xdg-shell version during creation. Set this to v2 for sway as well. Fixes https://github.com/swaywm/sway/issues/7001 * realtime: request SCHED_RR using CAP_SYS_NICE Try to gain SCHED_RR (round-robin) realtime scheduling privileges before starting the server. This requires CAP_SYS_NICE on Linux systems. We additionally register a pthread_atfork callback which resets the scheduling class back to SCHED_OTHER (the Linux system default). Due to CAP_SYS_NICE, setting RLIMIT_RTPRIO has no effect on the process as documented within man 7 sched (from Linux): Privileged (CAP_SYS_NICE) threads ignore the RLIMIT_RTPRIO limit; as with older kernels, they can make arbitrary changes to scheduling policy and priority. See getrlimit(2) for further information on RLIMIT_RTPRIO Note that this requires the sway distribution packagers to set the CAP_SYS_NICE capability on the sway binary. Supersedes #6992 * ext-session-lock: disable direct scan-out when locked * Polish the language in README.zh-CN.md & sync with English one Co-Authored-By: Urey. Xue <urey.s.knowledge@gmail.com> * De-duplicate IPC output descriptions * Handle NULL output make/model/serial * chore: chase wlroots xdg-shell update * xdg-shell: schedule a configure on maximize request This commit reverts 03879290dbee26127f6867ef60bc2a7f9a6c8c5f and fc84bcb7fb0ffa29b1f9bed287762241a3473803. * Add a Hindi (हिन्दी) translation to the README Hindi is one of the most prominent languages of the Indian Subcontinent. This commit adds the translation of the README into the Hindi language. Some of the words are still written in English because there wasn't an appropriate technical term of the word in the language. Co-authored-by: Surendrajat <surendrajat@protonmail.com> * sway: add bindgesture command Co-authored-by: Michael Weiser <michael.weiser@gmx.de> * build: link with -pthread Fixes the following FreeBSD error: ld: error: undefined symbol: pthread_getschedparam >>> referenced by realtime.c:25 (../sway/realtime.c:25) >>> sway/sway.p/realtime.c.o:(set_rr_scheduling) Fixes: a3a82efbf6b5 ("realtime: request SCHED_RR using CAP_SYS_NICE") * ipc: remove chatty debug log messages These aren't particularly useful, and clobber the debug logs. * Refuse to start when SUID is detected This ensures that those surprised by the deprecation of SUID operation receive an error rather than accidentally having sway run as root. This detection will be removed in a future release. * swaynag: move close_button up to fix SIGSEGV When swaynag_parse_options encounters '--dismiss-button' (or its shorthand '-s'), it sets the text of the first button in the swaynag.buttons list, which is expected to exist and to be the dismiss button, to the one passed by the user. Commit 4780afb68b4ee2cdf0e4925f40cf885819f8a74a ("swaynag: statically allocate button_close, and move declaration") moved the list initialization to after swaynag_parse_options is called which made that code fail. For example, the command 'swaynag --dismiss-button Dismiss' crashes and 'swaynag --message Message --button Yes "" --dismiss-button Dismiss' shows the wrong buttons. Move it back to before swaynag_parse_options is called. * config/output: use wlr_output_commit_state This makes the code more robust because we don't potentially leave bad state in wlr_output.pending behind anymore. This also fixes a bug. Closes: https://github.com/swaywm/sway/issues/7043 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3610 * Allocate enough space for `cmd_results->error` * Remove access to wlr_input_device union References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3626 Closes: https://github.com/swaywm/sway/issues/7077 * Rename dpms output command to power The "dpms" command refers to VESA Display Power Management Signaling, a deprecated standard. It's superseded by VESA DPM. Instead of tying out command name to a particular standard, use the neutral term "power". * Strip quotes in bindsym --input-device=... If the input device is quoted, which is common when using variables in the config file, those quotes must be ignored here, or the input device will be ignored. Fixes #7029. * Avoid unecessary string copy * Reject font values that are invalid for pango Use pango to parse font configuration early, and reject the command as invalid if the value is invalid for pango. Since we're already parsing the font into a `PangoFontDescription`, keep that instance around and avoid re-parsing the font each time we render text. Fixes: https://github.com/swaywm/sway/issues/6805 * Reuse parsed PangoFontDescription Avoids parsing the configured font each time text is rendered. * ipc: add "power" to output reply * config.in: switch to `output power` * Remove internal references to DPMS While at it, use an int for the config field, just like we do for all other fields. * fix: remove redundant empty statement in main.c This semi-colon looks like a typo. Luckily, it has no effect on the code as it's treated as an empty statement leading the switch case. Really straightforward nitpick change, was just something I was confused by when reading over the code. * input: chase delta_discrete semantics change * swaymsg: fix floating_nodes being ignored Fix floating_nodes being ignored in pretty_print_tree. * ipc: make get_deco_rect check config->hide_lone_tab Without this, the `IPC_GET_TREE` ipc call would return false information about the container's `deco_rect` and `rect` properties if `hide_edge_borders --i3` was in effect. * grimshot: fix tilde expansion within quotes * Enable single-pixel-buffer-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3428 * sway-output.5: improve display of parameter Since "width" and "height" are separate parameters, show them as such. * man: sway(5) move fixes * ipc: drop WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN case This has been removed from wlroots. * config/output: test adaptive sync Required for [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3637 * Fix crash in xdg_activation_v1.c wlr_xdg_surface_from_wlr_surface() can return a NULL pointer, so check for NULL before dereferencing it. * sway: Add non-desktop-output type Currently, when encountering a non-desktop display, sway offers the output for leasing and returns without storing it in a sway specific output type like `struct sway_output`. Additionally, running `swaymsg -t get_outputs` doesn't show non-desktop outputs. This commit stores the non-desktop outputs into a struct called `sway_output_non_desktop`, and adds them to a list on `sway_root` * sway: add non-desktop outputs to json when running `swaymsg -t get_outputs` * swaymsg: show non-desktop property when pretty printing outputs * man: Add XWayland information * ipc: expose mode picture aspect ratio * swaymsg: show mode picture aspect ratio * build: simplify protocol paths No need for arrays here. * sway/commands/output: Add command for unplugging non-physical outputs * Improve Japanese translation * allow pointer_constraints on layer_shell surfaces * check for NULL * use seat directly * Use keyboard_state.focused_surface directly * input: focus floating container when clicked on border Fixes #7209. * input: focus container when scrolling on titlebar Fixes #6503. * Fix leaks in criteria_destroy() * Avoid double free in criteria_destroy() * Add support for ext-idle-notify-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3753 * input: tweak focus behavior to allow focusing parent containers Sway focuses the inactive child when focusing split containers. However, there is currently no way to focus the parent container itself by mouse. A user must use the keyboard to do so. This commit maintains the current behavior, but makes it such that a second click on the split container titlebar (i.e., after its children are visible) focuses the split container itself. * Fix keymap being NULL and segfaulting on dev add Moved `libinput_config` to the callers of `sway_input_configure_libinput_device` so that we send the event after the added event. * Rework session lock keyboard focus handling When removing outputs, it is possible to end up in a situation where none of the session lock client's surfaces have keyboard focus, resulting in it not receiving keyboard events. Track the focused surface and update it as needed on surface destroy. * Fix focus tracking when session lock is active Remove the incorrect attempt to block focus changes when an input grab is present and replace it with the same logic used for layer_shell-based screen lockers: restore the focus after changing it. This fixes a use-after-free of seat->workspace if outputs are destroyed while a screen lock is enabled. * container_floating_set_default_size: Store workspace size box on the stack * Support libinput's 1.21 new dwtp option Support the new dwtp (disable while trackpointing) option introduced in libinput 1.21, allowing users to control whether the trackpoint (like those in Thinkpads, but not only) should be disabled while using the keyboard/touchpad. See: https://gitlab.freedesktop.org/libinput/libinput/-/issues/731 * tree: support formatting null titles Any windows that have never had a title set visually behave closer to that of an empty title, but are unformattable, as the code bails out early on a NULL title. * criteria: allow matching on empty (NULL) titles * criteria: allow matching for NULL string criteria * ci: install hwdata * Use wl_signal_emit_mutable() This function fixes segfaults when emitting a signal potentially removes arbitrary listeners. * Use wlr_damage_ring wlr_output_damage is to be replaced with wlr_damage_ring, so use that. * lock: fix crash on output destroy Closes: https://github.com/swaywm/sway/issues/7120 * container_get_siblings: handle NULL workspace * ci: checkout wlroots 0.16.0 * workspace_create: Don't allow NULL name (cherry picked from commit 34933bb84350fe805d82276ea02d5732546e9993) * output: set damage ring bounds to pixel values Fixes: https://github.com/swaywm/sway/issues/7254 (cherry picked from commit 85005b52fe5b832e4ea914fa28048b0c5c803769) * Use shm_open instead of mkstemp shm_open is more reliable because it does not require a writeable filesystem folder, unlike mkstemp. (cherry picked from commit e2bc8866f46701e9c825ad7fa5baac02b2e4898f) * build: drop wayland-scanner fallback (cherry picked from commit 366f6ef3d31688631dc453028e108f98a1d7ab57) * build: unify server & client protocol generation No need to make a difference here, let's just generate header files for both. (cherry picked from commit 5be5a038da8a3789a19945719f2a27233291445d) * build: drop "server" from target name for protocol code (cherry picked from commit e5475d9310941ce88ed016ce1515b36e3a440252) * build: drop intermediate libraries for protocols (cherry picked from commit af8a5a8918ef42336194fb1077b008a736de7af9) * root: move the workspace matching code to its own file This removes the pid_workspace bits from tree/root before it gets too interesting. No functional change. (cherry picked from commit eb5021ef990fb29ff86544aea58d687ad62c757a) * node: prettify node type names (cherry picked from commit 1c4b94ae3ca94b972410c80a61404a347af1ee68) * launcher: track workspaces by node This removes the need to rename the pid_workspaces when a workspace is renamed. It also opens the possibility of tracking other node types. Tracking containers would allow application to be placed correctly in the container tree even if the user has moved their focus elsewhere since it was launched. (cherry picked from commit 3b49f2782e8faf68766269b9c7390b16e25ae824) * launcher: use xdga tokens This reuses wlroots token tracking for workspace matching. It doesn't export any xdga tokens for clients yet. (cherry picked from commit bd66f4943da1c96edc3ba49573e27b42b688c543) * launcher: rename pid_workspace to launcher_ctx Soon we will match views with more than just a pid. (cherry picked from commit d75c9f9722389d441fd24bd490c5cf12c4bef39a) * view: associate launch contexts with views Views now maintain a reference to a launch context which, as a last resort, is populated at map time with a context associated with its pid. This opens the possibility of populating it before map via another source, e.g. xdga-tokens or configuration. (cherry picked from commit 864b3a9a18f236f92f1898bb44ab977ceaebfd68) * launcher: initialize launcher_ctxs once on startup (cherry picked from commit 66568508c06267445489d655c91c94a34d6d9ffe) * launcher: fudge the interface a bit We want to create a context before knowing the pid it will match with. (cherry picked from commit bdeb9f95651f6c99cc2f4cfb59020ddee202cf36) * launcher: export xdga tokens and use them for workspace matching (cherry picked from commit 30ad4dc4a5a41ce7c7aa85096a6e18f374172983) * launcher: export X startup ids and use them for workspace matching (cherry picked from commit 28fda4c0d38907fab94dc7d82c9dcf0754748b4e) * swaybar: Prioritize hotspot events to bar bindings This is consistent with i3bar's behaviour, and for example, allows binding a command to button1, while still being able to click on tray icons or other zones on the bar's status line which may have their own bindings. E.g., in Sway, without this commit, this config. makes tray icons unclickable: bar { # ... bindsym button1 exec swaynag -m You_clicked_the_tray._Want_some_help? } But the same configuration in i3 (with i3-nagbar) keeps tray items clickable. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 53f9dbd424dc173a85c9f4cd30802259d38b1ef4) * swaybar: Make hotspots block bar release bindings The previous commit prioritized hotspots before bar bindings for press events, which matches i3's behaviour. However, since hotspots don't need to do any processing on release events, those were not handled, and simply fell through to `bindsym --release` bar bindings (if any). This is counter-intuitive, and doesn't match i3's behaviour. Instead in case a hotspot handles the press event, it should also handle the release event, doing nothing, but blocking the event from triggering a --release bar binding. E.g., in Sway, without this commit, this config. shows a text on tray clicks: bar { # ... bindsym --release button1 exec swaynag -m I_got_the_release_event. } But the same configuration in i3 (with i3-nagbar) doesn't show the text. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 94b69acf0d7b26ee5af2172300cb18473508da76) * build: drop unused wayland-egl dependency (cherry picked from commit 37e4a3d6370dc6ba2b0877d588845c06781e880e) * build: bump version to 1.8-rc1 * Fix build on Debian Stable (cherry picked from commit dca0bb5749bc16f91ab964fc1b06ebb9a453368f) * build: fix have_xwayland when xcb-icccm is not found xcb-icccm is required to build Xwayland support. Backported from commit d41f11e6bd8cef80f02dda4c66d4a31611aed753. * build: bump version to 1.8-rc2 * seat: Avoid sending redundant keymaps on reload When we reload the config, we reset every input device and re-apply configuration from the config file. This means that the keyboard keymap is updated at least once during config reload, more if the config file contains keyboard configuration. When they keyboard keymap changes and is updated through wlr_seat, the keymap ends up sent to every keyboard bound in every client, seemingly multiple times. On an x230 of mine with a keyboard layout set in the config file, I see 42 keymap events sent to foot on config reload. Reduce events from keyboard configurations by skipping all but the currently active keyboard for the seat, and by clearing the active keyboard during input manager device reset. After this change, I only see a single just-in-time keymap event. Fixes: https://github.com/swaywm/sway/issues/6654 * criteria: be lenient on window_role and instance too * build: bump version to 1.8-rc3 * commands/move: Warp cursor after moving workspace to another output This makes sway's behavior consistent with i3 when `mouse_warping` is set to any value besides `none`. Fixes #7027. (cherry picked from commit e3c63bf58d0744dfb436f0f38442ce3735e40f47) * seat: Set keyboard if seat keyboard is NULL sway sends wl_keyboard.enter on seat focus change and when a keyboard active on a seat is configured. If all keyboards are removed and a keyboard is added back without changing the focused client, no new notify event would be sent despite having keyboard focus. This could lead to key events without notify, which is a protocol violation. As a quick fix, when configuring a keyboard on a seat where no keyboard is currently active, activate the keyboard so that a focused surface will receive a notify event. Regressed by: e1b268af98edeb09e570e8855ef64f0719cbafe2 Closes: https://github.com/swaywm/sway/issues/7330 (cherry picked from commit 1ade0ce753dc5f588584f444ce80d27c3b1e4300) * build: bump version to 1.8-rc4 * swaynag: fix NULL font description The font description was only set if provided on the CLI. It was left NULL for the defaults and when reading from the config file. Closes: https://github.com/swaywm/sway/issues/7186 (cherry picked from commit fd0af78e43f4dd67a404f475c676b25ae38a4b82) * build: bump version to 1.8 * Removed other README languages * Fixed build issues * Removed alpha from render_data struct * Updated PKGBUILDs and COPR spec * Update sway/desktop/render.c Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com> * Fixed deco_data not being initialized properly * Replaced wlr_egl_(make|unset)_current with eglMakeCurrent * Added matrix_projection into fx_renderer Signed-off-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: Sefa Eyeoglu <contact@scrumplex.net> Co-authored-by: Simon Ser <contact@emersion.fr> Co-authored-by: Seth Barberee <seth.barberee@gmail.com> Co-authored-by: Thomas Hebb <tommyhebb@gmail.com> Co-authored-by: Nathan Schulte <nmschulte@gmail.com> Co-authored-by: xdavidwu <xdavidwuph@gmail.com> Co-authored-by: David Rosca <nowrep@gmail.com> Co-authored-by: David96 <david@hameipe.de> Co-authored-by: Kenny Levinsen <kl@kl.wtf> Co-authored-by: Aleksei Bavshin <alebastr89@gmail.com> Co-authored-by: Kirill Chibisov <contact@kchibisov.com> Co-authored-by: Tudor Brindus <me@tbrindus.ca> Co-authored-by: Patrick Hilhorst <git@hilhorst.be> Co-authored-by: Rouven Czerwinski <rouven@czerwinskis.de> Co-authored-by: Tobias Bengfort <tobias.bengfort@posteo.de> Co-authored-by: Ronan Pigott <rpigott@berkeley.edu> Co-authored-by: Kirill Primak <vyivel@eclair.cafe> Co-authored-by: Tuomas Yrjölä <mail@yrhki.fi> Co-authored-by: Kirill Primak <vyivel@posteo.net> Co-authored-by: Alexander Browne <elcste@users.noreply.github.com> Co-authored-by: Marco Rubin <20150305+Rubo3@users.noreply.github.com> Co-authored-by: Muhamed Hobi <woohoomoo2u@gmail.com> Co-authored-by: Simon Zeni <simon@bl4ckb0ne.ca> Co-authored-by: Nihal Jere <nihal@nihaljere.xyz> Co-authored-by: Alexander Gramiak <agrambot@gmail.com> Co-authored-by: Moon Sungjoon <sumoon@seoulsaram.org> Co-authored-by: Nicolas Avrutin <nicolas@avrutin.net> Co-authored-by: ndren <andreien@ctemplar.com> Co-authored-by: Bill Li <billli11hkb@gmail.com> Co-authored-by: Leonardo Hernández Hernández <leohdz172@protonmail.com> Co-authored-by: Oğuz Ersen <oguz@ersen.moe> Co-authored-by: Manuel Stoeckl <code@mstoeckl.com> Co-authored-by: Yasin Silavi <59373143+sttatusx@users.noreply.github.com> Co-authored-by: Daniel De Graaf <code@danieldg.net> Co-authored-by: kraftwerk28 <kefirchik3@gmail.com> Co-authored-by: Eskil <67291226+eschillus@users.noreply.github.com> Co-authored-by: Alice Carroll <git@alice-carroll.pet> Co-authored-by: Alan <51193876+Pound-Hash@users.noreply.github.com> Co-authored-by: Victor Makarov <vitja.makarov@gmail.com> Co-authored-by: Michael Weiser <michael.weiser@gmx.de> Co-authored-by: -k <slowdive@me.com> Co-authored-by: Hongyi <61831273+FrozenArcher@users.noreply.github.com> Co-authored-by: Urey. Xue <urey.s.knowledge@gmail.com> Co-authored-by: LordRishav <75823494+LordRishav@users.noreply.github.com> Co-authored-by: Surendrajat <surendrajat@protonmail.com> Co-authored-by: Florian Franzen <Florian.Franzen@gmail.com> Co-authored-by: Greg Depoire--Ferrer <greg@gregdf.com> Co-authored-by: Thomas Jost <schnouki@schnouki.net> Co-authored-by: Hugo Osvaldo Barrera <hugo@barrera.io> Co-authored-by: zkldi <ktchidev@gmail.com> Co-authored-by: llyyr <llyyr.public@gmail.com> Co-authored-by: Baltazár Radics <baltazar.radics@gmail.com> Co-authored-by: Martin Michlmayr <tbm@cyrius.com> Co-authored-by: Filip Szczepański <jazz2rulez@gmail.com> Co-authored-by: Alex Maese <memaese@hotmail.com> Co-authored-by: マリウス <marius@xn--gckvb8fzb.com> Co-authored-by: Andri Yngvason <andri@yngvason.is> Co-authored-by: ohno418 <yutaro.ono.418@gmail.com> Co-authored-by: Ferdinand Schober <ferdinand.schober@fau.de> Co-authored-by: cparm <armelcadetpetit@gmail.com> Co-authored-by: Yaroslav de la Peña Smirnov <yps@yaroslavps.com> Co-authored-by: Alexander Orzechowski <orzechowski.alexander@gmail.com> Co-authored-by: pudiva chip líquida <pudiva@skylittlesystem.org> Co-authored-by: Puck Meerburg <puck@puckipedia.com> Co-authored-by: Callum Andrew <calcium@mailbox.org> Co-authored-by: Ronan Pigott <ronan@rjp.ie> Co-authored-by: Joan Bruguera <joanbrugueram@gmail.com> Co-authored-by: nerdopolis <bluescreen_avenger@verizon.net> Co-authored-by: Ankit Pandey <anpandey@protonmail.com> Co-authored-by: Alexis Tacnet <alexistacnet@gmail.com>
2023-01-05 09:32:43 +11:00
wlr_damage_ring_rotate(&output->damage_ring);
2018-07-07 19:30:52 +10:00
output->last_frame = *when;
}