├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── others.md └── workflows │ ├── ci.yaml │ └── mandoc.yaml ├── .gitignore ├── .gitmodules ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── config.h.in ├── man ├── meson.build └── wayfire.1.in ├── meson.build ├── meson_options.txt ├── metadata ├── alpha.xml ├── animate.xml ├── autostart.xml ├── blur.xml ├── command.xml ├── core.xml ├── cube.xml ├── decoration.xml ├── expo.xml ├── extra-gestures.xml ├── fast-switcher.xml ├── fisheye.xml ├── foreign-toplevel.xml ├── grid.xml ├── gtk-shell.xml ├── idle.xml ├── input-device.xml ├── input-method-v1.xml ├── input.xml ├── invert.xml ├── ipc-rules.xml ├── ipc.xml ├── meson.build ├── move.xml ├── oswitch.xml ├── output.xml ├── place.xml ├── preserve-output.xml ├── resize.xml ├── scale-title-filter.xml ├── scale.xml ├── session-lock.xml ├── shortcuts-inhibit.xml ├── simple-tile.xml ├── switcher.xml ├── vswipe.xml ├── vswitch.xml ├── wayfire-shell.xml ├── window-rules.xml ├── wm-actions.xml ├── wobbly.xml ├── workarounds.xml ├── wrot.xml ├── wsets.xml ├── xdg-activation.xml └── zoom.xml ├── plugins ├── animate │ ├── animate.cpp │ ├── animate.hpp │ ├── basic_animations.hpp │ ├── fire │ │ ├── fire.cpp │ │ ├── fire.hpp │ │ ├── particle.cpp │ │ ├── particle.hpp │ │ └── shaders.hpp │ ├── meson.build │ ├── shaders │ │ ├── frag.glsl │ │ └── vertex.glsl │ ├── spin.hpp │ ├── squeezimize.hpp │ ├── system_fade.hpp │ ├── unmapped-view-node.hpp │ └── zap.hpp ├── blur │ ├── blur-base.cpp │ ├── blur.cpp │ ├── blur.hpp │ ├── bokeh.cpp │ ├── box.cpp │ ├── gaussian.cpp │ ├── kawase.cpp │ └── meson.build ├── common │ ├── meson.build │ └── wayfire │ │ └── plugins │ │ └── common │ │ ├── cairo-util.hpp │ │ ├── geometry-animation.hpp │ │ ├── input-grab.hpp │ │ ├── key-repeat.hpp │ │ ├── move-drag-interface.hpp │ │ ├── preview-indication.hpp │ │ ├── shared-core-data.hpp │ │ ├── simple-text-node.hpp │ │ ├── simple-texture.hpp │ │ ├── util.hpp │ │ └── workspace-wall.hpp ├── cube │ ├── cube-background.hpp │ ├── cube-control-signal.hpp │ ├── cube.cpp │ ├── cube.hpp │ ├── cubemap-shaders.tpp │ ├── cubemap.cpp │ ├── cubemap.hpp │ ├── meson.build │ ├── shaders-3-2.tpp │ ├── shaders.tpp │ ├── simple-background.cpp │ ├── simple-background.hpp │ ├── skydome.cpp │ └── skydome.hpp ├── decor │ ├── deco-button.cpp │ ├── deco-button.hpp │ ├── deco-layout.cpp │ ├── deco-layout.hpp │ ├── deco-subsurface.cpp │ ├── deco-subsurface.hpp │ ├── deco-theme.cpp │ ├── deco-theme.hpp │ ├── decoration.cpp │ └── meson.build ├── grid │ ├── grid.cpp │ ├── meson.build │ └── wayfire │ │ └── plugins │ │ ├── crossfade.hpp │ │ └── grid.hpp ├── ipc-rules │ ├── ipc-events.hpp │ ├── ipc-input-methods.hpp │ ├── ipc-rules-common.hpp │ ├── ipc-rules.cpp │ ├── ipc-utility-methods.hpp │ └── meson.build ├── ipc │ ├── demo-ipc.cpp │ ├── ipc-activator.hpp │ ├── ipc-helpers.hpp │ ├── ipc-method-repository.hpp │ ├── ipc.cpp │ ├── ipc.hpp │ ├── meson.build │ └── stipc.cpp ├── meson.build ├── protocols │ ├── foreign-toplevel.cpp │ ├── gtk-shell.cpp │ ├── gtk-shell.hpp │ ├── input-method-v1.cpp │ ├── input-method-v1.hpp │ ├── meson.build │ ├── session-lock.cpp │ ├── shortcuts-inhibit.cpp │ ├── text-input-v1-v3.hpp │ ├── wayfire-shell.cpp │ └── xdg-activation.cpp ├── scale │ ├── meson.build │ ├── scale-title-filter.cpp │ ├── scale-title-overlay.cpp │ ├── scale-title-overlay.hpp │ ├── scale.cpp │ ├── scale.hpp │ └── wayfire │ │ └── plugins │ │ └── scale-signal.hpp ├── single_plugins │ ├── alpha.cpp │ ├── autostart.cpp │ ├── command.cpp │ ├── compositor-view-test.cpp │ ├── expo.cpp │ ├── extra-gestures.cpp │ ├── fast-switcher.cpp │ ├── fisheye.cpp │ ├── idle.cpp │ ├── invert.cpp │ ├── meson.build │ ├── move.cpp │ ├── oswitch.cpp │ ├── place.cpp │ ├── preserve-output.cpp │ ├── resize.cpp │ ├── switcher.cpp │ ├── vswipe-processing.hpp │ ├── vswipe.cpp │ ├── wrot.cpp │ ├── wsets.cpp │ ├── xkb-bindings.cpp │ └── zoom.cpp ├── tile │ ├── meson.build │ ├── tile-dragging.hpp │ ├── tile-ipc.hpp │ ├── tile-plugin.cpp │ ├── tile-wset.hpp │ ├── tree-controller.cpp │ ├── tree-controller.hpp │ ├── tree.cpp │ └── tree.hpp ├── vswitch │ ├── meson.build │ ├── vswitch.cpp │ └── wayfire │ │ └── plugins │ │ └── vswitch.hpp ├── window-rules │ ├── lambda-rules-registration.hpp │ ├── meson.build │ ├── view-action-interface.cpp │ ├── view-action-interface.hpp │ └── window-rules.cpp ├── wm-actions │ ├── meson.build │ ├── wm-actions-signals.hpp │ └── wm-actions.cpp └── wobbly │ ├── meson.build │ ├── wayfire │ └── plugins │ │ └── wobbly │ │ └── wobbly-signal.hpp │ ├── wobbly.c │ ├── wobbly.cpp │ └── wobbly.h ├── proto ├── gtk-shell.xml ├── meson.build ├── wayfire-shell-unstable-v2.xml ├── wlr-layer-shell-unstable-v1.xml └── wlr-output-power-management-unstable-v1.xml ├── src ├── api │ └── wayfire │ │ ├── bindings-repository.hpp │ │ ├── bindings.hpp │ │ ├── compositor-view.hpp │ │ ├── config-backend.hpp │ │ ├── core.hpp │ │ ├── dassert.hpp │ │ ├── debug.hpp │ │ ├── geometry.hpp │ │ ├── idle.hpp │ │ ├── img.hpp │ │ ├── input-device.hpp │ │ ├── matcher.hpp │ │ ├── nonstd │ │ ├── observer_ptr.h │ │ ├── reverse.hpp │ │ ├── safe-list.hpp │ │ ├── tracking-allocator.hpp │ │ ├── wlroots-full.hpp │ │ └── wlroots.hpp │ │ ├── object.hpp │ │ ├── opengl.hpp │ │ ├── option-wrapper.hpp │ │ ├── output-layout.hpp │ │ ├── output.hpp │ │ ├── per-output-plugin.hpp │ │ ├── plugin.hpp │ │ ├── region.hpp │ │ ├── render-manager.hpp │ │ ├── scene-input.hpp │ │ ├── scene-operations.hpp │ │ ├── scene-render.hpp │ │ ├── scene.hpp │ │ ├── seat.hpp │ │ ├── signal-definitions.hpp │ │ ├── signal-provider.hpp │ │ ├── toplevel-view.hpp │ │ ├── toplevel.hpp │ │ ├── txn │ │ ├── transaction-manager.hpp │ │ ├── transaction-object.hpp │ │ └── transaction.hpp │ │ ├── unstable │ │ ├── translation-node.hpp │ │ ├── wlr-subsurface-controller.hpp │ │ ├── wlr-surface-controller.hpp │ │ ├── wlr-surface-node.hpp │ │ ├── wlr-text-input-v3-popup.hpp │ │ ├── wlr-view-events.hpp │ │ ├── wlr-view-keyboard-interaction.hpp │ │ ├── xdg-toplevel-base.hpp │ │ └── xwl-toplevel-base.hpp │ │ ├── util.hpp │ │ ├── view-access-interface.hpp │ │ ├── view-helpers.hpp │ │ ├── view-transform.hpp │ │ ├── view.hpp │ │ ├── window-manager.hpp │ │ ├── workarea.hpp │ │ ├── workspace-set.hpp │ │ └── workspace-stream.hpp ├── core │ ├── core-impl.hpp │ ├── core.cpp │ ├── gldebug.hpp │ ├── idle.cpp │ ├── img.cpp │ ├── matcher.cpp │ ├── object.cpp │ ├── opengl-priv.hpp │ ├── opengl.cpp │ ├── output-layout.cpp │ ├── plugin-loader.cpp │ ├── plugin-loader.hpp │ ├── plugin.cpp │ ├── scene-priv.hpp │ ├── scene.cpp │ ├── seat │ │ ├── bindings-repository-impl.hpp │ │ ├── bindings-repository.cpp │ │ ├── cursor.cpp │ │ ├── cursor.hpp │ │ ├── drag-icon.cpp │ │ ├── drag-icon.hpp │ │ ├── hotspot-manager.cpp │ │ ├── hotspot-manager.hpp │ │ ├── input-manager.cpp │ │ ├── input-manager.hpp │ │ ├── input-method-popup.cpp │ │ ├── input-method-relay.cpp │ │ ├── input-method-relay.hpp │ │ ├── keyboard.cpp │ │ ├── keyboard.hpp │ │ ├── pointer.cpp │ │ ├── pointer.hpp │ │ ├── pointing-device.cpp │ │ ├── pointing-device.hpp │ │ ├── seat-impl.hpp │ │ ├── seat.cpp │ │ ├── switch.cpp │ │ ├── switch.hpp │ │ ├── tablet.cpp │ │ ├── tablet.hpp │ │ ├── touch.cpp │ │ └── touch.hpp │ ├── shaders.tpp │ ├── txn │ │ ├── transaction-manager-impl.hpp │ │ ├── transaction-manager.cpp │ │ └── transaction.cpp │ ├── view-access-interface.cpp │ ├── window-manager.cpp │ ├── wm.cpp │ └── wm.hpp ├── debug.cpp ├── default-config-backend.cpp ├── geometry.cpp ├── main.cpp ├── main.hpp ├── meson.build ├── output │ ├── output-impl.hpp │ ├── output.cpp │ ├── promotion-manager.hpp │ ├── render-manager.cpp │ ├── workarea.cpp │ ├── workspace-impl.cpp │ └── workspace-stream.cpp ├── pch │ └── pch.h ├── region.cpp ├── util.cpp ├── version │ ├── git-branch.cpp.in │ └── git-commit.cpp.in ├── view │ ├── compositor-view.cpp │ ├── layer-shell │ │ ├── layer-shell-node.cpp │ │ ├── layer-shell-node.hpp │ │ └── layer-shell.cpp │ ├── toplevel-node.cpp │ ├── toplevel-node.hpp │ ├── toplevel-view.cpp │ ├── translation-node.cpp │ ├── view-3d.cpp │ ├── view-impl.cpp │ ├── view-impl.hpp │ ├── view.cpp │ ├── wlr-subsurface-controller.cpp │ ├── wlr-surface-controller.cpp │ ├── wlr-surface-node.cpp │ ├── wlr-surface-pointer-interaction.hpp │ ├── wlr-surface-touch-interaction.cpp │ ├── xdg-shell.cpp │ ├── xdg-shell.hpp │ ├── xdg-shell │ │ ├── xdg-toplevel-view.cpp │ │ ├── xdg-toplevel-view.hpp │ │ ├── xdg-toplevel.cpp │ │ └── xdg-toplevel.hpp │ ├── xwayland.cpp │ └── xwayland │ │ ├── xwayland-helpers.cpp │ │ ├── xwayland-helpers.hpp │ │ ├── xwayland-toplevel-view.cpp │ │ ├── xwayland-toplevel-view.hpp │ │ ├── xwayland-toplevel.cpp │ │ ├── xwayland-toplevel.hpp │ │ ├── xwayland-unmanaged-view.hpp │ │ ├── xwayland-view-base.cpp │ │ └── xwayland-view-base.hpp └── wl-listener-wrapper.tpp ├── test ├── geometry │ ├── geometry_test.cpp │ └── meson.build ├── meson.build ├── misc │ ├── meson.build │ ├── safe-list-test.cpp │ └── tracking-allocator.cpp └── txn │ ├── meson.build │ ├── transaction-manager-test.cpp │ ├── transaction-test-object.hpp │ └── transaction-test.cpp ├── uncrustify.ini ├── wayfire.desktop └── wayfire.ini /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 4 9 | 10 | [*.{build,xml,yaml}] 11 | indent_size = 2 12 | 13 | [metadata/**.xml] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Bad behavior (crash, something doesn't work, etc.) 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Enable plugin X 16 | 2. Do Y 17 | 3. Z happens 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots or stacktrace** 23 | If applicable, add screenshots to help explain your problem. 24 | If it is a crash, attach the backtrace (or the whole log file), Wayfire will print it in the end of the log file or stdout. 25 | Backtrace with address sanitizer enabled (if possible): 26 | 27 | **Wayfire version** 28 | 0.5.0, git, package, something else? 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please describe what you want Wayfire to do. 11 | 12 | If applicable, give an example: User does X, Y, Wayfire does Z 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/others.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Others 3 | about: Issues which are neither bugs nor feature requests 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/mandoc.yaml: -------------------------------------------------------------------------------- 1 | name: mandoc 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | pipeline: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Install dependencies 17 | run: | 18 | sudo apt update 19 | sudo apt-get install -y mandoc 20 | - name: Check man pages 21 | run: | 22 | mandoc -T lint -W warning man/wayfire.1.in 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/c++,meson,ninja,linux 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=c++,meson,ninja,linux 4 | 5 | ### C++ ### 6 | # Prerequisites 7 | *.d 8 | 9 | # Compiled Object files 10 | *.slo 11 | *.lo 12 | *.o 13 | *.obj 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Compiled Dynamic libraries 20 | *.so 21 | *.dylib 22 | *.dll 23 | 24 | # Fortran module files 25 | *.mod 26 | *.smod 27 | 28 | # Compiled Static libraries 29 | *.lai 30 | *.la 31 | *.a 32 | *.lib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | 39 | ### Linux ### 40 | *~ 41 | 42 | # temporary files which can be created if a process still has a handle open of a deleted file 43 | .fuse_hidden* 44 | 45 | # KDE directory preferences 46 | .directory 47 | 48 | # Linux trash folder which might appear on any partition or disk 49 | .Trash-* 50 | 51 | # .nfs files are created when an open file is removed but is still being accessed 52 | .nfs* 53 | 54 | ### Meson ### 55 | # subproject directories 56 | /subprojects/* 57 | !/subprojects/*.wrap 58 | 59 | ### Ninja ### 60 | .ninja_deps 61 | .ninja_log 62 | 63 | build/** 64 | 65 | # End of https://www.toptal.com/developers/gitignore/api/c++,meson,ninja,linux -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "subprojects/wf-config"] 2 | path = subprojects/wf-config 3 | url = https://github.com/WayfireWM/wf-config 4 | [submodule "subprojects/wlroots"] 5 | path = subprojects/wlroots 6 | url = https://gitlab.freedesktop.org/wlroots/wlroots.git 7 | [submodule "subprojects/wf-utils"] 8 | path = subprojects/wf-utils 9 | url = https://github.com/WayfireWM/wf-utils.git 10 | [submodule "subprojects/wf-touch"] 11 | path = subprojects/wf-touch 12 | url = https://github.com/WayfireWM/wf-touch 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Iliya Bozhinov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define INSTALL_PREFIX "@INSTALL_PREFIX@" 5 | #define PLUGIN_PATH "@PLUGIN_PATH@" 6 | #define PLUGIN_XML_DIR "@PLUGIN_XML_DIR@" 7 | #define SYSCONFDIR "@SYSCONFDIR@" 8 | #define WF_DEFAULT_CONFIG_BACKEND "@DEFAULT_CONFIG_BACKEND@" 9 | #mesondefine BUILD_WITH_IMAGEIO 10 | #mesondefine USE_GLES32 11 | #mesondefine WF_HAS_XWAYLAND 12 | 13 | 14 | #endif /* end of include guard: CONFIG_H */ 15 | -------------------------------------------------------------------------------- /man/meson.build: -------------------------------------------------------------------------------- 1 | configure_file(input: 'wayfire.1.in', 2 | output: 'wayfire.1', 3 | configuration: conf_data) 4 | 5 | install_man(join_paths(meson.project_build_root(), 'man', 'wayfire.1')) 6 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('enable_gles32', type: 'boolean', value: true, description: 'Enable usage of GLES 3.2') 2 | option('enable_openmp', type: 'boolean', value: true, description: 'Enable usage of OpenMP') 3 | option('use_system_wfconfig', type: 'feature', value: 'auto', description: 'Use the system-wide installation of wf-config') 4 | option('use_system_wlroots', type: 'feature', value: 'auto', description: 'Use the system-wide installation of wlroots') 5 | option('xwayland', type: 'feature', value: 'auto', description: 'Build with xwayland support. Requires wlroots also built with xwayland support') 6 | option('default_config_backend', type: 'string', value: 'default', description: 'Default configuration backend to use') 7 | option('print_trace', type: 'boolean', value: true, description: 'Print stack trace in debug logs (disables coredump)') 8 | option('tests', type: 'feature', value: 'auto', description: 'Enable unit tests') 9 | -------------------------------------------------------------------------------- /metadata/alpha.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Alpha 5 | <_long>A plugin to change the opacity of windows. 6 | Desktop 7 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /metadata/autostart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Autostart 5 | <_long>A plugin to run shell commands on startup. 6 | General 7 | 8 | <_short>Autostart 9 | <_long>Specifies the shell commands to run on startup. 10 | 17 | 18 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /metadata/command.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Command 5 | <_long>A plugin to bind key combo (key, button, touch) to execute shell commands. 6 | General 7 | 20 | 21 | 34 | 35 | 48 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /metadata/decoration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Decoration 5 | <_long>Default decorations around XWayland windows. 6 | Effects 7 | 12 | 17 | 22 | 27 | 28 | 33 | 38 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /metadata/expo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Expo 5 | <_long>A plugin to show an overview of all workspaces. 6 | Desktop 7 | 12 | 17 | 22 | 27 | 32 | 40 | 45 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /metadata/extra-gestures.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Extra Touchscreen Gestures 5 | <_long>A plugin which provides several touchscreen gestures. 6 | Desktop 7 | 14 | 21 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /metadata/fast-switcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Fast Switcher 5 | <_long>A plugin to switch active window. 6 | Window Management 7 | 12 | 17 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /metadata/fisheye.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Fisheye 5 | <_long>A plugin which provides fisheye effect. 6 | Effects 7 | 12 | 18 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /metadata/foreign-toplevel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Foreign Toplevel Protocol 5 | <_long>An implementation of the wlr-foreign-toplevel-management-v1 protocol. 6 | Utility 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/gtk-shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>GTK Shell Protocol 5 | <_long>An implementation of the gtk-shell protocol. 6 | Utility 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/idle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Idle 5 | <_long>A plugin for idle settings, such as the screensaver and DPMS. 6 | Desktop 7 | 8 | 13 | 14 | 19 | 20 | 25 | 26 | 31 | 32 | 37 | 38 | 43 | 49 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /metadata/input-device.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | General 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /metadata/input-method-v1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Input-Method-V1 Protocol 5 | <_long>An implementation of the input-method-v1 protocol. Needed for proper functioning of input methods like Fcitx5. 6 | Utility 7 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /metadata/invert.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Invert 5 | <_long>A plugin to invert the colors of the whole output. 6 | Accessibility 7 | 12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /metadata/ipc-rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Window Rules IPC Interface 5 | <_long>Interface to allow an external program to implement window rules (requires the IPC plugin). 6 | Window Management 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/ipc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>IPC protocol 5 | <_long>Allow external programs to interact with Wayfire plugins. 6 | Utility 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/oswitch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Output Switcher 5 | <_long>A plugin to change the focused output. 6 | Desktop 7 | 12 | 17 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /metadata/output.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | General 5 | 8 | 11 | 14 | 17 | 20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /metadata/place.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Place 5 | <_long>A plugin to position newly opened windows. 6 | Window Management 7 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /metadata/preserve-output.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Preserve Output 5 | <_long>A plugin to restore windows to their original position if outputs are temporarily disconnected. 6 | Window Management 7 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /metadata/resize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Resize 5 | <_long>A plugin to resize windows by dragging them from any part (not just the edges). 6 | Window Management 7 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /metadata/scale-title-filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Scale Title Filter 5 | <_long>Filter the views shown by scale by typing. 6 | Utility 7 | 12 | 17 | 22 | 28 | 33 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /metadata/session-lock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Session Lock Protocol 5 | <_long>An implementation of the ext-session-lock-v1 protocol. Provides more secure screen locking. 6 | Utility 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/shortcuts-inhibit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Keyboard Shortcuts Inhibit Protocol 5 | <_long>An implementation of the keyboard-shortcuts-inhibit-v1 protocol. 6 | Utility 7 | 8 | 13 | 14 | 19 | 20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /metadata/switcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Switcher 5 | <_long>A plugin to change active window with an animation. 6 | Window Management 7 | 8 | 13 | 18 | 19 | 24 | 29 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /metadata/vswipe.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Viewport Swipe 5 | <_long>A plugin to swipe workspaces in a grid. 6 | Desktop 7 | 12 | 17 | 22 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 62 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /metadata/wayfire-shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Wayfire Shell Protocol 5 | <_long>An implementation of the wayfire-shell protocol. 6 | Utility 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /metadata/window-rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Window Rules 5 | <_long>A plugin to apply specific commands to windows by using various criteria. 6 | Window Management 7 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /metadata/wm-actions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>WM Actions 5 | <_long>A plugin which provides various window management functionalities. 6 | Window Management 7 | 12 | 17 | 22 | 27 | 32 | 37 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /metadata/wobbly.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Wobbly 5 | <_long>A plugin to get wobbly windows. 6 | Effects 7 | 12 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /metadata/wrot.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Window Rotate 5 | <_long>A plugin to rotate windows with the mouse. 6 | Effects 7 | 12 | 17 | 23 | 28 | 33 | 38 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /metadata/wsets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Workspace Sets 5 | <_long>A plugin which allows manipulation of workspace sets. 6 | Desktop 7 | 12 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /metadata/xdg-activation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>XDG Activation Protocol 5 | <_long>An implementation of the xdg-activation-v1 protocol. 6 | Utility 7 | 8 | 9 | -------------------------------------------------------------------------------- /metadata/zoom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <_short>Zoom 5 | <_long>A plugin to zoom in the desktop with the mouse. 6 | Accessibility 7 | 12 | 18 | 23 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /plugins/animate/animate.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ANIMATE_H_ 2 | #define ANIMATE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define WF_ANIMATE_HIDING_ANIMATION (1 << 0) 9 | #define WF_ANIMATE_SHOWING_ANIMATION (1 << 1) 10 | #define WF_ANIMATE_MAP_STATE_ANIMATION (1 << 2) 11 | #define WF_ANIMATE_MINIMIZE_STATE_ANIMATION (1 << 3) 12 | 13 | namespace wf 14 | { 15 | namespace animate 16 | { 17 | enum animation_type 18 | { 19 | ANIMATION_TYPE_MAP = WF_ANIMATE_SHOWING_ANIMATION | WF_ANIMATE_MAP_STATE_ANIMATION, 20 | ANIMATION_TYPE_UNMAP = WF_ANIMATE_HIDING_ANIMATION | WF_ANIMATE_MAP_STATE_ANIMATION, 21 | ANIMATION_TYPE_MINIMIZE = WF_ANIMATE_HIDING_ANIMATION | WF_ANIMATE_MINIMIZE_STATE_ANIMATION, 22 | ANIMATION_TYPE_RESTORE = WF_ANIMATE_SHOWING_ANIMATION | WF_ANIMATE_MINIMIZE_STATE_ANIMATION, 23 | }; 24 | 25 | class animation_base_t 26 | { 27 | public: 28 | virtual void init(wayfire_view view, wf::animation_description_t duration, animation_type type) 29 | {} 30 | 31 | /** 32 | * @return True if the animation should continue for at least one more frame. 33 | */ 34 | virtual bool step() 35 | { 36 | return false; 37 | } 38 | 39 | /** 40 | * Reverse the animation direction (hiding -> showing, showing -> hiding) 41 | */ 42 | virtual void reverse() 43 | {} 44 | 45 | virtual ~animation_base_t() = default; 46 | }; 47 | 48 | struct effect_description_t 49 | { 50 | std::function()> generator; 51 | std::function()> default_duration; 52 | }; 53 | 54 | /** 55 | * The effects registry holds a list of all available animation effects. 56 | * Plugins can access the effects registry via ref_ptr_t helper in wayfire/plugins/common/shared-core-data.hpp 57 | * They may add/remove their own effects. 58 | */ 59 | class animate_effects_registry_t 60 | { 61 | public: 62 | void register_effect(std::string name, effect_description_t effect) 63 | { 64 | effects[name] = effect; 65 | } 66 | 67 | void unregister_effect(std::string name) 68 | { 69 | effects.erase(name); 70 | } 71 | 72 | std::map effects; 73 | }; 74 | } 75 | } 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /plugins/animate/fire/fire.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FIRE_ANIMATION_HPP 2 | #define FIRE_ANIMATION_HPP 3 | 4 | #include 5 | #include 6 | #include "../animate.hpp" 7 | 8 | class FireTransformer; 9 | class ParticleSystem; 10 | 11 | class FireAnimation : public wf::animate::animation_base_t 12 | { 13 | std::string name; // the name of the transformer in the view's table 14 | wayfire_view view; 15 | wf::animation::simple_animation_t progression; 16 | 17 | public: 18 | 19 | ~FireAnimation(); 20 | void init(wayfire_view view, wf::animation_description_t, wf::animate::animation_type type) override; 21 | bool step() override; /* return true if continue, false otherwise */ 22 | void reverse() override; /* reverse the animation */ 23 | }; 24 | 25 | #endif /* end of include guard: FIRE_ANIMATION_HPP */ 26 | -------------------------------------------------------------------------------- /plugins/animate/fire/shaders.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PARTICLE_ANIMATION_SHADER 2 | #define PARTICLE_ANIMATION_SHADER 3 | 4 | static const char *particle_vert_source = 5 | R"( 6 | #version 100 7 | 8 | attribute mediump float radius; 9 | attribute mediump vec2 position; 10 | attribute mediump vec2 center; 11 | attribute mediump vec4 color; 12 | 13 | uniform mat4 matrix; 14 | 15 | varying mediump vec2 uv; 16 | varying mediump vec4 out_color; 17 | varying mediump float R; 18 | 19 | void main() { 20 | uv = position * radius; 21 | gl_Position = matrix * vec4(center.x + uv.x * 0.75, center.y + uv.y, 0.0, 1.0); 22 | 23 | R = radius; 24 | out_color = color; 25 | } 26 | )"; 27 | 28 | static const char *particle_frag_source = 29 | R"( 30 | #version 100 31 | 32 | varying mediump vec2 uv; 33 | varying mediump vec4 out_color; 34 | varying mediump float R; 35 | 36 | uniform mediump float smoothing; 37 | 38 | void main() 39 | { 40 | mediump float len = length(uv); 41 | if (len >= R) 42 | { 43 | gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); 44 | } 45 | else { 46 | mediump float factor = 1.0 - len / R; 47 | factor = pow(factor, smoothing); 48 | gl_FragColor = factor * out_color; 49 | } 50 | } 51 | )"; 52 | 53 | #endif /* end of include guard: PARTICLE_ANIMATION_SHADER */ 54 | -------------------------------------------------------------------------------- /plugins/animate/meson.build: -------------------------------------------------------------------------------- 1 | dependencies = [wlroots, pixman, wfconfig] 2 | 3 | if get_option('enable_openmp') 4 | dependencies += [dependency('openmp')] 5 | endif 6 | 7 | animiate = shared_module('animate', 8 | ['animate.cpp', 9 | 'fire/particle.cpp', 10 | 'fire/fire.cpp'], 11 | include_directories: [wayfire_api_inc, wayfire_conf_inc], 12 | dependencies: dependencies, 13 | install: true, 14 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 15 | 16 | install_headers(['animate.hpp'], subdir: 'wayfire/plugins/animate') 17 | -------------------------------------------------------------------------------- /plugins/animate/shaders/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | 3 | in mediump vec4 out_color; 4 | in mediump vec2 pos; 5 | out mediump vec4 fragColor; 6 | 7 | layout(location = 4) uniform highp float radii; 8 | 9 | void main() 10 | { 11 | mediump float dist_center = sqrt(pos.x * pos.x + pos.y * pos.y); 12 | mediump float factor = (radii - dist_center) / radii; 13 | if (factor < 0.0) factor = 0.0; 14 | mediump float factor2 = factor * factor; 15 | 16 | fragColor = vec4(out_color.xyz, out_color.w * factor2); 17 | } 18 | -------------------------------------------------------------------------------- /plugins/animate/shaders/vertex.glsl: -------------------------------------------------------------------------------- 1 | #version 310 es 2 | 3 | layout(location = 0) in mediump vec2 position; 4 | layout(location = 1) in mediump vec2 center; 5 | layout(location = 2) in mediump vec4 color; 6 | layout(location = 3) uniform mediump vec2 global_offset; 7 | 8 | out mediump vec4 out_color; 9 | out mediump vec2 pos; 10 | 11 | void main() { 12 | gl_Position = vec4 (position + center + global_offset, 0.0, 1.0); 13 | out_color = color; 14 | pos = position; 15 | } 16 | -------------------------------------------------------------------------------- /plugins/animate/system_fade.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SYSTEM_FADE_HPP 2 | #define SYSTEM_FADE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* animates wake from suspend/startup by fading in the whole output */ 11 | class wf_system_fade 12 | { 13 | wf::animation::simple_animation_t progression; 14 | 15 | wf::output_t *output; 16 | 17 | wf::effect_hook_t damage_hook, render_hook; 18 | 19 | public: 20 | wf_system_fade(wf::output_t *out, wf::animation_description_t dur) : 21 | progression(wf::create_option(dur)), output(out) 22 | { 23 | damage_hook = [=] () 24 | { output->render->damage_whole(); }; 25 | 26 | render_hook = [=] () 27 | { render(); }; 28 | 29 | output->render->add_effect(&damage_hook, wf::OUTPUT_EFFECT_PRE); 30 | output->render->add_effect(&render_hook, wf::OUTPUT_EFFECT_OVERLAY); 31 | output->render->set_redraw_always(); 32 | this->progression.animate(1, 0); 33 | } 34 | 35 | void render() 36 | { 37 | wf::color_t color{0, 0, 0, this->progression}; 38 | auto fb = output->render->get_target_framebuffer(); 39 | auto geometry = output->get_relative_geometry(); 40 | 41 | OpenGL::render_begin(fb); 42 | OpenGL::render_rectangle(geometry, color, 43 | fb.get_orthographic_projection()); 44 | OpenGL::render_end(); 45 | 46 | if (!progression.running()) 47 | { 48 | finish(); 49 | } 50 | } 51 | 52 | void finish() 53 | { 54 | output->render->rem_effect(&damage_hook); 55 | output->render->rem_effect(&render_hook); 56 | output->render->set_redraw_always(false); 57 | 58 | delete this; 59 | } 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /plugins/animate/unmapped-view-node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/geometry.hpp" 4 | #include "wayfire/opengl.hpp" 5 | #include "wayfire/region.hpp" 6 | #include "wayfire/scene-render.hpp" 7 | #include "wayfire/scene.hpp" 8 | #include 9 | 10 | namespace wf 11 | { 12 | class unmapped_view_snapshot_node : public wf::scene::node_t 13 | { 14 | wf::render_target_t snapshot; 15 | wf::geometry_t bbox; 16 | 17 | public: 18 | unmapped_view_snapshot_node(wayfire_view view) : node_t(false) 19 | { 20 | view->take_snapshot(snapshot); 21 | bbox = view->get_surface_root_node()->get_bounding_box(); 22 | } 23 | 24 | ~unmapped_view_snapshot_node() 25 | { 26 | OpenGL::render_begin(); 27 | snapshot.release(); 28 | OpenGL::render_end(); 29 | } 30 | 31 | wf::geometry_t get_bounding_box() override 32 | { 33 | return bbox; 34 | } 35 | 36 | void gen_render_instances(std::vector& instances, 37 | scene::damage_callback push_damage, wf::output_t *shown_on) override 38 | { 39 | instances.push_back(std::make_unique(this, push_damage, shown_on)); 40 | } 41 | 42 | std::string stringify() const override 43 | { 44 | return "unmapped-view-snapshot-node " + this->stringify_flags(); 45 | } 46 | 47 | private: 48 | class rinstance_t : public wf::scene::simple_render_instance_t 49 | { 50 | public: 51 | using simple_render_instance_t::simple_render_instance_t; 52 | void render(const wf::render_target_t& target, const wf::region_t& region) 53 | { 54 | OpenGL::render_begin(target); 55 | for (auto& box : region) 56 | { 57 | target.logic_scissor(wlr_box_from_pixman_box(box)); 58 | OpenGL::render_texture(self->snapshot.tex, target, self->get_bounding_box()); 59 | } 60 | 61 | OpenGL::render_end(); 62 | } 63 | }; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /plugins/blur/meson.build: -------------------------------------------------------------------------------- 1 | blur_base = shared_library('wayfire-blur-base', 2 | ['blur-base.cpp', 'box.cpp', 'gaussian.cpp', 'kawase.cpp', 'bokeh.cpp'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc], 4 | dependencies: [wlroots, pixman, wfconfig], 5 | override_options: ['b_lundef=false'], 6 | install: true) 7 | install_headers(['blur.hpp'], subdir: 'wayfire/plugins/blur') 8 | 9 | blur = shared_module('blur', ['blur.cpp'], 10 | link_with: blur_base, 11 | include_directories: [wayfire_api_inc, wayfire_conf_inc], 12 | dependencies: [wlroots, pixman, wfconfig], 13 | install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) 14 | -------------------------------------------------------------------------------- /plugins/common/meson.build: -------------------------------------------------------------------------------- 1 | plugins_common_inc = include_directories('.') 2 | install_subdir('wayfire', install_dir: get_option('includedir')) 3 | -------------------------------------------------------------------------------- /plugins/common/wayfire/plugins/common/geometry-animation.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | using namespace wf::animation; 9 | class geometry_animation_t : public duration_t 10 | { 11 | public: 12 | using duration_t::duration_t; 13 | 14 | timed_transition_t x{*this}; 15 | timed_transition_t y{*this}; 16 | timed_transition_t width{*this}; 17 | timed_transition_t height{*this}; 18 | 19 | void set_start(wf::geometry_t geometry) 20 | { 21 | copy_fields(geometry, &timed_transition_t::start); 22 | } 23 | 24 | void set_end(wf::geometry_t geometry) 25 | { 26 | copy_fields(geometry, &timed_transition_t::end); 27 | } 28 | 29 | operator wf::geometry_t() const 30 | { 31 | return {(int)x, (int)y, (int)width, (int)height}; 32 | } 33 | 34 | protected: 35 | void copy_fields(wf::geometry_t geometry, double timed_transition_t::*member) 36 | { 37 | this->x.*member = geometry.x; 38 | this->y.*member = geometry.y; 39 | this->width.*member = geometry.width; 40 | this->height.*member = geometry.height; 41 | } 42 | }; 43 | 44 | /** Interpolate the geometry between a and b with alpha (in [0..1]), i.e a * 45 | * (1-alpha) + b * alpha */ 46 | static inline wf::geometry_t interpolate(wf::geometry_t a, wf::geometry_t b, 47 | double alpha) 48 | { 49 | const auto& interp = [=] (int32_t wf::geometry_t::*member) -> int32_t 50 | { 51 | return std::round((1 - alpha) * a.*member + alpha * b.*member); 52 | }; 53 | 54 | return { 55 | interp(&wf::geometry_t::x), 56 | interp(&wf::geometry_t::y), 57 | interp(&wf::geometry_t::width), 58 | interp(&wf::geometry_t::height) 59 | }; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /plugins/common/wayfire/plugins/common/key-repeat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | struct key_repeat_t 9 | { 10 | wf::option_wrapper_t delay{"input/kb_repeat_delay"}; 11 | wf::option_wrapper_t rate{"input/kb_repeat_rate"}; 12 | 13 | wf::wl_timer timer_delay; 14 | wf::wl_timer timer_rate; 15 | 16 | using callback_t = std::function; 17 | 18 | key_repeat_t() 19 | {} 20 | key_repeat_t(uint32_t key, callback_t handler) 21 | { 22 | set_callback(key, handler); 23 | } 24 | 25 | void set_callback(uint32_t key, callback_t handler) 26 | { 27 | disconnect(); 28 | timer_delay.set_timeout(delay, [=] () 29 | { 30 | timer_rate.set_timeout(1000 / rate, [=] () 31 | { 32 | // handle can determine if key should be repeated 33 | return handler(key); 34 | }); 35 | }); 36 | } 37 | 38 | void disconnect() 39 | { 40 | timer_delay.disconnect(); 41 | timer_rate.disconnect(); 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /plugins/common/wayfire/plugins/common/shared-core-data.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | /** 9 | * The purpose of shared is to allow multiple plugins or plugin instances to 10 | * have shared global custom data. 11 | * 12 | * While this is already possible if the shared data is stored as custom data on 13 | * `wf::get_core()`, the classes here provide convenient wrappers for managing 14 | * the lifetime of the shared data by utilizing RAII. 15 | */ 16 | namespace shared_data 17 | { 18 | namespace detail 19 | { 20 | /** Implementation detail: the actual data stored in core. */ 21 | template 22 | class shared_data_t : public wf::custom_data_t 23 | { 24 | public: 25 | T data; 26 | int32_t use_count = 0; 27 | }; 28 | } 29 | 30 | /** 31 | * A pointer to shared data which holds a reference to it (similar to 32 | * std::shared_ptr). Once the last reference is destroyed, data will be freed 33 | * from core. 34 | */ 35 | template 36 | class ref_ptr_t 37 | { 38 | public: 39 | ref_ptr_t() 40 | { 41 | update_use_count(+1); 42 | this->data = &wf::get_core().get_data_safe>()->data; 43 | } 44 | 45 | ref_ptr_t(const ref_ptr_t& other) 46 | { 47 | this->data = other.data; 48 | update_use_count(+1); 49 | } 50 | 51 | ref_ptr_t& operator =(const ref_ptr_t& other) 52 | { 53 | this->data = other.data; 54 | update_use_count(+1); 55 | } 56 | 57 | ref_ptr_t(ref_ptr_t&& other) = default; 58 | ref_ptr_t& operator =(ref_ptr_t&& other) = default; 59 | 60 | ~ref_ptr_t() 61 | { 62 | update_use_count(-1); 63 | } 64 | 65 | T *get() 66 | { 67 | return data; 68 | } 69 | 70 | T*operator ->() 71 | { 72 | return data; 73 | } 74 | 75 | private: 76 | // Update the use count, and delete data if necessary. 77 | void update_use_count(int32_t delta) 78 | { 79 | auto instance = wf::get_core().get_data_safe>(); 80 | instance->use_count += delta; 81 | if (instance->use_count <= 0) 82 | { 83 | wf::get_core().erase_data>(); 84 | } 85 | } 86 | 87 | // Pointer to the global data 88 | T *data; 89 | }; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /plugins/common/wayfire/plugins/common/simple-text-node.hpp: -------------------------------------------------------------------------------- 1 | #include "wayfire/opengl.hpp" 2 | #include "wayfire/output.hpp" 3 | #include "wayfire/scene.hpp" 4 | #include 5 | 6 | class simple_text_node_t : public wf::scene::node_t 7 | { 8 | class render_instance_t : public wf::scene::simple_render_instance_t 9 | { 10 | public: 11 | using simple_render_instance_t::simple_render_instance_t; 12 | 13 | void render(const wf::render_target_t& target, const wf::region_t& region) 14 | { 15 | OpenGL::render_begin(target); 16 | 17 | auto g = self->get_bounding_box(); 18 | for (auto box : region) 19 | { 20 | target.logic_scissor(wlr_box_from_pixman_box(box)); 21 | OpenGL::render_texture(self->cr_text.tex.tex, target, g, glm::vec4(1.0f), 22 | OpenGL::TEXTURE_TRANSFORM_INVERT_Y); 23 | } 24 | 25 | OpenGL::render_end(); 26 | } 27 | }; 28 | 29 | wf::cairo_text_t cr_text; 30 | 31 | public: 32 | simple_text_node_t() : node_t(false) 33 | {} 34 | 35 | void gen_render_instances(std::vector& instances, 36 | wf::scene::damage_callback push_damage, wf::output_t *output) override 37 | { 38 | instances.push_back(std::make_unique(this, push_damage, output)); 39 | } 40 | 41 | wf::geometry_t get_bounding_box() override 42 | { 43 | return wf::construct_box(position, size.value_or(cr_text.get_size())); 44 | } 45 | 46 | void set_position(wf::point_t position) 47 | { 48 | this->position = position; 49 | } 50 | 51 | void set_size(wf::dimensions_t size) 52 | { 53 | this->size = size; 54 | } 55 | 56 | void set_text_params(wf::cairo_text_t::params params) 57 | { 58 | this->params = params; 59 | } 60 | 61 | void set_text(std::string text) 62 | { 63 | wf::scene::damage_node(this->shared_from_this(), get_bounding_box()); 64 | cr_text.render_text(text, params); 65 | wf::scene::damage_node(this->shared_from_this(), get_bounding_box()); 66 | } 67 | 68 | private: 69 | wf::cairo_text_t::params params; 70 | std::optional size; 71 | wf::point_t position; 72 | }; 73 | -------------------------------------------------------------------------------- /plugins/common/wayfire/plugins/common/simple-texture.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace wf 5 | { 6 | struct simple_texture_t 7 | { 8 | GLuint tex = -1; 9 | int width = 0; 10 | int height = 0; 11 | 12 | /** 13 | * Destroy the GL texture. 14 | * This will call OpenGL::render_begin()/end() internally. 15 | */ 16 | void release() 17 | { 18 | if (this->tex == (GLuint) - 1) 19 | { 20 | return; 21 | } 22 | 23 | OpenGL::render_begin(); 24 | GL_CALL(glDeleteTextures(1, &tex)); 25 | OpenGL::render_end(); 26 | this->tex = -1; 27 | } 28 | 29 | simple_texture_t() = default; 30 | 31 | /** Auto-release the texture when the object is destroyed */ 32 | ~simple_texture_t() 33 | { 34 | release(); 35 | } 36 | 37 | simple_texture_t(const simple_texture_t &) = delete; 38 | simple_texture_t& operator =(const simple_texture_t&) = delete; 39 | 40 | simple_texture_t(simple_texture_t && o) noexcept : tex(o.tex), width(o.width), 41 | height(o.height) 42 | { 43 | o.tex = (GLuint) - 1; 44 | } 45 | 46 | simple_texture_t& operator =(simple_texture_t&& o) noexcept 47 | { 48 | if (&o == this) 49 | { 50 | return *this; 51 | } 52 | 53 | release(); 54 | 55 | tex = o.tex; 56 | width = o.width; 57 | height = o.height; 58 | o.tex = (GLuint) - 1; 59 | 60 | return *this; 61 | } 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /plugins/cube/cube-background.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_CUBE_BACKGROUND_HPP 2 | #define WF_CUBE_BACKGROUND_HPP 3 | 4 | #include 5 | #include "cube.hpp" 6 | 7 | class wf_cube_background_base 8 | { 9 | public: 10 | virtual void render_frame(const wf::render_target_t& fb, 11 | wf_cube_animation_attribs& attribs) = 0; 12 | virtual ~wf_cube_background_base() = default; 13 | }; 14 | 15 | #endif /* end of include guard: WF_CUBE_BACKGROUND_HPP */ 16 | -------------------------------------------------------------------------------- /plugins/cube/cube-control-signal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_CONTROL_SIGNAL 2 | #define CUBE_CONTROL_SIGNAL 3 | 4 | #include 5 | 6 | /* A private signal, currently shared by idle & cube 7 | * 8 | * It is used to rotate the cube from the idle plugin as a screensaver. 9 | */ 10 | 11 | /* Rotate cube to given angle and zoom level */ 12 | struct cube_control_signal 13 | { 14 | double angle; // cube rotation in radians 15 | double zoom; // 1.0 means 100%; increase value to zoom 16 | double ease; // for cube deformation; range 0.0-1.0 17 | bool last_frame; // ends cube animation if true 18 | bool carried_out; // false if cube is disabled 19 | }; 20 | 21 | #endif /* end of include guard: CUBE_CONTROL_SIGNAL */ 22 | -------------------------------------------------------------------------------- /plugins/cube/cube.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_CUBE_HPP 2 | #define WF_CUBE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define TEX_ERROR_FLAG_COLOR 0, 1, 0, 1 11 | 12 | using namespace wf::animation; 13 | 14 | class cube_animation_t : public duration_t 15 | { 16 | public: 17 | using duration_t::duration_t; 18 | timed_transition_t offset_y{*this}; 19 | timed_transition_t offset_z{*this}; 20 | timed_transition_t rotation{*this}; 21 | timed_transition_t zoom{*this}; 22 | timed_transition_t ease_deformation{*this}; 23 | }; 24 | 25 | struct wf_cube_animation_attribs 26 | { 27 | wf::option_wrapper_t animation_duration{"cube/initial_animation"}; 28 | cube_animation_t cube_animation{animation_duration}; 29 | 30 | glm::mat4 projection, view; 31 | float side_angle; 32 | 33 | bool in_exit; 34 | }; 35 | 36 | #endif /* end of include guard: WF_CUBE_HPP */ 37 | -------------------------------------------------------------------------------- /plugins/cube/cubemap-shaders.tpp: -------------------------------------------------------------------------------- 1 | static const char* cubemap_vertex = 2 | R"(#version 100 3 | 4 | attribute mediump vec3 position; 5 | varying highp vec3 direction; 6 | 7 | uniform mat4 cubeMapMatrix; 8 | 9 | void main() 10 | { 11 | gl_Position = cubeMapMatrix * vec4(position, 1.0); 12 | direction = position; 13 | })"; 14 | 15 | static const char* cubemap_fragment = 16 | R"(#version 100 17 | varying highp vec3 direction; 18 | uniform samplerCube smp; 19 | 20 | void main() 21 | { 22 | gl_FragColor = vec4(textureCube(smp, direction).xyz, 1); 23 | })"; 24 | -------------------------------------------------------------------------------- /plugins/cube/cubemap.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_CUBE_CUBEMAP_HPP 2 | #define WF_CUBE_CUBEMAP_HPP 3 | 4 | #include "cube-background.hpp" 5 | 6 | class wf_cube_background_cubemap : public wf_cube_background_base 7 | { 8 | public: 9 | wf_cube_background_cubemap(); 10 | virtual void render_frame(const wf::render_target_t& fb, 11 | wf_cube_animation_attribs& attribs) override; 12 | 13 | ~wf_cube_background_cubemap(); 14 | 15 | private: 16 | void reload_texture(); 17 | void create_program(); 18 | 19 | OpenGL::program_t program; 20 | GLuint tex = -1; 21 | GLuint vbo_cube_vertices; 22 | GLuint ibo_cube_indices; 23 | 24 | std::string last_background_image; 25 | wf::option_wrapper_t background_image{"cube/cubemap_image"}; 26 | }; 27 | 28 | #endif /* end of include guard: WF_CUBE_CUBEMAP_HPP */ 29 | -------------------------------------------------------------------------------- /plugins/cube/meson.build: -------------------------------------------------------------------------------- 1 | animiate = shared_module('cube', 2 | ['cube.cpp', 'cubemap.cpp', 'skydome.cpp', 'simple-background.cpp'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, ipc_include_dirs], 4 | dependencies: [wlroots, pixman, wfconfig, json], 5 | install: true, 6 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 7 | -------------------------------------------------------------------------------- /plugins/cube/shaders.tpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static const char* cube_vertex_2_0 = 4 | R"(#version 100 5 | attribute mediump vec3 position; 6 | attribute highp vec2 uvPosition; 7 | 8 | varying highp vec2 uvpos; 9 | 10 | uniform mat4 VP; 11 | uniform mat4 model; 12 | 13 | void main() { 14 | gl_Position = VP * model * vec4(position, 1.0); 15 | uvpos = uvPosition; 16 | })"; 17 | 18 | static const char* cube_fragment_2_0 = 19 | R"(#version 100 20 | varying highp vec2 uvpos; 21 | uniform sampler2D smp; 22 | 23 | void main() { 24 | gl_FragColor = vec4(texture2D(smp, uvpos).xyz, 1); 25 | })"; 26 | -------------------------------------------------------------------------------- /plugins/cube/simple-background.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "simple-background.hpp" 3 | 4 | wf_cube_simple_background::wf_cube_simple_background() 5 | {} 6 | 7 | void wf_cube_simple_background::render_frame(const wf::render_target_t& fb, 8 | wf_cube_animation_attribs&) 9 | { 10 | OpenGL::render_begin(fb); 11 | OpenGL::clear(background_color, GL_COLOR_BUFFER_BIT); 12 | OpenGL::render_end(); 13 | } 14 | -------------------------------------------------------------------------------- /plugins/cube/simple-background.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_CUBE_SIMPLE_BACKGROUND_HPP 2 | #define WF_CUBE_SIMPLE_BACKGROUND_HPP 3 | 4 | #include "cube-background.hpp" 5 | 6 | class wf_cube_simple_background : public wf_cube_background_base 7 | { 8 | wf::option_wrapper_t background_color{"cube/background"}; 9 | 10 | public: 11 | wf_cube_simple_background(); 12 | virtual void render_frame(const wf::render_target_t& fb, 13 | wf_cube_animation_attribs& attribs) override; 14 | }; 15 | 16 | #endif /* end of include guard: WF_CUBE_SIMPLE_BACKGROUND_HPP */ 17 | -------------------------------------------------------------------------------- /plugins/cube/skydome.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_CUBE_BACKGROUND_SKYDOME 2 | #define WF_CUBE_BACKGROUND_SKYDOME 3 | 4 | #include "cube-background.hpp" 5 | #include "wayfire/output.hpp" 6 | #include 7 | 8 | class wf_cube_background_skydome : public wf_cube_background_base 9 | { 10 | public: 11 | wf_cube_background_skydome(wf::output_t *output); 12 | virtual void render_frame(const wf::render_target_t& fb, 13 | wf_cube_animation_attribs& attribs) override; 14 | 15 | virtual ~wf_cube_background_skydome(); 16 | 17 | private: 18 | wf::output_t *output; 19 | 20 | void load_program(); 21 | void fill_vertices(); 22 | void reload_texture(); 23 | 24 | OpenGL::program_t program; 25 | GLuint tex = -1; 26 | 27 | std::vector vertices; 28 | std::vector coords; 29 | std::vector indices; 30 | 31 | std::string last_background_image; 32 | int last_mirror = -1; 33 | wf::option_wrapper_t background_image{"cube/skydome_texture"}; 34 | wf::option_wrapper_t mirror_opt{"cube/skydome_mirror"}; 35 | }; 36 | 37 | #endif /* end of include guard: WF_CUBE_BACKGROUND_SKYDOME */ 38 | -------------------------------------------------------------------------------- /plugins/decor/deco-subsurface.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DECO_SUBSURFACE_HPP 2 | #define DECO_SUBSURFACE_HPP 3 | 4 | #include "wayfire/object.hpp" 5 | #include "wayfire/toplevel.hpp" 6 | #include 7 | #include 8 | 9 | class simple_decoration_node_t; 10 | namespace wf 11 | { 12 | /** 13 | * A decorator object attached as custom data to a toplevel object. 14 | */ 15 | class simple_decorator_t : public wf::custom_data_t 16 | { 17 | wayfire_toplevel_view view; 18 | std::shared_ptr deco; 19 | 20 | wf::signal::connection_t on_view_activated; 21 | wf::signal::connection_t on_view_geometry_changed; 22 | wf::signal::connection_t on_view_fullscreen; 23 | 24 | public: 25 | simple_decorator_t(wayfire_toplevel_view view); 26 | ~simple_decorator_t(); 27 | wf::decoration_margins_t get_margins(const wf::toplevel_state_t& state); 28 | }; 29 | } 30 | 31 | #endif /* end of include guard: DECO_SUBSURFACE_HPP */ 32 | -------------------------------------------------------------------------------- /plugins/decor/meson.build: -------------------------------------------------------------------------------- 1 | decoration = shared_module('decoration', 2 | ['decoration.cpp', 'deco-subsurface.cpp', 'deco-button.cpp', 3 | 'deco-layout.cpp', 'deco-theme.cpp'], 4 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 5 | dependencies: [wlroots, pixman, wf_protos, wfconfig, cairo, pango, pangocairo], 6 | install: true, 7 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 8 | -------------------------------------------------------------------------------- /plugins/grid/meson.build: -------------------------------------------------------------------------------- 1 | grid_inc = include_directories('.') 2 | all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, wobbly_inc, grid_inc] 3 | all_deps = [wlroots, pixman, wfconfig, wftouch, cairo, json] 4 | 5 | shared_module('grid', ['grid.cpp'], 6 | include_directories: all_include_dirs, 7 | dependencies: all_deps, 8 | install: true, 9 | install_dir: conf_data.get('PLUGIN_PATH')) 10 | 11 | install_subdir('wayfire', install_dir: get_option('includedir')) 12 | -------------------------------------------------------------------------------- /plugins/grid/wayfire/plugins/grid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace wf 8 | { 9 | namespace grid 10 | { 11 | /** 12 | * name: request 13 | * on: core 14 | * when: Emitted before move renders a grid indicator and sets the slot. 15 | * carried_out: true if a plugin can handle move request to grid. 16 | */ 17 | struct grid_request_signal 18 | { 19 | /* True if a plugin handled this signal */ 20 | bool carried_out = false; 21 | }; 22 | 23 | /** 24 | * The slot where a view can be placed with grid. 25 | * BL = bottom-left, TR = top-right, etc. 26 | */ 27 | enum slot_t 28 | { 29 | SLOT_NONE = 0, 30 | SLOT_BL = 1, 31 | SLOT_BOTTOM = 2, 32 | SLOT_BR = 3, 33 | SLOT_LEFT = 4, 34 | SLOT_CENTER = 5, 35 | SLOT_RIGHT = 6, 36 | SLOT_TL = 7, 37 | SLOT_TOP = 8, 38 | SLOT_TR = 9, 39 | }; 40 | 41 | /* 42 | * 7 8 9 43 | * 4 5 6 44 | * 1 2 3 45 | */ 46 | inline uint32_t get_tiled_edges_for_slot(uint32_t slot) 47 | { 48 | if (slot == 0) 49 | { 50 | return 0; 51 | } 52 | 53 | uint32_t edges = wf::TILED_EDGES_ALL; 54 | if (slot % 3 == 0) 55 | { 56 | edges &= ~WLR_EDGE_LEFT; 57 | } 58 | 59 | if (slot % 3 == 1) 60 | { 61 | edges &= ~WLR_EDGE_RIGHT; 62 | } 63 | 64 | if (slot <= 3) 65 | { 66 | edges &= ~WLR_EDGE_TOP; 67 | } 68 | 69 | if (slot >= 7) 70 | { 71 | edges &= ~WLR_EDGE_BOTTOM; 72 | } 73 | 74 | return edges; 75 | } 76 | 77 | inline uint32_t get_slot_from_tiled_edges(uint32_t edges) 78 | { 79 | for (int slot = 0; slot <= 9; slot++) 80 | { 81 | if (get_tiled_edges_for_slot(slot) == edges) 82 | { 83 | return slot; 84 | } 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | /* 91 | * 7 8 9 92 | * 4 5 6 93 | * 1 2 3 94 | * */ 95 | inline wf::geometry_t get_slot_dimensions(wf::output_t *output, int n) 96 | { 97 | auto area = output->workarea->get_workarea(); 98 | int w2 = area.width / 2; 99 | int h2 = area.height / 2; 100 | 101 | if (n % 3 == 1) 102 | { 103 | area.width = w2; 104 | } 105 | 106 | if (n % 3 == 0) 107 | { 108 | area.width = w2, area.x += w2; 109 | } 110 | 111 | if (n >= 7) 112 | { 113 | area.height = h2; 114 | } else if (n <= 3) 115 | { 116 | area.height = h2, area.y += h2; 117 | } 118 | 119 | return area; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /plugins/ipc-rules/meson.build: -------------------------------------------------------------------------------- 1 | all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc] 2 | all_deps = [wlroots, pixman, wfconfig, wftouch, json] 3 | 4 | shared_module('ipc-rules', ['ipc-rules.cpp'], 5 | include_directories: all_include_dirs, 6 | dependencies: all_deps, 7 | install: true, 8 | install_dir: conf_data.get('PLUGIN_PATH')) 9 | 10 | install_headers(['ipc-rules-common.hpp'], subdir: 'wayfire/plugins/ipc') 11 | -------------------------------------------------------------------------------- /plugins/ipc/ipc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ipc-method-repository.hpp" 9 | 10 | namespace wf 11 | { 12 | namespace ipc 13 | { 14 | /** 15 | * Represents a single connected client to the IPC socket. 16 | */ 17 | class server_t; 18 | class client_t : public client_interface_t 19 | { 20 | public: 21 | client_t(server_t *server, int client_fd); 22 | ~client_t(); 23 | void send_json(nlohmann::json json) override; 24 | 25 | private: 26 | int fd; 27 | wl_event_source *source; 28 | server_t *ipc; 29 | 30 | int current_buffer_valid = 0; 31 | std::vector buffer; 32 | int read_up_to(int n, int *available); 33 | 34 | /** Handle incoming data on the socket */ 35 | std::function handle_fd_activity; 36 | void handle_fd_incoming(uint32_t); 37 | }; 38 | 39 | /** 40 | * The IPC server is a singleton object accessed via shared_data::ref_ptr_t. 41 | * It represents the IPC socket used for communication with clients. 42 | */ 43 | class server_t 44 | { 45 | public: 46 | server_t(); 47 | void init(std::string socket_path); 48 | ~server_t(); 49 | 50 | private: 51 | friend class client_t; 52 | wf::shared_data::ref_ptr_t method_repository; 53 | 54 | void handle_incoming_message(client_t *client, nlohmann::json message); 55 | 56 | void client_disappeared(client_t *client); 57 | 58 | int fd = -1; 59 | 60 | /** 61 | * Setup a socket at the given address, and set it as CLOEXEC and non-blocking. 62 | */ 63 | int setup_socket(const char *address); 64 | sockaddr_un saddr; 65 | wl_event_source *source; 66 | std::vector> clients; 67 | 68 | std::function accept_new_client; 69 | void do_accept_new_client(); 70 | }; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /plugins/ipc/meson.build: -------------------------------------------------------------------------------- 1 | evdev = dependency('libevdev') 2 | 3 | ipc_include_dirs = include_directories('.') 4 | 5 | ipc = shared_module('ipc', 6 | ['ipc.cpp'], 7 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 8 | dependencies: [wlroots, pixman, wfconfig, wftouch, json, evdev], 9 | install: true, 10 | install_dir: conf_data.get('PLUGIN_PATH')) 11 | 12 | stipc = shared_module('stipc', 13 | ['stipc.cpp'], 14 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 15 | dependencies: [wlroots, pixman, wfconfig, wftouch, json, evdev], 16 | install: true, 17 | install_dir: conf_data.get('PLUGIN_PATH')) 18 | 19 | demoipc = shared_module('demo-ipc', 20 | ['demo-ipc.cpp'], 21 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 22 | dependencies: [wlroots, pixman, wfconfig, wftouch, json, evdev], 23 | install: true, 24 | install_dir: conf_data.get('PLUGIN_PATH')) 25 | 26 | install_headers(['ipc-method-repository.hpp', 'ipc-helpers.hpp', 'ipc-activator.hpp'], subdir: 'wayfire/plugins/ipc') 27 | -------------------------------------------------------------------------------- /plugins/meson.build: -------------------------------------------------------------------------------- 1 | subdir('common') 2 | subdir('ipc') 3 | subdir('protocols') 4 | subdir('vswitch') 5 | subdir('wobbly') 6 | subdir('grid') 7 | subdir('decor') 8 | subdir('animate') 9 | subdir('cube') 10 | subdir('window-rules') 11 | subdir('blur') 12 | subdir('tile') 13 | subdir('wm-actions') 14 | subdir('scale') 15 | subdir('single_plugins') 16 | subdir('ipc-rules') 17 | -------------------------------------------------------------------------------- /plugins/protocols/gtk-shell.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /** 6 | * A signal to query the gtk_shell plugin about the gtk-shell-specific app_id of the given view. 7 | */ 8 | struct gtk_shell_app_id_query_signal 9 | { 10 | wayfire_view view; 11 | 12 | // Set by the gtk-shell plugin in response to the signal 13 | std::string app_id; 14 | }; 15 | -------------------------------------------------------------------------------- /plugins/protocols/input-method-v1.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace wf 5 | { 6 | /** 7 | * on: core 8 | * Emitted when a text input (v1 or v3) is activated. 9 | */ 10 | struct input_method_v1_activate_signal 11 | {}; 12 | 13 | /** 14 | * on: core 15 | * Emitted when a text input (v1 or v3) is deactivated. 16 | */ 17 | struct input_method_v1_deactivate_signal 18 | {}; 19 | } 20 | -------------------------------------------------------------------------------- /plugins/protocols/meson.build: -------------------------------------------------------------------------------- 1 | protocol_plugins = [ 2 | 'foreign-toplevel', 'gtk-shell', 'wayfire-shell', 'xdg-activation', 'shortcuts-inhibit', 3 | 'input-method-v1', 'session-lock' 4 | ] 5 | 6 | all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc] 7 | all_deps = [wlroots, pixman, wfconfig, wf_protos, json, cairo, pango, pangocairo] 8 | 9 | foreach plugin : protocol_plugins 10 | shared_module(plugin, plugin + '.cpp', 11 | include_directories: all_include_dirs, 12 | dependencies: all_deps, 13 | install: true, 14 | install_dir: conf_data.get('PLUGIN_PATH')) 15 | endforeach 16 | 17 | install_headers(['input-method-v1.hpp'], subdir: 'wayfire/plugins/input-method-v1/') 18 | -------------------------------------------------------------------------------- /plugins/protocols/xdg-activation.cpp: -------------------------------------------------------------------------------- 1 | #include "wayfire/core.hpp" 2 | #include "wayfire/signal-definitions.hpp" 3 | #include "wayfire/view.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "config.h" 11 | 12 | class wayfire_xdg_activation_protocol_impl : public wf::plugin_interface_t 13 | { 14 | public: 15 | void init() override 16 | { 17 | xdg_activation = wlr_xdg_activation_v1_create(wf::get_core().display); 18 | xdg_activation_request_activate.notify = xdg_activation_handle_request_activate; 19 | 20 | wl_signal_add(&xdg_activation->events.request_activate, &xdg_activation_request_activate); 21 | } 22 | 23 | void fini() override 24 | {} 25 | 26 | bool is_unloadable() override 27 | { 28 | return false; 29 | } 30 | 31 | private: 32 | static void xdg_activation_handle_request_activate(struct wl_listener *listener, void *data) 33 | { 34 | auto event = static_cast(data); 35 | 36 | wayfire_view view = wf::wl_surface_to_wayfire_view(event->surface->resource); 37 | if (!view) 38 | { 39 | LOGE("Could not get view"); 40 | return; 41 | } 42 | 43 | auto toplevel = wf::toplevel_cast(view); 44 | if (!toplevel) 45 | { 46 | LOGE("Could not get toplevel view"); 47 | return; 48 | } 49 | 50 | if (!event->token->seat) 51 | { 52 | LOGI("Denying focus request, seat wasn't supplied"); 53 | return; 54 | } 55 | 56 | LOGI("Activating view"); 57 | wf::get_core().default_wm->focus_request(toplevel); 58 | } 59 | 60 | struct wlr_xdg_activation_v1 *xdg_activation; 61 | struct wl_listener xdg_activation_request_activate; 62 | }; 63 | 64 | DECLARE_WAYFIRE_PLUGIN(wayfire_xdg_activation_protocol_impl); 65 | -------------------------------------------------------------------------------- /plugins/scale/meson.build: -------------------------------------------------------------------------------- 1 | all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, vswitch_inc, wobbly_inc, include_directories('.')] 2 | all_deps = [wlroots, pixman, wfconfig, wftouch, cairo, pango, pangocairo, json] 3 | 4 | shared_module('scale', ['scale.cpp', 'scale-title-overlay.cpp'], 5 | include_directories: all_include_dirs, 6 | dependencies: all_deps, 7 | install: true, 8 | install_dir: conf_data.get('PLUGIN_PATH')) 9 | 10 | shared_module('scale-title-filter', 'scale-title-filter.cpp', 11 | include_directories: all_include_dirs, 12 | dependencies: all_deps, 13 | install: true, 14 | install_dir: conf_data.get('PLUGIN_PATH')) 15 | 16 | install_headers(['wayfire/plugins/scale-signal.hpp'], subdir: 'wayfire/plugins') 17 | -------------------------------------------------------------------------------- /plugins/scale/scale-title-overlay.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/signal-definitions.hpp" 4 | #include "wayfire/signal-provider.hpp" 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace wf 12 | { 13 | namespace scene 14 | { 15 | class title_overlay_node_t; 16 | } 17 | } 18 | 19 | 20 | class scale_show_title_t 21 | { 22 | protected: 23 | /* Overlays for showing the title of each view */ 24 | wf::option_wrapper_t bg_color{"scale/bg_color"}; 25 | wf::option_wrapper_t text_color{"scale/text_color"}; 26 | wf::option_wrapper_t show_view_title_overlay_opt{ 27 | "scale/title_overlay"}; 28 | wf::option_wrapper_t title_font_size{"scale/title_font_size"}; 29 | wf::option_wrapper_t title_position{"scale/title_position"}; 30 | wf::output_t *output; 31 | 32 | public: 33 | scale_show_title_t(); 34 | 35 | void init(wf::output_t *output); 36 | 37 | void fini(); 38 | 39 | protected: 40 | /* signals */ 41 | wf::signal::connection_t view_filter; 42 | wf::signal::connection_t scale_end; 43 | wf::signal::connection_t add_title_overlay; 44 | wf::signal::connection_t rem_title_overlay; 45 | wf::signal::connection_t> post_motion; 46 | wf::signal::connection_t> 47 | post_absolute_motion; 48 | 49 | enum class title_overlay_t 50 | { 51 | NEVER, 52 | MOUSE, 53 | ALL, 54 | }; 55 | 56 | friend class wf::scene::title_overlay_node_t; 57 | 58 | title_overlay_t show_view_title_overlay; 59 | /* only used if title overlay is set to follow the mouse */ 60 | wayfire_view last_title_overlay = nullptr; 61 | 62 | void update_title_overlay_opt(); 63 | void update_title_overlay_mouse(); 64 | }; 65 | -------------------------------------------------------------------------------- /plugins/scale/scale.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/debug.hpp" 4 | #include "wayfire/toplevel-view.hpp" 5 | #include "wayfire/plugins/common/util.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | inline wayfire_toplevel_view scale_find_view_at(wf::pointf_t at, wf::output_t *output) 12 | { 13 | auto offset = wf::origin(output->get_layout_geometry()); 14 | at.x -= offset.x; 15 | at.y -= offset.y; 16 | return wf::find_output_view_at(output, at); 17 | } 18 | -------------------------------------------------------------------------------- /plugins/single_plugins/autostart.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class wayfire_autostart : public wf::plugin_interface_t 8 | { 9 | wf::option_wrapper_t autostart_wf_shell{"autostart/autostart_wf_shell"}; 10 | wf::option_wrapper_t> 11 | autostart_entries{"autostart/autostart"}; 12 | 13 | public: 14 | void init() override 15 | { 16 | /* Run only once, at startup */ 17 | auto section = wf::get_core().config.get_section("autostart"); 18 | 19 | bool panel_manually_started = false; 20 | bool background_manually_started = false; 21 | 22 | for (const auto& [name, command] : autostart_entries.value()) 23 | { 24 | // Because we accept any option names, we should ignore regular 25 | // options 26 | if (name == "autostart_wf_shell") 27 | { 28 | continue; 29 | } 30 | 31 | wf::get_core().run(command); 32 | if (command.find("wf-panel") != std::string::npos) 33 | { 34 | panel_manually_started = true; 35 | } 36 | 37 | if (command.find("wf-background") != std::string::npos) 38 | { 39 | background_manually_started = true; 40 | } 41 | } 42 | 43 | if (autostart_wf_shell && !panel_manually_started) 44 | { 45 | wf::get_core().run("wf-panel"); 46 | } 47 | 48 | if (autostart_wf_shell && !background_manually_started) 49 | { 50 | wf::get_core().run("wf-background"); 51 | } 52 | } 53 | 54 | bool is_unloadable() override 55 | { 56 | return false; 57 | } 58 | }; 59 | 60 | DECLARE_WAYFIRE_PLUGIN(wayfire_autostart); 61 | -------------------------------------------------------------------------------- /plugins/single_plugins/compositor-view-test.cpp: -------------------------------------------------------------------------------- 1 | #include "wayfire/compositor-view.hpp" 2 | #include "wayfire/render-manager.hpp" 3 | #include "wayfire/output.hpp" 4 | #include "wayfire/core.hpp" 5 | #include "wayfire/debug.hpp" 6 | 7 | extern "C" 8 | { 9 | #define static 10 | #include 11 | #include 12 | #include 13 | #undef static 14 | } 15 | 16 | class test_view : public wayfire_compositor_view_t, 17 | public wayfire_compositor_interactive_view 18 | { 19 | public: 20 | virtual void _wlr_render_box(const wf::framebuffer_t& fb, int x, int y, 21 | const wlr_box& scissor) 22 | { 23 | wlr_box g{x, y, geometry.width, geometry.height}; 24 | geometry = fb.damage_box_from_geometry_box(g); 25 | 26 | float projection[9]; 27 | wlr_matrix_projection(projection, fb.viewport_width, fb.viewport_height, 28 | (wl_output_transform)fb.wl_transform); 29 | 30 | float matrix[9]; 31 | wlr_matrix_project_box(matrix, &g, WL_OUTPUT_TRANSFORM_NORMAL, 0, 32 | projection); 33 | 34 | OpenGL::render_begin(fb); 35 | auto sbox = scissor; 36 | wlr_renderer_scissor(wf::get_core().renderer, &sbox); 37 | 38 | float color[] = {1.0f, 0.0, 1.0f, 1.0f}; 39 | 40 | wlr_render_quad_with_matrix(wf::get_core().renderer, color, matrix); 41 | OpenGL::render_end(); 42 | } 43 | 44 | virtual bool accepts_input(int sx, int sy) 45 | { 46 | return 0 <= sx && sx < geometry.width && 47 | 0 <= sy && sy < geometry.height; 48 | } 49 | }; 50 | 51 | class wayfire_cvtest : public wayfire_plugin_t 52 | { 53 | wf::key_callback binding; 54 | 55 | public: 56 | void init(wayfire_config *config) 57 | { 58 | binding = [=] (uint32_t) {test();}; 59 | output->add_key(new_static_option(" KEY_T"), &binding); 60 | } 61 | 62 | void test() 63 | { 64 | auto cv = new wayfire_mirror_view_t(output->get_top_view()); 65 | 66 | auto v = std::unique_ptr{cv}; 67 | wf::get_core().add_view(std::move(v)); 68 | cv->map(); 69 | } 70 | }; 71 | 72 | extern "C" 73 | { 74 | wayfire_plugin_t *newInstance() 75 | { 76 | return new wayfire_cvtest; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /plugins/single_plugins/meson.build: -------------------------------------------------------------------------------- 1 | plugins = [ 2 | 'move', 'resize', 'command', 'autostart', 'vswipe', 'wrot', 'expo', 3 | 'switcher', 'fast-switcher', 'oswitch', 'place', 'invert', 4 | 'fisheye', 'zoom', 'alpha', 'idle', 'extra-gestures', 'preserve-output', 5 | 'wsets', 'xkb-bindings' 6 | ] 7 | 8 | all_include_dirs = [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, vswitch_inc, wobbly_inc, grid_inc] 9 | all_deps = [wlroots, pixman, wfconfig, wftouch, cairo, pango, pangocairo, json] 10 | 11 | foreach plugin : plugins 12 | shared_module(plugin, plugin + '.cpp', 13 | include_directories: all_include_dirs, 14 | dependencies: all_deps, 15 | install: true, 16 | install_dir: conf_data.get('PLUGIN_PATH')) 17 | endforeach 18 | -------------------------------------------------------------------------------- /plugins/single_plugins/vswipe-processing.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static inline double vswipe_process_delta(const double delta, 5 | const double accumulated_dx, 6 | const int vx, const int vw, 7 | const double speed_cap = 0.5, 8 | const bool free_movement = false) 9 | { 10 | // The slowdown below must be applied differently for going out of bounds. 11 | double sdx_offset = free_movement ? 12 | std::copysign(0, accumulated_dx) : accumulated_dx; 13 | if (vx - accumulated_dx < 0.0) 14 | { 15 | sdx_offset = (accumulated_dx - std::floor(accumulated_dx)) + 1.0; 16 | } 17 | 18 | if (vx - accumulated_dx > vw - 1.0) 19 | { 20 | sdx_offset = (accumulated_dx - std::ceil(accumulated_dx)) - 1.0; 21 | } 22 | 23 | // To achieve a "rubberband" resistance effect when going too far, ease-in 24 | // of the whole swiped distance is used as a slowdown factor for the current 25 | // delta. 26 | const double ease = 1.0 - std::pow(std::abs(sdx_offset) - 0.025, 4.0); 27 | 28 | // If we're moving further in the limit direction, slow down all the way 29 | // to extremely slow, but reversing the direction should be easier. 30 | const double slowdown = wf::clamp(ease, 31 | std::signbit(delta) == std::signbit(sdx_offset) ? 0.005 : 0.2, 1.0); 32 | 33 | return wf::clamp(delta, -speed_cap, speed_cap) * slowdown; 34 | } 35 | 36 | static inline int vswipe_finish_target(const double accumulated_dx, 37 | const int vx, const int vw, 38 | const double last_deltas = 0, 39 | const double move_threshold = 0.35, 40 | const double fast_threshold = 24, 41 | const bool free_movement = false) 42 | { 43 | int target_dx = 0; 44 | if (accumulated_dx > 0) 45 | { 46 | target_dx = std::floor(accumulated_dx); 47 | if ((accumulated_dx - target_dx > move_threshold) || 48 | ((!free_movement || !target_dx) && (last_deltas > fast_threshold))) 49 | { 50 | ++target_dx; 51 | } 52 | 53 | if (vx - target_dx < 0) 54 | { 55 | target_dx = vx; 56 | } 57 | } else if (accumulated_dx < 0) 58 | { 59 | target_dx = std::ceil(accumulated_dx); 60 | if ((accumulated_dx - target_dx < -move_threshold) || 61 | ((!free_movement || !target_dx) && (last_deltas < -fast_threshold))) 62 | { 63 | --target_dx; 64 | } 65 | 66 | if (vx - target_dx > vw - 1) 67 | { 68 | target_dx = vx - vw + 1; 69 | } 70 | } 71 | 72 | if (!free_movement) 73 | { 74 | target_dx = wf::clamp(target_dx, -1, 1); 75 | } 76 | 77 | return target_dx; 78 | } 79 | -------------------------------------------------------------------------------- /plugins/tile/meson.build: -------------------------------------------------------------------------------- 1 | tile = shared_module('simple-tile', 2 | ['tile-plugin.cpp', 'tree.cpp', 'tree-controller.cpp'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, grid_inc, wobbly_inc, ipc_include_dirs], 4 | dependencies: [wlroots, pixman, wfconfig, json], 5 | install: true, 6 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 7 | 8 | 9 | -------------------------------------------------------------------------------- /plugins/vswitch/meson.build: -------------------------------------------------------------------------------- 1 | vswitch_inc = include_directories('.') 2 | 3 | vswitch = shared_module('vswitch', 4 | ['vswitch.cpp'], 5 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc, vswitch_inc, ipc_include_dirs], 6 | dependencies: [wlroots, pixman, wfconfig, json], 7 | install: true, 8 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 9 | 10 | install_headers(['wayfire/plugins/vswitch.hpp'], subdir: 'wayfire/plugins') 11 | -------------------------------------------------------------------------------- /plugins/window-rules/meson.build: -------------------------------------------------------------------------------- 1 | window_rules = shared_module('window-rules', 2 | ['window-rules.cpp', 'view-action-interface.cpp'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc, grid_inc, plugins_common_inc], 4 | dependencies: [wlroots, pixman, wfconfig, wfutils], 5 | install: true, 6 | install_dir: join_paths(get_option('libdir'), 'wayfire') 7 | ) 8 | -------------------------------------------------------------------------------- /plugins/window-rules/view-action-interface.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VIEW_ACTION_INTERFACE_HPP 2 | #define VIEW_ACTION_INTERFACE_HPP 3 | 4 | #include "wayfire/action/action_interface.hpp" 5 | #include "wayfire/view.hpp" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace wf 11 | { 12 | class view_action_interface_t : public action_interface_t 13 | { 14 | public: 15 | virtual ~view_action_interface_t() override; 16 | 17 | virtual bool execute(const std::string & name, 18 | const std::vector & args) override; 19 | 20 | void set_view(wayfire_view view); 21 | 22 | private: 23 | void _maximize(); 24 | void _unmaximize(); 25 | void _minimize(); 26 | void _unminimize(); 27 | void _make_sticky(); 28 | void _always_on_top(); 29 | 30 | std::tuple _expect_float(const std::vector & args, 31 | std::size_t position); 32 | std::tuple _expect_double(const std::vector & args, 33 | std::size_t position); 34 | std::tuple _expect_int(const std::vector & args, 35 | std::size_t position); 36 | 37 | std::tuple _validate_alpha(const std::vector & args); 38 | std::tuple _validate_geometry( 39 | const std::vector & args); 40 | std::tuple _validate_position( 41 | const std::vector & args); 42 | std::tuple _validate_size(const std::vector & args); 43 | 44 | std::tuple _validate_ws(const std::vector& args); 45 | 46 | void _set_alpha(float alpha); 47 | void _set_geometry(int x, int y, int w, int h); 48 | void _set_geometry_ppt(int x, int y, int w, int h); 49 | void _start_on_output(std::string output); 50 | void _move(int x, int y); 51 | void _resize(int w, int h); 52 | 53 | void _assign_ws(wf::point_t point); 54 | 55 | wf::geometry_t _get_workspace_grid_geometry(wf::output_t *output) const; 56 | 57 | wayfire_toplevel_view _view; 58 | wayfire_view _nontoplevel; 59 | }; 60 | } // End namespace wf. 61 | 62 | #endif // VIEW_ACTION_INTERFACE_HPP 63 | -------------------------------------------------------------------------------- /plugins/wm-actions/meson.build: -------------------------------------------------------------------------------- 1 | wm_actions = shared_module('wm-actions', 2 | ['wm-actions.cpp'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 4 | dependencies: [wlroots, pixman, wfconfig, json], 5 | install: true, 6 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 7 | 8 | install_headers( [ 'wm-actions-signals.hpp' ], subdir: 'wayfire/plugins' ) 9 | -------------------------------------------------------------------------------- /plugins/wm-actions/wm-actions-signals.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace wf 6 | { 7 | /** 8 | * on: output 9 | * when: Emitted whenever some entity requests that the view's above state 10 | * is supposed to change. 11 | * arguments: above: whether or not to set above state 12 | */ 13 | struct wm_actions_set_above_state_signal 14 | { 15 | wayfire_view view; 16 | 17 | /** The requested above state. If this is true, the view will be 18 | * added to the always-above layer. If it is false, the view will 19 | * be placed in the 'normal' workspace layer. */ 20 | bool above; 21 | }; 22 | 23 | /** 24 | * on: output 25 | * when: Emitted whenever a views above layer has been changed. 26 | */ 27 | struct wm_actions_above_changed_signal 28 | { 29 | wayfire_view view; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /plugins/wobbly/meson.build: -------------------------------------------------------------------------------- 1 | wobbly = shared_module('wobbly', 2 | ['wobbly.cpp', 'wobbly.c'], 3 | include_directories: [wayfire_api_inc, wayfire_conf_inc, plugins_common_inc], 4 | dependencies: [wlroots, pixman, wfconfig], 5 | install: true, 6 | install_dir: join_paths(get_option('libdir'), 'wayfire')) 7 | 8 | wobbly_inc = include_directories('.') 9 | install_headers(['wayfire/plugins/wobbly/wobbly-signal.hpp'], subdir: 'wayfire/plugins/wobbly') 10 | -------------------------------------------------------------------------------- /plugins/wobbly/wobbly.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * Copyright 2014 Scott Moreau 4 | * All Rights Reserved. 5 | * 6 | **************************************************************************/ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #define MINIMAL_FRICTION 0.1 13 | #define MAXIMAL_FRICTION 10.0 14 | #define MINIMAL_SPRING_K 0.1 15 | #define MAXIMAL_SPRING_K 10.0 16 | #define WOBBLY_MASS 15.0 17 | 18 | double wobbly_settings_get_friction(); 19 | double wobbly_settings_get_spring_k(); 20 | 21 | struct wobbly_surface 22 | { 23 | void *ww; 24 | int x, y, width, height; 25 | int x_cells, y_cells; 26 | int grabbed, synced; 27 | int vertex_count; 28 | 29 | GLfloat *v, *uv; 30 | }; 31 | 32 | struct wobbly_rect 33 | { 34 | float tlx, tly; 35 | float brx, bry; 36 | }; 37 | 38 | int wobbly_init(struct wobbly_surface *surface); 39 | void wobbly_fini(struct wobbly_surface *surface); 40 | void wobbly_set_top_anchor(struct wobbly_surface *surface, 41 | int x, int y, int w, int h); 42 | 43 | void wobbly_grab_notify(struct wobbly_surface *surface, int x, int y); 44 | void wobbly_slight_wobble(struct wobbly_surface *surface); 45 | void wobbly_ungrab_notify(struct wobbly_surface *surface); 46 | 47 | void wobbly_scale(struct wobbly_surface *surface, double dx, double dy); 48 | void wobbly_resize(struct wobbly_surface *surface, int width, int height); 49 | void wobbly_move_notify(struct wobbly_surface *surface, int x, int y); 50 | void wobbly_prepare_paint(struct wobbly_surface *surface, int msSinceLastPaint); 51 | void wobbly_done_paint(struct wobbly_surface *surface); 52 | void wobbly_add_geometry(struct wobbly_surface *surface); 53 | struct wobbly_rect wobbly_boundingbox(struct wobbly_surface *surface); 54 | 55 | void wobbly_force_geometry(struct wobbly_surface *surface, 56 | int x, int y, int w, int h); 57 | void wobbly_unenforce_geometry(struct wobbly_surface *surface); 58 | 59 | void wobbly_translate(struct wobbly_surface *surface, int dx, int dy); 60 | -------------------------------------------------------------------------------- /proto/meson.build: -------------------------------------------------------------------------------- 1 | wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir') 2 | 3 | wayland_scanner = find_program('wayland-scanner', native: true) 4 | 5 | wayland_scanner_server = generator( 6 | wayland_scanner, 7 | output: '@BASENAME@-protocol.h', 8 | arguments: ['server-header', '@INPUT@', '@OUTPUT@'], 9 | ) 10 | 11 | wayland_scanner_code = generator( 12 | wayland_scanner, 13 | output: '@BASENAME@-protocol.c', 14 | arguments: ['private-code', '@INPUT@', '@OUTPUT@'], 15 | ) 16 | 17 | wayland_scanner_client = generator( 18 | wayland_scanner, 19 | output: '@BASENAME@-client-protocol.h', 20 | arguments: ['client-header', '@INPUT@', '@OUTPUT@'], 21 | ) 22 | 23 | server_protocols = [ 24 | [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], 25 | [wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'], 26 | [wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], 27 | [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], 28 | [wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], 29 | [wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], 30 | [wl_protocol_dir, 'stable/tablet/tablet-v2.xml'], 31 | [wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'], 32 | [wl_protocol_dir, 'unstable/input-method/input-method-unstable-v1.xml'], 33 | [wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'], 34 | [wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'], 35 | 'wayfire-shell-unstable-v2.xml', 36 | 'gtk-shell.xml', 37 | 'wlr-layer-shell-unstable-v1.xml', 38 | 'wlr-output-power-management-unstable-v1.xml' 39 | ] 40 | 41 | wl_protos_src = [] 42 | wl_protos_headers = [] 43 | 44 | foreach p : server_protocols 45 | xml = join_paths(p) 46 | wl_protos_src += wayland_scanner_code.process(xml) 47 | wl_protos_headers += wayland_scanner_server.process(xml) 48 | endforeach 49 | 50 | lib_wl_protos = static_library('wl_protos', wl_protos_src + wl_protos_headers, 51 | dependencies: [wayland_client]) # for the include directory 52 | 53 | wf_protos = declare_dependency( 54 | link_with: lib_wl_protos, 55 | sources: wl_protos_headers, 56 | ) 57 | 58 | # Install wayfire-shell protocol, so that other projects can find it 59 | install_data('wayfire-shell-unstable-v2.xml', install_dir: join_paths(pkgdatadir, 'unstable')) 60 | -------------------------------------------------------------------------------- /src/api/wayfire/compositor-view.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COMPOSITOR_VIEW_HPP 2 | #define COMPOSITOR_VIEW_HPP 3 | 4 | #include "wayfire/geometry.hpp" 5 | #include "wayfire/view.hpp" 6 | #include 7 | 8 | namespace wf 9 | { 10 | /** 11 | * color_rect_view_t represents another common type of compositor view - a 12 | * view which is simply a colored rectangle with a border. 13 | */ 14 | class color_rect_view_t : public wf::view_interface_t 15 | { 16 | protected: 17 | wf::color_t _color; 18 | wf::color_t _border_color; 19 | int border; 20 | 21 | wf::geometry_t geometry; 22 | bool _is_mapped; 23 | class color_rect_node_t; 24 | 25 | /** 26 | * Create a colored rect view. The map signal is not fired by default. 27 | * The creator of the colored view should also add it to the desired layer. 28 | */ 29 | color_rect_view_t(); 30 | friend class wf::tracking_allocator_t; 31 | 32 | public: 33 | /** 34 | * Create and initialize a new color rect view. 35 | * The view will be automatically mapped, and if specified, put on the given output and layer. 36 | */ 37 | static std::shared_ptr create(view_role_t role, 38 | wf::output_t *start_output = nullptr, std::optional layer = {}); 39 | 40 | /** 41 | * Emit the unmap signal and then drop the internal reference. 42 | */ 43 | virtual void close() override; 44 | 45 | /** Set the view color. Color's alpha is not premultiplied */ 46 | virtual void set_color(wf::color_t color); 47 | /** Set the view border color. Color's alpha is not premultiplied */ 48 | virtual void set_border_color(wf::color_t border); 49 | /** Set the border width. */ 50 | virtual void set_border(int width); 51 | 52 | /** Get the view color. Color's alpha is not premultiplied */ 53 | wf::color_t get_color() 54 | { 55 | return _color; 56 | } 57 | 58 | /** Get the view border color. Color's alpha is not premultiplied */ 59 | wf::color_t get_border_color() 60 | { 61 | return _border_color; 62 | } 63 | 64 | /** Get the border width. */ 65 | int get_border() 66 | { 67 | return border; 68 | } 69 | 70 | /** Set the view geometry. */ 71 | virtual void set_geometry(wf::geometry_t geometry); 72 | virtual wf::geometry_t get_geometry(); 73 | 74 | /* required for view_interface_t */ 75 | virtual bool is_mapped() const override; 76 | 77 | virtual wlr_surface *get_keyboard_focus_surface() override; 78 | virtual bool is_focusable() const override; 79 | }; 80 | } 81 | 82 | #endif /* end of include guard: COMPOSITOR_VIEW_HPP */ 83 | -------------------------------------------------------------------------------- /src/api/wayfire/config-backend.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace wf 8 | { 9 | /** 10 | * A base class for configuration backend plugins. 11 | * 12 | * A configuration backend plugin is loaded immediately after creating a 13 | * wayland display and initializing the logging infrastructure. Because of 14 | * this, the configuration backend plugins are not allowed to use any 15 | * Wayfire APIs, but can use wf-config. 16 | * 17 | * The job of a configuration backend plugin is to populate and update the 18 | * configuration options used in the rest of the code. 19 | */ 20 | class config_backend_t 21 | { 22 | public: 23 | /** 24 | * Initialize the config backend and do the initial loading of config options. 25 | * The config backend must follow the same option types as described in the XML 26 | * files. 27 | * 28 | * @param display The wayland display used by Wayfire. 29 | * @param config A reference to the config manager which needs to be 30 | * populated. 31 | * @param cmd_config_file The configuration file specified on the command line. 32 | */ 33 | virtual void init(wl_display *display, config::config_manager_t& config, 34 | const std::string& cmd_config_file) = 0; 35 | 36 | /** 37 | * Find the output section for a given output. 38 | * 39 | * The returned section must be a valid output object as 40 | * described in output.xml 41 | */ 42 | virtual std::shared_ptr get_output_section( 43 | wlr_output *output); 44 | 45 | /** 46 | * Find the output section for a given input device. 47 | * 48 | * The returned section must be a valid output object as 49 | * described in input-device.xml 50 | */ 51 | virtual std::shared_ptr get_input_device_section( 52 | wlr_input_device *device); 53 | 54 | virtual ~config_backend_t() = default; 55 | 56 | protected: 57 | /** A helper to read the XML directories that Wayfire looks at */ 58 | virtual std::vector get_xml_dirs() const; 59 | }; 60 | } 61 | 62 | /** 63 | * A macro to declare the necessary functions, given the backend class name. 64 | */ 65 | #define DECLARE_WAYFIRE_CONFIG_BACKEND(PluginClass) \ 66 | extern "C" \ 67 | { \ 68 | wf::config_backend_t*newInstance() { return new PluginClass; } \ 69 | uint32_t getWayfireVersion() { return WAYFIRE_API_ABI_VERSION; } \ 70 | } 71 | -------------------------------------------------------------------------------- /src/api/wayfire/dassert.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | /** 9 | * Print the current stacktrace at runtime. 10 | * 11 | * @param fast_mode If fast_mode is true, the stacktrace will be generated 12 | * using the fastest possible method. However, this means that not all 13 | * information will be printed (for ex., line numbers may be missing). 14 | */ 15 | void print_trace(bool fast_mode); 16 | 17 | /** 18 | * Assert that the condition is true. 19 | * Optionally print a message. 20 | * Print backtrace when the assertion fails and exit. 21 | */ 22 | inline void dassert(bool condition, std::string message = "") 23 | { 24 | if (!condition) 25 | { 26 | LOGE(message); 27 | print_trace(false); 28 | std::exit(0); 29 | } 30 | } 31 | } 32 | 33 | #define DASSERT(condition) \ 34 | wf::dassert(condition, "Assertion failed at " __FILE__ ":" __LINE__) 35 | -------------------------------------------------------------------------------- /src/api/wayfire/idle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace wf 4 | { 5 | /** 6 | * Dummy non-copyable type that increments the global inhibitor count when created, 7 | * and decrements when destroyed. These changes influence wlroots idle enablement. 8 | */ 9 | class idle_inhibitor_t 10 | { 11 | public: 12 | idle_inhibitor_t(); 13 | ~idle_inhibitor_t(); 14 | 15 | idle_inhibitor_t(const idle_inhibitor_t &) = delete; 16 | idle_inhibitor_t(idle_inhibitor_t &&) = delete; 17 | idle_inhibitor_t& operator =(const idle_inhibitor_t&) = delete; 18 | idle_inhibitor_t& operator =(idle_inhibitor_t&&) = delete; 19 | 20 | private: 21 | static unsigned int inhibitors; 22 | void notify_update(); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/api/wayfire/img.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IMG_HPP_ 2 | #define IMG_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace image_io 8 | { 9 | /* Load the image from the given file, binding it to the given GL texture target 10 | * Bind the texture before you call this function 11 | * Guaranteed: doesn't change any GL state except pixel packing */ 12 | bool load_from_file(std::string name, GLuint target); 13 | 14 | /* Function that saves the given pixels(in rgba format) to a (currently) png file */ 15 | void write_to_file(std::string name, uint8_t *pixels, int w, int h, 16 | std::string type, bool invert = false); 17 | 18 | void write_to_file(std::string name, wf::framebuffer_t buffer); 19 | 20 | /* Initializes all backends, called at startup */ 21 | void init(); 22 | } 23 | 24 | #endif /* end of include guard: IMG_HPP_ */ 25 | -------------------------------------------------------------------------------- /src/api/wayfire/input-device.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_INPUT_DEVICE_HPP 2 | #define WF_INPUT_DEVICE_HPP 3 | 4 | #include 5 | 6 | namespace wf 7 | { 8 | class input_device_t 9 | { 10 | public: 11 | /** 12 | * General comment 13 | * @return The represented wlr_input_device 14 | */ 15 | wlr_input_device *get_wlr_handle(); 16 | 17 | /** 18 | * @param enabled Whether the compositor should handle input events from 19 | * the device 20 | * @return true if the device state was successfully changed 21 | */ 22 | bool set_enabled(bool enabled = true); 23 | 24 | /** 25 | * @return true if the compositor should receive events from the device 26 | */ 27 | bool is_enabled(); 28 | virtual ~input_device_t() = default; 29 | 30 | protected: 31 | wlr_input_device *handle; 32 | input_device_t(wlr_input_device *handle); 33 | }; 34 | } 35 | 36 | #endif /* end of include guard: WF_INPUT_DEVICE_HPP */ 37 | -------------------------------------------------------------------------------- /src/api/wayfire/matcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | /** 9 | * view_matcher_t provides a way to match certain views based on conditions. 10 | * The conditions are represented as string options. 11 | * 12 | * For information about the syntax or the possible conditions, see 13 | * wf::view_condition_interface_t and wf::condition_parser_t. 14 | */ 15 | class view_matcher_t 16 | { 17 | public: 18 | /** 19 | * Create a new matcher from the given option. 20 | * 21 | * Whenever the option value changes, the condition will be updated. 22 | * 23 | * @param option The option where the condition is encoded. 24 | */ 25 | view_matcher_t(std::shared_ptr> option); 26 | 27 | /** 28 | * Create a new matcher from the given option name. 29 | * The option will be loaded from core. 30 | * 31 | * @throws a std::runtime_error if the option is not found, or if the option 32 | * is not a string. 33 | */ 34 | view_matcher_t(const std::string& option_name); 35 | 36 | view_matcher_t(const view_matcher_t &) = delete; 37 | view_matcher_t(view_matcher_t &&) = default; 38 | view_matcher_t& operator =(const view_matcher_t&) = delete; 39 | view_matcher_t& operator =(view_matcher_t&&) = default; 40 | 41 | /** 42 | * Set the condition option after initialization. 43 | */ 44 | void set_from_option(std::shared_ptr> option); 45 | 46 | /** 47 | * @return True if the view matches the condition specified, false otherwise. 48 | */ 49 | bool matches(wayfire_view view); 50 | 51 | /** Destructor */ 52 | ~view_matcher_t(); 53 | 54 | private: 55 | view_matcher_t(); 56 | 57 | class impl; 58 | std::unique_ptr priv; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /src/api/wayfire/nonstd/reverse.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_REVERSE_HPP 2 | #define WF_REVERSE_HPP 3 | 4 | #include 5 | 6 | /* from https://stackoverflow.com/questions/8542591/c11-reverse-range-based-for-loop 7 | * */ 8 | namespace wf 9 | { 10 | template 11 | struct reversion_wrapper 12 | { 13 | T& iterable; 14 | }; 15 | 16 | template 17 | auto begin(reversion_wrapper w) 18 | { 19 | return std::rbegin(w.iterable); 20 | } 21 | 22 | template 23 | auto end(reversion_wrapper w) 24 | { 25 | return std::rend(w.iterable); 26 | } 27 | 28 | template 29 | reversion_wrapper reverse(T&& iterable) 30 | { 31 | return {iterable}; 32 | } 33 | } 34 | 35 | #endif /* end of include guard: WF_REVERSE_HPP */ 36 | -------------------------------------------------------------------------------- /src/api/wayfire/nonstd/tracking-allocator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace wf 9 | { 10 | /** 11 | * The destruct signal is emitted directly before an object is freed. 12 | * Emitted on objects managed with the tracking allocator which support signals. 13 | */ 14 | template 15 | struct destruct_signal 16 | { 17 | T *object; 18 | }; 19 | 20 | /** 21 | * The tracking allocator is a factory singleton for allocating objects of a certain type. 22 | * The objects are allocated via shared pointers, and the tracking allocator keeps a list of all allocated 23 | * objects, accessible by plugins. 24 | */ 25 | template 26 | class tracking_allocator_t 27 | { 28 | public: 29 | /** 30 | * Get the single global instance of the tracking allocator. 31 | */ 32 | static tracking_allocator_t& get() 33 | { 34 | static tracking_allocator_t allocator; 35 | return allocator; 36 | } 37 | 38 | template 39 | std::shared_ptr allocate(Args... args) 40 | { 41 | static_assert(std::is_base_of_v); 42 | auto ptr = std::shared_ptr( 43 | new ConcreteObjectType(std::forward(args)...), 44 | std::bind(&tracking_allocator_t::deallocate_object, this, std::placeholders::_1)); 45 | 46 | allocated_objects.push_back(ptr.get()); 47 | return ptr; 48 | } 49 | 50 | const std::vector>& get_all() 51 | { 52 | return allocated_objects; 53 | } 54 | 55 | private: 56 | std::vector> allocated_objects; 57 | void deallocate_object(ObjectType *obj) 58 | { 59 | if constexpr (std::is_base_of_v) 60 | { 61 | destruct_signal event; 62 | event.object = obj; 63 | obj->emit(&event); 64 | } 65 | 66 | auto it = std::find(allocated_objects.begin(), allocated_objects.end(), 67 | nonstd::observer_ptr{obj}); 68 | wf::dassert(it != allocated_objects.end(), "Object is not allocated?"); 69 | allocated_objects.erase(it); 70 | delete obj; 71 | } 72 | }; 73 | } 74 | -------------------------------------------------------------------------------- /src/api/wayfire/nonstd/wlroots.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef WLR_USE_UNSTABLE 4 | #define WLR_USE_UNSTABLE 5 | #endif 6 | 7 | /** 8 | * This file is used to put all wlroots headers needed in the Wayfire API 9 | * in an extern "C" block because wlroots headers are not always compatible 10 | * with C++. 11 | */ 12 | extern "C" 13 | { 14 | struct wlr_backend; 15 | struct wlr_renderer; 16 | struct wlr_seat; 17 | struct wlr_cursor; 18 | struct wlr_data_device_manager; 19 | struct wlr_data_control_manager_v1; 20 | struct wlr_gamma_control_manager_v1; 21 | struct wlr_xdg_output_manager_v1; 22 | struct wlr_export_dmabuf_manager_v1; 23 | struct wlr_server_decoration_manager; 24 | struct wlr_input_inhibit_manager; 25 | struct wlr_idle_inhibit_manager_v1; 26 | struct wlr_xdg_decoration_manager_v1; 27 | struct wlr_virtual_keyboard_manager_v1; 28 | struct wlr_virtual_pointer_manager_v1; 29 | struct wlr_idle_notifier_v1; 30 | struct wlr_screencopy_manager_v1; 31 | struct wlr_foreign_toplevel_manager_v1; 32 | struct wlr_pointer_gestures_v1; 33 | struct wlr_relative_pointer_manager_v1; 34 | struct wlr_pointer_constraints_v1; 35 | struct wlr_tablet_manager_v2; 36 | struct wlr_input_method_manager_v2; 37 | struct wlr_text_input_manager_v3; 38 | struct wlr_presentation; 39 | struct wlr_primary_selection_v1_device_manager; 40 | struct wlr_drm_lease_v1_manager; 41 | struct wlr_session_lock_manager_v1; 42 | 43 | struct wlr_xdg_foreign_v1; 44 | struct wlr_xdg_foreign_v2; 45 | struct wlr_xdg_foreign_registry; 46 | 47 | struct wlr_pointer_axis_event; 48 | struct wlr_pointer_motion_event; 49 | struct wlr_output_layout; 50 | struct wlr_surface; 51 | struct wlr_texture; 52 | struct wlr_viewporter; 53 | 54 | #include 55 | #include 56 | #include 57 | #include 58 | #define static 59 | #include 60 | #undef static 61 | #include 62 | #include 63 | #include 64 | #include 65 | 66 | static constexpr uint32_t WLR_KEY_PRESSED = WL_KEYBOARD_KEY_STATE_PRESSED; 67 | static constexpr uint32_t WLR_KEY_RELEASED = WL_KEYBOARD_KEY_STATE_RELEASED; 68 | 69 | struct mwlr_keyboard_modifiers_event 70 | { 71 | uint32_t time_msec; 72 | }; 73 | } 74 | -------------------------------------------------------------------------------- /src/api/wayfire/option-wrapper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace wf 8 | { 9 | namespace detail 10 | { 11 | // Forward declaration to avoid adding unnecessary includes. 12 | [[noreturn]] 13 | void option_wrapper_debug_message(const std::string& option_name, const std::runtime_error& err); 14 | [[noreturn]] 15 | void option_wrapper_debug_message(const std::string& option_name, const std::logic_error& err); 16 | } 17 | 18 | /** 19 | * A simple wrapper around a config option. 20 | */ 21 | template 22 | class option_wrapper_t : public base_option_wrapper_t 23 | { 24 | public: 25 | /** 26 | * Initialize the option wrapper and directly load the given option. 27 | */ 28 | option_wrapper_t(const std::string& option_name) : 29 | wf::base_option_wrapper_t() 30 | { 31 | this->load_option(option_name); 32 | } 33 | 34 | void load_option(const std::string& option_name) 35 | { 36 | try { 37 | base_option_wrapper_t::load_option(option_name); 38 | } catch (const std::runtime_error& err) 39 | { 40 | detail::option_wrapper_debug_message(option_name, err); 41 | } catch (const std::logic_error& err) 42 | { 43 | detail::option_wrapper_debug_message(option_name, err); 44 | } 45 | } 46 | 47 | option_wrapper_t() : wf::base_option_wrapper_t() 48 | {} 49 | 50 | protected: 51 | std::shared_ptr load_raw_option(const std::string& name) 52 | { 53 | return wf::get_core().config.get_option(name); 54 | } 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/api/wayfire/region.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "wayfire/geometry.hpp" 5 | 6 | /* ---------------------- pixman utility functions -------------------------- */ 7 | namespace wf 8 | { 9 | struct region_t 10 | { 11 | region_t(); 12 | /* Makes a copy of the given region */ 13 | region_t(pixman_region32_t *damage); 14 | region_t(const wlr_box& box); 15 | ~region_t(); 16 | 17 | region_t(const region_t& other); 18 | region_t(region_t&& other); 19 | 20 | region_t& operator =(const region_t& other); 21 | region_t& operator =(region_t&& other); 22 | 23 | bool empty() const; 24 | void clear(); 25 | 26 | void expand_edges(int amount); 27 | pixman_box32_t get_extents() const; 28 | bool contains_point(const point_t& point) const; 29 | bool contains_pointf(const pointf_t& point) const; 30 | 31 | /* Translate the region */ 32 | region_t operator +(const point_t& vector) const; 33 | region_t& operator +=(const point_t& vector); 34 | 35 | region_t operator -(const point_t& vector) const; 36 | region_t& operator -=(const point_t& vector); 37 | 38 | region_t operator *(float scale) const; 39 | region_t& operator *=(float scale); 40 | 41 | /* Region intersection */ 42 | region_t operator &(const wlr_box& box) const; 43 | region_t operator &(const region_t& other) const; 44 | region_t& operator &=(const wlr_box& box); 45 | region_t& operator &=(const region_t& other); 46 | 47 | /* Region union */ 48 | region_t operator |(const wlr_box& other) const; 49 | region_t operator |(const region_t& other) const; 50 | region_t& operator |=(const wlr_box& other); 51 | region_t& operator |=(const region_t& other); 52 | 53 | /* Subtract the box/region from the current region */ 54 | region_t operator ^(const wlr_box& box) const; 55 | region_t operator ^(const region_t& other) const; 56 | region_t& operator ^=(const wlr_box& box); 57 | region_t& operator ^=(const region_t& other); 58 | 59 | pixman_region32_t *to_pixman(); 60 | 61 | const pixman_box32_t *begin() const; 62 | const pixman_box32_t *end() const; 63 | 64 | private: 65 | pixman_region32_t _region; 66 | /* Returns a const-casted pixman_region32_t*, useful in const operators 67 | * where we use this->_region as only source for calculations, but pixman 68 | * won't let us pass a const pixman_region32_t* */ 69 | pixman_region32_t *unconst() const; 70 | }; 71 | } 72 | 73 | wlr_box wlr_box_from_pixman_box(const pixman_box32_t& box); 74 | pixman_box32_t pixman_box_from_wlr_box(const wlr_box& box); 75 | -------------------------------------------------------------------------------- /src/api/wayfire/scene-operations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/scene-input.hpp" 4 | #include 5 | #include 6 | 7 | // This header contains implementations of simple scenegraph related functionality 8 | // used in many places throughout the codebase. 9 | 10 | namespace wf 11 | { 12 | namespace scene 13 | { 14 | /** 15 | * Remove a child node from a parent node and update the parent. 16 | */ 17 | inline void remove_child(node_ptr child, uint32_t add_flags = 0) 18 | { 19 | if (!child->parent()) 20 | { 21 | return; 22 | } 23 | 24 | auto parent = dynamic_cast(child->parent()); 25 | wf::dassert(parent, "Removing a child from a non-floating container!"); 26 | 27 | auto children = parent->get_children(); 28 | children.erase(std::remove(children.begin(), children.end(), child), 29 | children.end()); 30 | parent->set_children_list(children); 31 | update(parent->shared_from_this(), update_flag::CHILDREN_LIST | add_flags); 32 | } 33 | 34 | inline void add_front(floating_inner_ptr parent, node_ptr child) 35 | { 36 | auto children = parent->get_children(); 37 | children.insert(children.begin(), child); 38 | parent->set_children_list(children); 39 | update(parent, update_flag::CHILDREN_LIST); 40 | } 41 | 42 | inline void readd_front(floating_inner_ptr parent, node_ptr child) 43 | { 44 | remove_child(child); 45 | add_front(parent, child); 46 | } 47 | 48 | inline void add_back(floating_inner_ptr parent, node_ptr child) 49 | { 50 | auto children = parent->get_children(); 51 | children.push_back(child); 52 | parent->set_children_list(children); 53 | update(parent, update_flag::CHILDREN_LIST); 54 | } 55 | 56 | inline void readd_back(floating_inner_ptr parent, node_ptr child) 57 | { 58 | remove_child(child); 59 | add_back(parent, child); 60 | } 61 | 62 | inline bool raise_to_front(node_ptr child) 63 | { 64 | auto dyn_parent = dynamic_cast(child->parent()); 65 | wf::dassert(dyn_parent, "Raise to front in a non-floating container!"); 66 | 67 | auto children = dyn_parent->get_children(); 68 | if (children.front() == child) 69 | { 70 | return false; 71 | } 72 | 73 | children.erase(std::remove(children.begin(), children.end(), child), 74 | children.end()); 75 | children.insert(children.begin(), child); 76 | dyn_parent->set_children_list(children); 77 | update(dyn_parent->shared_from_this(), update_flag::CHILDREN_LIST); 78 | return true; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/api/wayfire/txn/transaction-manager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/signal-provider.hpp" 4 | #include "wayfire/txn/transaction-object.hpp" 5 | #include 6 | 7 | namespace wf 8 | { 9 | namespace txn 10 | { 11 | /* 12 | * The transaction manager keeps track of all committed and pending transactions and ensures that there is at 13 | * most one committed transaction for a given object. 14 | * 15 | * In order to do ensure correct ordering of transactions, it keeps a list of pending transactions. The first 16 | * transaction is committed as soon as there are no committed transactions with the same objects. In addition, 17 | * any new transactions which are not immediately committed but work with the same objects are coalesced 18 | * together. For example, if there are two transactions, one for objects A, for objects B,C and a third 19 | * transaction for objects A,B comes in, then all these three are merged together. This merging is done to 20 | * avoid sending excessive configure events to clients - for example during an interactive resize. 21 | */ 22 | class transaction_manager_t : public signal::provider_t 23 | { 24 | public: 25 | transaction_manager_t(); 26 | ~transaction_manager_t(); 27 | 28 | /** 29 | * Add a new transaction to the list of scheduled transactions. The transaction might be merged with 30 | * other transactions which came before or after it, according to the coalescing schema described above. 31 | * 32 | * Note that a transaction will never be started immediately. Instead, it will be started on the next idle 33 | * event of the event loop. 34 | */ 35 | void schedule_transaction(transaction_uptr tx); 36 | 37 | /** 38 | * A convenience function to create a transaction for a single object and schedule it via 39 | * schedule_transaction(). 40 | */ 41 | void schedule_object(transaction_object_sptr object); 42 | 43 | /** 44 | * Check whether there is a pending transaction for the given object. 45 | */ 46 | bool is_object_pending(transaction_object_sptr object) const; 47 | 48 | /** 49 | * Check whether there is a committed transaction for the given object. 50 | */ 51 | bool is_object_committed(transaction_object_sptr object) const; 52 | 53 | struct impl; 54 | std::unique_ptr priv; 55 | }; 56 | 57 | /** 58 | * The new-transaction signal is emitted before a new transaction is added to the transaction manager (e.g. 59 | * at the beginning of schedule_transaction()). The transaction may be merged into another transaction before 60 | * it is actually executed. 61 | */ 62 | struct new_transaction_signal 63 | { 64 | transaction_t *tx; 65 | }; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/api/wayfire/txn/transaction-object.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace wf 6 | { 7 | namespace txn 8 | { 9 | /** 10 | * A transaction object participates in the transactions system. 11 | * 12 | * Transaction objects usually have double-buffered state, which may not be applicable immediately, that is, 13 | * when a state change is requested, it takes some time until the changes can be applied. Sometimes, multiple 14 | * such objects are updated together in a single transaction, in which case the changes are to be seen as 15 | * atomic across all participating objects. 16 | * 17 | * The typical example of transaction objects are toplevels, where changing for example the size of the 18 | * toplevel requires cooperation from the client, and therefore cannot be done instantaneously. 19 | * 20 | * When speaking about transaction objects, they usually have three different types of state: current, 21 | * committed and pending. Current state is what the object currently is configured as, committed state is a 22 | * state which will soon be current (e.g. changes are underway), and pending are changes which have been 23 | * planned for the future, but execution has not started yet. 24 | */ 25 | class transaction_object_t : public signal::provider_t 26 | { 27 | public: 28 | /** 29 | * Get a string representing the transaction object. Used for debugging purposes. 30 | */ 31 | virtual std::string stringify() const; 32 | 33 | /** 34 | * Make the pending state committed. 35 | * This function is called when a transaction is committed. 36 | */ 37 | virtual void commit() = 0; 38 | 39 | /** 40 | * Make the committed state current. 41 | * This function is called when all transaction objects in a transaction are ready to apply the committed 42 | * state. 43 | */ 44 | virtual void apply() = 0; 45 | 46 | virtual ~transaction_object_t() = default; 47 | }; 48 | 49 | using transaction_object_sptr = std::shared_ptr; 50 | 51 | /** 52 | * A signal emitted on a transaction_object_t to indicate that it is ready to be applied. 53 | */ 54 | struct object_ready_signal 55 | { 56 | transaction_object_t *self; 57 | }; 58 | 59 | /** 60 | * Emit the object-ready signal on the given object. 61 | */ 62 | inline void emit_object_ready(wf::txn::transaction_object_t *obj) 63 | { 64 | wf::txn::object_ready_signal data_ready; 65 | data_ready.self = obj; 66 | obj->emit(&data_ready); 67 | return; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/api/wayfire/txn/transaction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/signal-provider.hpp" 4 | #include "wayfire/util.hpp" 5 | #include 6 | 7 | namespace wf 8 | { 9 | namespace txn 10 | { 11 | /** 12 | * A transaction contains one or more transaction objects whose state should be applied atomically, that is, 13 | * changes to the objects should be applied only after all the objects are ready to apply the changes. 14 | */ 15 | class transaction_t : public signal::provider_t 16 | { 17 | public: 18 | using timer_setter_t = std::function::callback_t)>; 19 | 20 | /** 21 | * Create a new transaction. 22 | * 23 | * @param timeout The timeout for the transaction in milliseconds after it is committed. 24 | * -1 means that core should pick a default timeout. 25 | */ 26 | static std::unique_ptr create(int64_t timeout = -1); 27 | 28 | /** 29 | * Create a new empty transaction. 30 | * 31 | * @param timer A function used to set timeout callbacks at runtime. 32 | * @param timeout The maximal duration, in milliseconds, to wait for transaction objects to become ready. 33 | * When the timeout is reached, all committed state is applied. 34 | */ 35 | transaction_t(uint64_t timeout, timer_setter_t timer_setter); 36 | 37 | /** 38 | * Add a new object to the transaction. If the object was already part of it, this is no-op. 39 | */ 40 | void add_object(transaction_object_sptr object); 41 | 42 | /** 43 | * Get a list of all the objects currently part of the transaction. 44 | */ 45 | const std::vector& get_objects() const; 46 | 47 | /** 48 | * Commit the transaction, that is, commit the pending state of all participating objects. 49 | * As soon as all objects are ready or the transaction times out, the state will be applied. 50 | */ 51 | void commit(); 52 | 53 | virtual ~transaction_t() = default; 54 | 55 | private: 56 | std::vector objects; 57 | int count_ready_objects = 0; 58 | uint64_t timeout; 59 | timer_setter_t timer_setter; 60 | 61 | void apply(bool did_timeout); 62 | wf::signal::connection_t on_object_ready; 63 | }; 64 | 65 | using transaction_uptr = std::unique_ptr; 66 | 67 | /** 68 | * A signal emitted on a transaction as soon as it has been applied. 69 | */ 70 | struct transaction_applied_signal 71 | { 72 | transaction_t *self; 73 | 74 | // Set to true if the transaction timed out and the desired object state may not have been achieved. 75 | bool timed_out; 76 | }; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/translation-node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace wf 7 | { 8 | namespace scene 9 | { 10 | /** 11 | * A node which simply applies an offset to its children. 12 | */ 13 | class translation_node_t : public wf::scene::floating_inner_node_t 14 | { 15 | public: 16 | translation_node_t(bool is_structure = false); 17 | 18 | /** 19 | * Set the offset the node applies to its children. 20 | * Note that damage is not automatically applied. 21 | */ 22 | void set_offset(wf::point_t offset); 23 | 24 | /** 25 | * Get the current offset (set via @set_offset). Default offset is {0, 0}. 26 | */ 27 | wf::point_t get_offset() const; 28 | 29 | public: // Implementation of node_t interface 30 | wf::pointf_t to_local(const wf::pointf_t& point) override; 31 | wf::pointf_t to_global(const wf::pointf_t& point) override; 32 | 33 | std::string stringify() const override; 34 | void gen_render_instances(std::vector& instances, 35 | scene::damage_callback damage, wf::output_t *output) override; 36 | wf::geometry_t get_bounding_box() override; 37 | uint32_t optimize_update(uint32_t flags) override; 38 | 39 | protected: 40 | wf::point_t offset = {0, 0}; 41 | }; 42 | 43 | class translation_node_instance_t : public render_instance_t 44 | { 45 | protected: 46 | std::vector children; 47 | damage_callback push_damage; 48 | std::shared_ptr self; 49 | wf::signal::connection_t on_node_damage; 50 | wf::signal::connection_t on_regen_instances; 51 | wf::output_t *shown_on; 52 | void regen_instances(); 53 | 54 | public: 55 | translation_node_instance_t(translation_node_t *self, 56 | damage_callback push_damage, wf::output_t *shown_on); 57 | 58 | // Implementation of render_instance_t 59 | void schedule_instructions(std::vector& instructions, 60 | const wf::render_target_t& target, wf::region_t& damage) override; 61 | void render(const wf::render_target_t& target, const wf::region_t& region) override; 62 | void presentation_feedback(wf::output_t *output) override; 63 | wf::scene::direct_scanout try_scanout(wf::output_t *output) override; 64 | void compute_visibility(wf::output_t *output, wf::region_t& visible) override; 65 | }; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/wlr-subsurface-controller.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/util.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace wf 10 | { 11 | /** 12 | * A subsurface root node. It applies a translation to its children equal to the offset of the subsurface. 13 | */ 14 | class wlr_subsurface_root_node_t : public wf::scene::translation_node_t 15 | { 16 | public: 17 | wlr_subsurface_root_node_t(wlr_subsurface *subsurface); 18 | std::string stringify() const override; 19 | bool update_offset(bool damage = true); 20 | 21 | private: 22 | wlr_subsurface *subsurface; 23 | wf::wl_listener_wrapper on_subsurface_destroy; 24 | wf::wl_listener_wrapper on_subsurface_commit; 25 | }; 26 | 27 | /** 28 | * A class which manages a wlr_subsurface. Its lifetime is tied to the wlr_subsurface object. 29 | * 30 | * This class is responsible for managing the subsurface's state and enabling/disabling it when the subsurface 31 | * is mapped and unmapped. In addition, it should clean up the scenegraph when the subsurface is destroyed. 32 | */ 33 | class wlr_subsurface_controller_t 34 | { 35 | public: 36 | wlr_subsurface_controller_t(wlr_subsurface *sub); 37 | std::shared_ptr get_subsurface_root(); 38 | 39 | private: 40 | wlr_subsurface *sub; 41 | wl_listener_wrapper on_map, on_unmap, on_destroy; 42 | std::shared_ptr subsurface_root_node; 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/wlr-surface-controller.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/scene.hpp" 4 | #include 5 | 6 | namespace wf 7 | { 8 | struct node_recheck_constraints_signal 9 | {}; 10 | 11 | /** 12 | * A class for managing a wlr_surface. 13 | * It is responsible for adding subsurfaces to it. 14 | */ 15 | class wlr_surface_controller_t 16 | { 17 | public: 18 | static void create_controller(wlr_surface *surface, scene::floating_inner_ptr root_node); 19 | static void try_free_controller(wlr_surface *surface); 20 | 21 | private: 22 | wlr_surface_controller_t(wlr_surface *surface, scene::floating_inner_ptr root_node); 23 | ~wlr_surface_controller_t(); 24 | 25 | void update_subsurface_order_and_position(); 26 | 27 | scene::floating_inner_ptr root; 28 | wlr_surface *surface; 29 | 30 | wf::wl_listener_wrapper on_destroy; 31 | wf::wl_listener_wrapper on_new_subsurface; 32 | wf::wl_listener_wrapper on_commit; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/wlr-text-input-v3-popup.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace wf 9 | { 10 | class text_input_v3_im_relay_interface_t : public wf::signal::provider_t 11 | { 12 | public: 13 | virtual wlr_text_input_v3 *find_focused_text_input_v3() = 0; 14 | virtual ~text_input_v3_im_relay_interface_t() = default; 15 | }; 16 | 17 | /** 18 | * A view implementation which presents an input-method popup-like surface relative to a text-input-v3 cursor. 19 | */ 20 | class text_input_v3_popup : public wf::view_interface_t 21 | { 22 | public: 23 | text_input_v3_im_relay_interface_t *relay = nullptr; 24 | wlr_surface *surface = nullptr; 25 | 26 | text_input_v3_popup(text_input_v3_im_relay_interface_t *relay, wlr_surface *surface); 27 | static std::shared_ptr create(text_input_v3_im_relay_interface_t*, wlr_surface*); 28 | 29 | bool is_mapped() const override; 30 | std::string get_app_id() override; 31 | std::string get_title() override; 32 | wf::geometry_t get_geometry(); 33 | void map(); 34 | void unmap(); 35 | void update_geometry(); 36 | void update_cursor_rect(wlr_box*); 37 | ~text_input_v3_popup(); 38 | 39 | private: 40 | wf::geometry_t geometry{0, 0, 0, 0}; 41 | wlr_box old_cursor_rect{0, 0, 0, 0}; 42 | wf::dimensions_t last_size{0, 0}; 43 | std::shared_ptr main_surface; 44 | std::shared_ptr surface_root_node; 45 | 46 | virtual wlr_surface *get_keyboard_focus_surface() override 47 | { 48 | return nullptr; 49 | } 50 | 51 | wf::signal::connection_t on_text_input_commit = [=] (auto s) 52 | { 53 | update_cursor_rect(&s->cursor_rect); 54 | }; 55 | 56 | wf::wl_listener_wrapper on_map; 57 | wf::wl_listener_wrapper on_unmap; 58 | wf::wl_listener_wrapper on_commit; 59 | wf::wl_listener_wrapper on_surface_destroy; 60 | 61 | public: 62 | // This is only a convenience wrapper for the users of this class. 63 | wf::wl_listener_wrapper on_destroy; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/wlr-view-events.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // WF_USE_CONFIG_H is set only when building Wayfire itself, external plugins 4 | // need to use 5 | #ifdef WF_USE_CONFIG_H 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #include 12 | #include 13 | 14 | namespace wf 15 | { 16 | /** 17 | * A signal emitted whenever a new xdg_surface object was created on the wlroots side. 18 | * By using this signal, plugins may indicate to core that they want to override the view implementation for 19 | * the given surface. 20 | */ 21 | struct new_xdg_surface_signal 22 | { 23 | wlr_xdg_surface *surface; 24 | 25 | /** 26 | * If a plugin sets this to false, then that plugin is responsible for allocating a view and the 27 | * corresponding nodes for the xdg_surface. Core will not handle the xdg_surface any further. 28 | */ 29 | bool use_default_implementation = true; 30 | }; 31 | 32 | #if WF_HAS_XWAYLAND 33 | /** 34 | * A signal emitted whenever a new wlr_xwayland_surface object was created on the wlroots side. 35 | * By using this signal, plugins may indicate to core that they want to override the view implementation for 36 | * the given surface. 37 | */ 38 | struct new_xwayland_surface_signal 39 | { 40 | wlr_xwayland_surface *surface; 41 | 42 | /** 43 | * If a plugin sets this to false, then that plugin is responsible for allocating a view and the 44 | * corresponding nodes for the xwayland_surface. Core will not handle the xwayland_surface any further. 45 | */ 46 | bool use_default_implementation = true; 47 | }; 48 | 49 | #endif 50 | 51 | /** 52 | * A signal emitted on core when a view with the default wayfire implementation is about to be mapped. 53 | * Plugins can take a look at the view and decide to overwrite its implementation. 54 | */ 55 | struct view_pre_map_signal 56 | { 57 | /** 58 | * The view which will be mapped after this signal, if plugins do not override it. 59 | */ 60 | wf::view_interface_t *view; 61 | 62 | /** 63 | * The wlr-surface of the view. 64 | */ 65 | wlr_surface *surface; 66 | 67 | /** 68 | * Plugins can set this to override the view implementation. If they do so, the view will not be mapped, 69 | * and instead the default controller and view implementation for the view will be destroyed after the 70 | * signal. Plugins are then free to provide a view implementation themselves. 71 | */ 72 | bool override_implementation = false; 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/wlr-view-keyboard-interaction.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace wf 12 | { 13 | /** 14 | * An implementation of keyboard_interaction_t for wlr_surface-based views. 15 | */ 16 | class wlr_view_keyboard_interaction_t : public wf::keyboard_interaction_t 17 | { 18 | std::weak_ptr view; 19 | bool force_enter; 20 | 21 | public: 22 | wlr_view_keyboard_interaction_t(wayfire_view _view, bool force_enter = false) 23 | { 24 | this->view = _view->weak_from_this(); 25 | this->force_enter = force_enter; 26 | } 27 | 28 | void handle_keyboard_enter(wf::seat_t *seat) override 29 | { 30 | if (auto ptr = view.lock()) 31 | { 32 | if (ptr->get_wlr_surface()) 33 | { 34 | auto pressed_keys = seat->get_pressed_keys(); 35 | 36 | auto kbd = wlr_seat_get_keyboard(seat->seat); 37 | 38 | if (force_enter) 39 | { 40 | wlr_seat_keyboard_enter(seat->seat, ptr->get_wlr_surface(), 41 | pressed_keys.data(), pressed_keys.size(), kbd ? &kbd->modifiers : NULL); 42 | } else 43 | { 44 | wlr_seat_keyboard_notify_enter(seat->seat, ptr->get_wlr_surface(), 45 | pressed_keys.data(), pressed_keys.size(), kbd ? &kbd->modifiers : NULL); 46 | } 47 | } 48 | } 49 | } 50 | 51 | void handle_keyboard_leave(wf::seat_t *seat) override 52 | { 53 | if (auto ptr = view.lock()) 54 | { 55 | wlr_seat_keyboard_notify_clear_focus(seat->seat); 56 | } 57 | } 58 | 59 | void handle_keyboard_key(wf::seat_t *seat, wlr_keyboard_key_event event) override 60 | { 61 | wlr_seat_keyboard_notify_key(seat->seat, event.time_msec, event.keycode, event.state); 62 | } 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/xdg-toplevel-base.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace wf 8 | { 9 | /** 10 | * A base class for xdg_toplevel-based views which implements the view_interface_t (but not toplevel_view_t, 11 | * see @xdg_toplevel_view_t for the full implementation). 12 | */ 13 | class xdg_toplevel_view_base_t : public virtual wf::view_interface_t 14 | { 15 | public: 16 | xdg_toplevel_view_base_t(wlr_xdg_toplevel *toplevel, bool autocommit); 17 | virtual ~xdg_toplevel_view_base_t(); 18 | 19 | void close() override; 20 | void ping() override; 21 | wlr_surface *get_keyboard_focus_surface() override; 22 | bool is_focusable() const override; 23 | std::string get_app_id() override; 24 | std::string get_title() override; 25 | bool is_mapped() const override; 26 | 27 | /** Set the view state to mapped. */ 28 | virtual void map(); 29 | /** Set the view state to unmapped. */ 30 | virtual void unmap(); 31 | 32 | protected: 33 | wlr_xdg_toplevel *xdg_toplevel; 34 | std::string app_id; 35 | std::string title; 36 | virtual void destroy(); 37 | 38 | std::shared_ptr main_surface; 39 | 40 | wf::wl_listener_wrapper on_destroy; 41 | wf::wl_listener_wrapper on_new_popup; 42 | wf::wl_listener_wrapper on_set_title; 43 | wf::wl_listener_wrapper on_set_app_id; 44 | wf::wl_listener_wrapper on_ping_timeout; 45 | 46 | void handle_title_changed(std::string new_title); 47 | void handle_app_id_changed(std::string new_app_id); 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /src/api/wayfire/unstable/xwl-toplevel-base.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // WF_USE_CONFIG_H is set only when building Wayfire itself, external plugins 4 | // need to use 5 | #ifdef WF_USE_CONFIG_H 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace wf 16 | { 17 | #if WF_HAS_XWAYLAND 18 | /** 19 | * A base class for views which base on a wlr_xwayland surface. 20 | * Contains the implementation of view_interface_t functions used in them. 21 | */ 22 | class xwayland_view_base_t : public virtual wf::view_interface_t 23 | { 24 | public: 25 | xwayland_view_base_t(wlr_xwayland_surface *xww); 26 | virtual ~xwayland_view_base_t(); 27 | 28 | virtual void do_map(wlr_surface *surface, bool autocommit, bool emit_map = true); 29 | virtual void do_unmap(); 30 | 31 | virtual void destroy(); 32 | void ping() override; 33 | void close() override; 34 | bool is_mapped() const override; 35 | std::string get_app_id() override; 36 | std::string get_title() override; 37 | 38 | wlr_surface *get_keyboard_focus_surface() override; 39 | bool is_focusable() const override; 40 | 41 | protected: 42 | std::string title, app_id; 43 | wlr_xwayland_surface *xw; 44 | bool kb_focus_enabled = true; 45 | 46 | /** Used by view implementations when the app id changes */ 47 | void handle_app_id_changed(std::string new_app_id); 48 | 49 | /** Used by view implementations when the title changes */ 50 | void handle_title_changed(std::string new_title); 51 | 52 | wf::wl_listener_wrapper on_destroy, on_set_title, on_set_app_id, on_ping_timeout; 53 | std::shared_ptr main_surface; 54 | }; 55 | #endif 56 | } 57 | -------------------------------------------------------------------------------- /src/api/wayfire/view-access-interface.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/condition/access_interface.hpp" 4 | #include "wayfire/view.hpp" 5 | #include 6 | #include 7 | 8 | namespace wf 9 | { 10 | /** 11 | * @brief The view_access_interface_t class is a view specific implementation of 12 | * access_interface_t. 13 | * 14 | * Refer to the docs of access_interface_t for more information. 15 | * 16 | * The following properties are supported: 17 | * 18 | * format: 19 | * property -> type (comment) 20 | * 21 | * "app_id" -> std::string 22 | * "title" -> std::string 23 | * "role" -> std::string 24 | * "fullscreen" -> bool 25 | * "activated" -> bool 26 | * "minimized" -> bool 27 | * "tiled-left" -> bool 28 | * "tiled-right" -> bool 29 | * "tiled-top" -> bool 30 | * "tiled-bottom" -> bool 31 | * "maximized" -> bool 32 | * "floating" -> bool 33 | * "type" -> std::string (This will return a type string like the matcher plugin did) 34 | */ 35 | class view_access_interface_t : public access_interface_t 36 | { 37 | public: 38 | /** 39 | * @brief view_access_interface_t Default constructor. 40 | */ 41 | view_access_interface_t(); 42 | 43 | /** 44 | * @brief view_access_interface_t Constructor that immediately assigns a view. 45 | * 46 | * @param[in] view The view to assign. 47 | */ 48 | view_access_interface_t(wayfire_view view); 49 | 50 | // Inherits docs. 51 | virtual ~view_access_interface_t() override; 52 | 53 | // Inherits docs. 54 | virtual variant_t get(const std::string & identifier, bool & error) override; 55 | 56 | /** 57 | * @brief set_view Setter for the view to interrogate. 58 | * 59 | * @param[in] view The view to assign. 60 | */ 61 | void set_view(wayfire_view view); 62 | 63 | private: 64 | 65 | /** 66 | * @brief _view The view to interrogate. 67 | */ 68 | wayfire_view _view; 69 | }; 70 | } // End namespace wf. 71 | -------------------------------------------------------------------------------- /src/api/wayfire/view-helpers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "toplevel.hpp" 4 | #include "wayfire/scene-input.hpp" 5 | #include "wayfire/scene.hpp" 6 | #include 7 | #include 8 | 9 | // This file contains helper functions which are helpful when working with views. Most of the operations are 10 | // simply wrappers around more low-level functionality provided by views, scenegraph, etc. 11 | namespace wf 12 | { 13 | /** 14 | * Find the scenegraph layer that the view is currently in. 15 | */ 16 | std::optional get_view_layer(wayfire_view view); 17 | 18 | /** 19 | * Reorder the nodes on the path from the view to the scenegraph root so that the view is as high in the 20 | * stacking order as possible. 21 | * 22 | * Also damages the affected nodes. 23 | */ 24 | void view_bring_to_front(wayfire_view view); 25 | 26 | /** 27 | * Iterate over all scenegraph nodes in the given scenegraph subtree and collect all enabled view nodes. 28 | * The nodes returned are in front-to-back order. 29 | */ 30 | std::vector collect_views_from_scenegraph(wf::scene::node_ptr root); 31 | 32 | /** 33 | * Collect all views from the scenegraph nodes of the output for the given layers. 34 | */ 35 | std::vector collect_views_from_output( 36 | wf::output_t *output, std::initializer_list layers); 37 | 38 | /** 39 | * Find the topmost parent in the chain of views. 40 | */ 41 | wayfire_view find_topmost_parent(wayfire_view v); 42 | wayfire_toplevel_view find_topmost_parent(wayfire_toplevel_view v); 43 | 44 | /** 45 | * A few simple functions which help in view implementations. 46 | */ 47 | namespace view_implementation 48 | { 49 | void emit_toplevel_state_change_signals(wayfire_toplevel_view view, const wf::toplevel_state_t& old_state); 50 | void emit_view_map_signal(wayfire_view view, bool has_position); 51 | void emit_ping_timeout_signal(wayfire_view view); 52 | void emit_geometry_changed_signal(wayfire_toplevel_view view, wf::geometry_t old_geometry); 53 | void emit_title_changed_signal(wayfire_view view); 54 | void emit_app_id_changed_signal(wayfire_view view); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/api/wayfire/workarea.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace wf 8 | { 9 | /** 10 | * Each output has a workarea manager which keeps track of the available workarea on that output. The 11 | * available area is typically the full output area minus any space reserved for panels, bars, etc. 12 | */ 13 | class output_workarea_manager_t 14 | { 15 | public: 16 | /** 17 | * Special clients like panels can reserve place from an edge of the output. 18 | * It is used when calculating the dimensions of maximized/tiled windows and 19 | * others. The remaining space (which isn't reserved for panels) is called 20 | * the workarea. 21 | */ 22 | enum anchored_edge 23 | { 24 | ANCHORED_EDGE_TOP = 0, 25 | ANCHORED_EDGE_BOTTOM = 1, 26 | ANCHORED_EDGE_LEFT = 2, 27 | ANCHORED_EDGE_RIGHT = 3, 28 | }; 29 | 30 | struct anchored_area 31 | { 32 | // The edge from which to reserve area. 33 | anchored_edge edge; 34 | 35 | // Amount of space to reserve. 36 | int reserved_size; 37 | 38 | // The reflowed callback is optional and when present, is called every time the anchored areas are 39 | // reflowed (e.g. anchored areas are recalculated). The passed geometry is the available workarea 40 | // before the view's own request was considered. That means, for the first anchored area in the 41 | // workarea manager, the geometry will be the full output's geometry. For each subsequent anchored 42 | // area, the size of the previous anchored areas is excluded from the passed available workarea. 43 | std::function reflowed; 44 | }; 45 | 46 | /** 47 | * Add a reserved area. The actual recalculation must be manually 48 | * triggered by calling reflow_reserved_areas() 49 | */ 50 | void add_reserved_area(anchored_area *area); 51 | 52 | /** 53 | * Remove a reserved area. The actual recalculation must be manually 54 | * triggered by calling reflow_reserved_areas() 55 | */ 56 | void remove_reserved_area(anchored_area *area); 57 | 58 | /** 59 | * Recalculate reserved area for each anchored area 60 | */ 61 | void reflow_reserved_areas(); 62 | 63 | /** 64 | * @return The free space of the output after reserving the space for panels 65 | */ 66 | wf::geometry_t get_workarea(); 67 | 68 | output_workarea_manager_t(wf::output_t *output); 69 | ~output_workarea_manager_t(); 70 | 71 | private: 72 | struct impl; 73 | std::unique_ptr priv; 74 | }; 75 | } 76 | -------------------------------------------------------------------------------- /src/api/wayfire/workspace-stream.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/scene-render.hpp" 4 | #include "wayfire/scene.hpp" 5 | #include "wayfire/signal-provider.hpp" 6 | #include 7 | #include 8 | #include 9 | 10 | namespace wf 11 | { 12 | /** 13 | * A workspace stream is a special node which displays a workspace of an output. 14 | */ 15 | class workspace_stream_node_t : public scene::node_t 16 | { 17 | public: 18 | workspace_stream_node_t(wf::output_t *output, wf::point_t workspace); 19 | 20 | // The color of the background of the workspace stream. 21 | // If not set, the default background color (specified in the config file) 22 | // of Wayfire is used. 23 | std::optional background; 24 | 25 | wf::output_t*const output; 26 | const wf::point_t ws; 27 | 28 | // node_t implementation 29 | 30 | public: 31 | std::string stringify() const override; 32 | void gen_render_instances(std::vector& instances, 33 | scene::damage_callback push_damage, wf::output_t *output) override; 34 | // The bounding box of a workspace stream is 35 | // (0, 0, output_width, output_height). 36 | wf::geometry_t get_bounding_box() override; 37 | class workspace_stream_instance_t; 38 | 39 | private: 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /src/core/idle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "core/seat/input-manager.hpp" 4 | #include "core-impl.hpp" 5 | 6 | unsigned int wf::idle_inhibitor_t::inhibitors = 0; 7 | 8 | void wf::idle_inhibitor_t::notify_update() 9 | { 10 | /* NOTE: inhibited -> NOT enabled */ 11 | wlr_idle_notifier_v1_set_inhibited(wf::get_core().protocols.idle_notifier, inhibitors != 0); 12 | 13 | wf::idle_inhibit_changed_signal data; 14 | data.inhibit = (inhibitors != 0); 15 | wf::get_core().emit(&data); 16 | } 17 | 18 | wf::idle_inhibitor_t::idle_inhibitor_t() 19 | { 20 | LOGD("creating idle inhibitor ", this, " previous count: ", inhibitors); 21 | inhibitors++; 22 | notify_update(); 23 | } 24 | 25 | wf::idle_inhibitor_t::~idle_inhibitor_t() 26 | { 27 | LOGD("destroying idle inhibitor ", this, " previous count: ", inhibitors); 28 | inhibitors--; 29 | notify_update(); 30 | } 31 | -------------------------------------------------------------------------------- /src/core/object.cpp: -------------------------------------------------------------------------------- 1 | #include "wayfire/object.hpp" 2 | #include "wayfire/nonstd/safe-list.hpp" 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | void wf::signal::connection_base_t::disconnect() 9 | { 10 | auto connected_copy = this->connected_to; 11 | for (auto& x : connected_copy) 12 | { 13 | x->disconnect(this); 14 | } 15 | } 16 | 17 | class wf::object_base_t::obase_impl 18 | { 19 | public: 20 | std::unordered_map> data; 21 | uint32_t object_id; 22 | }; 23 | 24 | wf::object_base_t::object_base_t() 25 | { 26 | this->obase_priv = std::make_unique(); 27 | 28 | static uint32_t global_id = 0; 29 | obase_priv->object_id = global_id++; 30 | } 31 | 32 | wf::object_base_t::~object_base_t() = default; 33 | 34 | std::string wf::object_base_t::to_string() const 35 | { 36 | return std::to_string(get_id()); 37 | } 38 | 39 | uint32_t wf::object_base_t::get_id() const 40 | { 41 | return obase_priv->object_id; 42 | } 43 | 44 | bool wf::object_base_t::has_data(std::string name) 45 | { 46 | return obase_priv->data[name] != nullptr; 47 | } 48 | 49 | void wf::object_base_t::erase_data(std::string name) 50 | { 51 | auto data = std::move(obase_priv->data[name]); 52 | obase_priv->data.erase(name); 53 | data.reset(); 54 | } 55 | 56 | wf::custom_data_t*wf::object_base_t::_fetch_data(std::string name) 57 | { 58 | auto it = obase_priv->data.find(name); 59 | if (it == obase_priv->data.end()) 60 | { 61 | return nullptr; 62 | } 63 | 64 | return it->second.get(); 65 | } 66 | 67 | wf::custom_data_t*wf::object_base_t::_fetch_erase(std::string name) 68 | { 69 | auto data = obase_priv->data[name].release(); 70 | erase_data(name); 71 | 72 | return data; 73 | } 74 | 75 | void wf::object_base_t::_store_data(std::unique_ptr data, 76 | std::string name) 77 | { 78 | obase_priv->data[name] = std::move(data); 79 | } 80 | 81 | void wf::object_base_t::_clear_data() 82 | { 83 | obase_priv->data.clear(); 84 | } 85 | -------------------------------------------------------------------------------- /src/core/opengl-priv.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_OPENGL_PRIV_HPP 2 | #define WF_OPENGL_PRIV_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace OpenGL 8 | { 9 | /** Initialize OpenGL helper functions */ 10 | void init(); 11 | /** Destroy the default GL program and resources */ 12 | void fini(); 13 | /** Indicate we have started repainting the given output */ 14 | void bind_output(wf::output_t *output, uint32_t fb); 15 | /** Indicate the output frame has been finished */ 16 | void unbind_output(wf::output_t *output); 17 | } 18 | 19 | #endif /* end of include guard: WF_OPENGL_PRIV_HPP */ 20 | -------------------------------------------------------------------------------- /src/core/plugin-loader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "wayfire/plugin.hpp" 6 | #include "config.h" 7 | #include "wayfire/util.hpp" 8 | #include 9 | 10 | namespace wf 11 | { 12 | struct loaded_plugin_t 13 | { 14 | // A pointer to the plugin 15 | std::unique_ptr instance; 16 | 17 | // A handle returned by dlopen(). 18 | void *so_handle; 19 | 20 | // A path to the .so file of the plugin. 21 | std::string so_path; 22 | }; 23 | 24 | struct plugin_manager_t 25 | { 26 | plugin_manager_t(); 27 | ~plugin_manager_t(); 28 | 29 | void reload_dynamic_plugins(); 30 | wf::wl_idle_call idle_reload_plugins; 31 | 32 | private: 33 | wf::option_wrapper_t plugins_opt; 34 | wf::option_wrapper_t enable_so_unloading; 35 | std::unordered_map loaded_plugins; 36 | 37 | void deinit_plugins(bool unloadable); 38 | 39 | std::optional load_plugin_from_file(std::string path); 40 | void load_static_plugins(); 41 | void destroy_plugin(loaded_plugin_t& plugin); 42 | }; 43 | 44 | /** Helper functions */ 45 | template 46 | B union_cast(A object) 47 | { 48 | union 49 | { 50 | A x; 51 | B y; 52 | } helper; 53 | helper.x = object; 54 | return helper.y; 55 | } 56 | 57 | /** 58 | * Open a plugin file and check the file for version errors. 59 | * 60 | * On success, return the handle from dlopen() and the pointer to the 61 | * newInstance of the plugin. 62 | * 63 | * @return (dlopen() handle, newInstance pointer) 64 | */ 65 | std::pair get_new_instance_handle(const std::string& path); 66 | 67 | /** 68 | * List the locations where wayfire's plugins are installed. 69 | * This function takes care of env variable WAYFIRE_PLUGIN_PATH, 70 | * as well as the default location. 71 | */ 72 | std::vector get_plugin_paths(); 73 | 74 | /** 75 | * Search each path specified in @param plugin_paths for a plugin named @param 76 | * plugin_name 77 | * @param plugin_paths A list of locations where wayfire plugins are installed 78 | * @param plugin_name The plugin to be searched. If @param plugin_name is an 79 | * absolute path, then it is returned without modification. 80 | */ 81 | std::optional get_plugin_path_for_name( 82 | std::vector plugin_paths, std::string plugin_name); 83 | } 84 | -------------------------------------------------------------------------------- /src/core/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "core-impl.hpp" 2 | #include "wayfire/debug.hpp" 3 | #include "wayfire/output.hpp" 4 | #include "seat/input-manager.hpp" 5 | #include "wayfire/signal-definitions.hpp" 6 | #include 7 | #include 8 | 9 | void wf::plugin_interface_t::fini() 10 | {} 11 | 12 | namespace wf 13 | { 14 | /** Implementation of default config backend functions. */ 15 | std::shared_ptr wf::config_backend_t::get_output_section( 16 | wlr_output *output) 17 | { 18 | std::string name = output->name; 19 | name = "output:" + name; 20 | auto& config = wf::get_core().config; 21 | if (!config.get_section(name)) 22 | { 23 | config.merge_section( 24 | config.get_section("output")->clone_with_name(name)); 25 | } 26 | 27 | return config.get_section(name); 28 | } 29 | 30 | std::shared_ptr wf::config_backend_t::get_input_device_section( 31 | wlr_input_device *device) 32 | { 33 | std::string name = nonull(device->name); 34 | name = "input-device:" + name; 35 | auto& config = wf::get_core().config; 36 | if (!config.get_section(name)) 37 | { 38 | config.merge_section( 39 | config.get_section("input-device")->clone_with_name(name)); 40 | } 41 | 42 | return config.get_section(name); 43 | } 44 | 45 | std::vector wf::config_backend_t::get_xml_dirs() const 46 | { 47 | std::vector xmldirs; 48 | if (char *plugin_xml_path = getenv("WAYFIRE_PLUGIN_XML_PATH")) 49 | { 50 | std::stringstream ss(plugin_xml_path); 51 | std::string entry; 52 | while (std::getline(ss, entry, ':')) 53 | { 54 | xmldirs.push_back(entry); 55 | } 56 | } 57 | 58 | // also add XDG specific paths 59 | std::string xdg_data_dir; 60 | char *c_xdg_data_dir = std::getenv("XDG_DATA_HOME"); 61 | char *c_user_home = std::getenv("HOME"); 62 | 63 | if (c_xdg_data_dir != NULL) 64 | { 65 | xdg_data_dir = c_xdg_data_dir; 66 | } else if (c_user_home != NULL) 67 | { 68 | xdg_data_dir = (std::string)c_user_home + "/.local/share/"; 69 | } 70 | 71 | if (xdg_data_dir != "") 72 | { 73 | xmldirs.push_back(xdg_data_dir + "/wayfire/metadata"); 74 | } 75 | 76 | xmldirs.push_back(PLUGIN_XML_DIR); 77 | return xmldirs; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/core/scene-priv.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | namespace wf 6 | { 7 | namespace scene 8 | { 9 | struct root_node_t::priv_t 10 | {}; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/core/seat/bindings-repository-impl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/bindings-repository.hpp" 4 | #include "hotspot-manager.hpp" 5 | #include "wayfire/signal-definitions.hpp" 6 | #include 7 | 8 | struct wf::bindings_repository_t::impl 9 | { 10 | /** 11 | * Recreate hotspots. 12 | * 13 | * The action will take place on the next idle. 14 | */ 15 | void recreate_hotspots() 16 | { 17 | this->idle_recreate_hotspots.run_once([=] () 18 | { 19 | if (enabled > 0) 20 | { 21 | hotspot_mgr.update_hotspots(activators); 22 | } else 23 | { 24 | hotspot_mgr.update_hotspots({}); 25 | } 26 | }); 27 | } 28 | 29 | void reparse_extensions(); 30 | 31 | binding_container_t keys; 32 | binding_container_t axes; 33 | binding_container_t buttons; 34 | binding_container_t activators; 35 | 36 | hotspot_manager_t hotspot_mgr; 37 | 38 | wf::signal::connection_t on_config_reload = [=] (wf::reload_config_signal *ev) 39 | { 40 | recreate_hotspots(); 41 | reparse_extensions(); 42 | }; 43 | 44 | wf::wl_idle_call idle_recreate_hotspots; 45 | wf::wl_idle_call idle_reparse_bindings; 46 | 47 | int enabled = 1; 48 | }; 49 | -------------------------------------------------------------------------------- /src/core/seat/cursor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CURSOR_HPP 2 | #define CURSOR_HPP 3 | 4 | #include "seat-impl.hpp" 5 | #include "wayfire/plugin.hpp" 6 | #include "wayfire/signal-definitions.hpp" 7 | #include "wayfire/util.hpp" 8 | 9 | namespace wf 10 | { 11 | struct cursor_t 12 | { 13 | cursor_t(wf::seat_t *seat); 14 | ~cursor_t() = default; 15 | 16 | /** 17 | * Register a new input device. 18 | */ 19 | void add_new_device(wlr_input_device *device); 20 | 21 | /** 22 | * Set the cursor image from a wlroots event. 23 | * @param validate_request Whether to validate the request against the 24 | * currently focused pointer surface, or not. 25 | */ 26 | void set_cursor(wlr_seat_pointer_request_set_cursor_event *ev, 27 | bool validate_request); 28 | void set_cursor(std::string name); 29 | void unhide_cursor(); 30 | void hide_cursor(); 31 | int hide_ref_counter = 0; 32 | 33 | /** 34 | * Delay setting the cursor, in order to avoid setting the cursor 35 | * multiple times in a single frame and to avoid setting it in the middle 36 | * of the repaint loop (not allowed by wlroots). 37 | */ 38 | wf::wl_idle_call idle_set_cursor; 39 | 40 | /** 41 | * Start/stop touchscreen mode, which means the cursor will be hidden. 42 | * It will be shown again once a pointer or tablet event happens. 43 | */ 44 | void set_touchscreen_mode(bool enabled); 45 | 46 | /* Move the cursor to the given point */ 47 | void warp_cursor(wf::pointf_t point); 48 | wf::pointf_t get_cursor_position(); 49 | 50 | void init_xcursor(); 51 | void setup_listeners(); 52 | 53 | // Device event listeners 54 | wf::wl_listener_wrapper on_button, on_motion, on_motion_absolute, on_axis, 55 | 56 | on_swipe_begin, on_swipe_update, on_swipe_end, 57 | on_pinch_begin, on_pinch_update, on_pinch_end, 58 | on_hold_begin, on_hold_end, 59 | 60 | on_tablet_tip, on_tablet_axis, 61 | on_tablet_button, on_tablet_proximity, 62 | on_frame; 63 | 64 | // Seat events 65 | wf::wl_listener_wrapper request_set_cursor; 66 | 67 | wf::signal::connection_t config_reloaded; 68 | wf::seat_t *seat; 69 | 70 | wlr_cursor *cursor = NULL; 71 | wlr_xcursor_manager *xcursor = NULL; 72 | 73 | bool touchscreen_mode_active = false; 74 | }; 75 | } 76 | 77 | #endif /* end of include guard: CURSOR_HPP */ 78 | -------------------------------------------------------------------------------- /src/core/seat/drag-icon.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "wayfire/geometry.hpp" 5 | #include 6 | #include 7 | 8 | namespace wf 9 | { 10 | namespace scene 11 | { 12 | class dnd_root_icon_root_node_t; 13 | } 14 | 15 | class drag_icon_t 16 | { 17 | public: 18 | wlr_drag_icon *icon; 19 | wl_listener_wrapper on_map, on_unmap, on_destroy; 20 | 21 | drag_icon_t(wlr_drag_icon *icon); 22 | ~drag_icon_t(); 23 | 24 | /** Called each time the DnD icon position changes. */ 25 | void update_position(); 26 | 27 | /** Last icon box. */ 28 | wf::geometry_t last_box = {0, 0, 0, 0}; 29 | wf::point_t get_position(); 30 | 31 | std::shared_ptr root_node; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /src/core/seat/input-manager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_MANAGER_HPP 2 | #define INPUT_MANAGER_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "seat-impl.hpp" 9 | #include "wayfire/plugin.hpp" 10 | #include "wayfire/signal-provider.hpp" 11 | #include "wayfire/view.hpp" 12 | #include "wayfire/core.hpp" 13 | #include "wayfire/signal-definitions.hpp" 14 | #include 15 | 16 | namespace wf 17 | { 18 | /** 19 | * input_manager is a class which manages high-level input state: 20 | * 1. Active grabs 21 | * 2. Exclusive clients 22 | * 3. Available input devices 23 | */ 24 | class input_manager_t 25 | { 26 | private: 27 | wf::wl_listener_wrapper input_device_created; 28 | wf::wl_idle_call idle_update_cursor; 29 | 30 | wf::signal::connection_t config_updated; 31 | wf::signal::connection_t output_added; 32 | 33 | public: 34 | /** 35 | * Locked mods are stored globally because the keyboard devices might be 36 | * destroyed and created again by wlroots. 37 | */ 38 | uint32_t locked_mods = 0; 39 | 40 | /** 41 | * Go through all input devices and map them to outputs as specified in the 42 | * config file or by hints in the wlroots backend. 43 | */ 44 | void refresh_device_mappings(); 45 | 46 | input_manager_t(); 47 | ~input_manager_t() = default; 48 | 49 | /** Initialize a new input device */ 50 | void handle_new_input(wlr_input_device *dev); 51 | /** Destroy an input device */ 52 | void handle_input_destroyed(wlr_input_device *dev); 53 | 54 | wl_client *exclusive_client = NULL; 55 | /** 56 | * Set the exclusive client. 57 | * Only it can get pointer focus from now on. 58 | * Exceptions are allowed for special views like OSKs. 59 | */ 60 | void set_exclusive_focus(wl_client *client); 61 | 62 | std::vector> input_devices; 63 | }; 64 | } 65 | 66 | /** 67 | * Emit a signal for device events. 68 | */ 69 | template 70 | wf::input_event_processing_mode_t emit_device_event_signal(EventType *event, wlr_input_device *device) 71 | { 72 | wf::input_event_signal data; 73 | data.event = event; 74 | data.device = device; 75 | wf::get_core().emit(&data); 76 | return data.mode; 77 | } 78 | 79 | template 80 | void emit_device_post_event_signal(EventType *event, wlr_input_device *device) 81 | { 82 | wf::post_input_event_signal data; 83 | data.event = event; 84 | data.device = device; 85 | wf::get_core().emit(&data); 86 | } 87 | 88 | #endif /* end of include guard: INPUT_MANAGER_HPP */ 89 | -------------------------------------------------------------------------------- /src/core/seat/keyboard.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "seat-impl.hpp" 5 | #include "wayfire/signal-definitions.hpp" 6 | #include "wayfire/signal-provider.hpp" 7 | #include "wayfire/util.hpp" 8 | #include 9 | 10 | namespace wf 11 | { 12 | enum locked_mods_t 13 | { 14 | KB_MOD_NUM_LOCK = 1 << 0, 15 | KB_MOD_CAPS_LOCK = 1 << 1, 16 | }; 17 | 18 | /** 19 | * Represents a logical keyboard. 20 | */ 21 | class keyboard_t 22 | { 23 | public: 24 | keyboard_t(wlr_input_device *keyboard); 25 | ~keyboard_t(); 26 | 27 | wlr_keyboard *handle; 28 | wlr_input_device *device; 29 | 30 | /** Get the currently pressed modifiers */ 31 | uint32_t get_modifiers(); 32 | 33 | /* The keycode which triggered the modifier binding */ 34 | uint32_t mod_binding_key = 0; 35 | 36 | /** Convert a key to a modifier */ 37 | uint32_t mod_from_key(uint32_t key); 38 | 39 | private: 40 | wf::wl_listener_wrapper on_key, on_modifier; 41 | void setup_listeners(); 42 | 43 | wf::signal::connection_t on_config_reload; 44 | void reload_input_options(); 45 | 46 | wf::option_wrapper_t model, variant, layout, options, rules; 47 | wf::option_wrapper_t repeat_rate, repeat_delay; 48 | /** Options have changed in the config file */ 49 | bool dirty_options = true; 50 | 51 | std::chrono::steady_clock::time_point mod_binding_start; 52 | 53 | bool handle_keyboard_key(uint32_t key, uint32_t state); 54 | 55 | /** Get the current locked mods */ 56 | uint32_t get_locked_mods(); 57 | 58 | /** Check whether we have only modifiers pressed down */ 59 | bool has_only_modifiers(); 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /src/core/seat/pointing-device.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_SEAT_POINTING_DEVICE_HPP 2 | #define WF_SEAT_POINTING_DEVICE_HPP 3 | 4 | #include "seat-impl.hpp" 5 | 6 | namespace wf 7 | { 8 | struct pointing_device_t : public input_device_impl_t 9 | { 10 | pointing_device_t(wlr_input_device *dev); 11 | virtual ~pointing_device_t() = default; 12 | 13 | void update_options() override; 14 | 15 | static struct config_t 16 | { 17 | wf::option_wrapper_t left_handed_mode; 18 | wf::option_wrapper_t middle_emulation; 19 | wf::option_wrapper_t mouse_cursor_speed; 20 | wf::option_wrapper_t mouse_scroll_speed; 21 | wf::option_wrapper_t tablet_motion_mode; 22 | wf::option_wrapper_t touchpad_cursor_speed; 23 | wf::option_wrapper_t touchpad_scroll_speed; 24 | wf::option_wrapper_t trackpoint_cursor_speed; 25 | wf::option_wrapper_t touchpad_click_method; 26 | wf::option_wrapper_t touchpad_scroll_method; 27 | wf::option_wrapper_t touchpad_accel_profile; 28 | wf::option_wrapper_t mouse_accel_profile; 29 | wf::option_wrapper_t trackpoint_accel_profile; 30 | wf::option_wrapper_t touchpad_tap_enabled; 31 | wf::option_wrapper_t touchpad_dwt_enabled; 32 | wf::option_wrapper_t touchpad_dwmouse_enabled; 33 | wf::option_wrapper_t touchpad_natural_scroll_enabled; 34 | wf::option_wrapper_t mouse_natural_scroll_enabled; 35 | wf::option_wrapper_t touchpad_drag_lock_enabled; 36 | void load(); 37 | } config; 38 | }; 39 | } 40 | 41 | #endif /* end of include guard: WF_SEAT_POINTING_DEVICE_HPP */ 42 | -------------------------------------------------------------------------------- /src/core/seat/switch.cpp: -------------------------------------------------------------------------------- 1 | #include "switch.hpp" 2 | #include 3 | #include 4 | 5 | wf::switch_device_t::switch_device_t(wlr_input_device *dev) : 6 | input_device_impl_t(dev) 7 | { 8 | on_switch.set_callback([&] (void *data) 9 | { 10 | this->handle_switched((wlr_switch_toggle_event*)data); 11 | }); 12 | on_switch.connect(&wlr_switch_from_input_device(dev)->events.toggle); 13 | } 14 | 15 | void wf::switch_device_t::handle_switched(wlr_switch_toggle_event *ev) 16 | { 17 | wf::switch_signal data; 18 | data.device = nonstd::make_observer(this); 19 | data.state = (ev->switch_state == WLR_SWITCH_STATE_ON); 20 | wf::get_core().emit(&data); 21 | } 22 | -------------------------------------------------------------------------------- /src/core/seat/switch.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WF_SEAT_SWITCH_HPP 2 | #define WF_SEAT_SWITCH_HPP 3 | 4 | #include "seat-impl.hpp" 5 | 6 | namespace wf 7 | { 8 | struct switch_device_t : public input_device_impl_t 9 | { 10 | wf::wl_listener_wrapper on_switch; 11 | void handle_switched(wlr_switch_toggle_event *ev); 12 | 13 | switch_device_t(wlr_input_device *dev); 14 | virtual ~switch_device_t() = default; 15 | }; 16 | } 17 | 18 | #endif /* end of include guard: WF_SEAT_SWITCH_HPP */ 19 | -------------------------------------------------------------------------------- /src/core/shaders.tpp: -------------------------------------------------------------------------------- 1 | static const char *default_vertex_shader_source = 2 | R"(#version 100 3 | 4 | attribute mediump vec2 position; 5 | attribute highp vec2 uvPosition; 6 | varying highp vec2 uvpos; 7 | 8 | uniform mat4 MVP; 9 | 10 | void main() { 11 | gl_Position = MVP * vec4(position.xy, 0.0, 1.0); 12 | uvpos = uvPosition; 13 | })"; 14 | 15 | static const char *default_fragment_shader_source = 16 | R"(#version 100 17 | @builtin_ext@ 18 | @builtin@ 19 | 20 | varying highp vec2 uvpos; 21 | uniform mediump vec4 color; 22 | 23 | void main() 24 | { 25 | mediump vec4 tex_color = get_pixel(uvpos); 26 | tex_color.rgb = tex_color.rgb * color.a; 27 | gl_FragColor = tex_color * color; 28 | })"; 29 | 30 | static const char *color_rect_fragment_source = 31 | R"(#version 100 32 | varying highp vec2 uvpos; 33 | uniform mediump vec4 color; 34 | 35 | void main() 36 | { 37 | gl_FragColor = color; 38 | })"; 39 | 40 | 41 | 42 | static const char *builtin_rgba_source = 43 | R"( 44 | uniform sampler2D _wayfire_texture; 45 | uniform mediump vec2 _wayfire_uv_base; 46 | uniform mediump vec2 _wayfire_uv_scale; 47 | 48 | mediump vec4 get_pixel(highp vec2 uv) { 49 | uv = _wayfire_uv_base + _wayfire_uv_scale * uv; 50 | return texture2D(_wayfire_texture, uv); 51 | } 52 | )"; 53 | 54 | static const char *builtin_rgbx_source = 55 | R"( 56 | uniform sampler2D _wayfire_texture; 57 | uniform mediump vec2 _wayfire_uv_base; 58 | uniform mediump vec2 _wayfire_uv_scale; 59 | 60 | mediump vec4 get_pixel(highp vec2 uv) { 61 | uv = _wayfire_uv_base + _wayfire_uv_scale * uv; 62 | return vec4(texture2D(_wayfire_texture, uv).rgb, 1.0); 63 | } 64 | )"; 65 | 66 | static const char *builtin_external_source = 67 | R"( 68 | uniform samplerExternalOES _wayfire_texture; 69 | uniform mediump vec2 _wayfire_uv_base; 70 | uniform mediump vec2 _wayfire_uv_scale; 71 | 72 | mediump vec4 get_pixel(highp vec2 uv) { 73 | uv = _wayfire_uv_base + _wayfire_uv_scale * uv; 74 | return texture2D(_wayfire_texture, uv); 75 | } 76 | )"; 77 | 78 | static const char *builtin_ext_external_source = 79 | R"(#extension GL_OES_EGL_image_external : require 80 | 81 | )"; 82 | -------------------------------------------------------------------------------- /src/core/txn/transaction-manager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "transaction-manager-impl.hpp" 4 | #include "wayfire/debug.hpp" 5 | #include "wayfire/txn/transaction.hpp" 6 | 7 | wf::txn::transaction_manager_t::transaction_manager_t() 8 | { 9 | this->priv = std::make_unique(); 10 | } 11 | 12 | wf::txn::transaction_manager_t::~transaction_manager_t() = default; 13 | 14 | void wf::txn::transaction_manager_t::schedule_transaction(wf::txn::transaction_uptr tx) 15 | { 16 | new_transaction_signal ev; 17 | ev.tx = tx.get(); 18 | this->emit(&ev); 19 | priv->schedule_transaction(std::move(tx)); 20 | } 21 | 22 | void wf::txn::transaction_manager_t::schedule_object(transaction_object_sptr object) 23 | { 24 | auto tx = wf::txn::transaction_t::create(); 25 | tx->add_object(std::move(object)); 26 | schedule_transaction(std::move(tx)); 27 | } 28 | 29 | template 30 | static bool is_contained(const std::vector& objs, const T& object) 31 | { 32 | return std::find(objs.begin(), objs.end(), object) != objs.end(); 33 | } 34 | 35 | bool wf::txn::transaction_manager_t::is_object_pending(transaction_object_sptr object) const 36 | { 37 | return std::any_of(this->priv->pending.begin(), this->priv->pending.end(), [&] (auto& pending) 38 | { 39 | return is_contained(pending->get_objects(), object); 40 | }); 41 | } 42 | 43 | bool wf::txn::transaction_manager_t::is_object_committed(transaction_object_sptr object) const 44 | { 45 | return std::any_of(this->priv->committed.begin(), this->priv->committed.end(), [&] (auto& committed) 46 | { 47 | return is_contained(committed->get_objects(), object); 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /src/core/wm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WM_H 2 | #define WM_H 3 | 4 | #include "wayfire/plugin.hpp" 5 | #include "wayfire/per-output-plugin.hpp" 6 | #include "wayfire/bindings.hpp" 7 | #include "wayfire/signal-definitions.hpp" 8 | #include "wayfire/signal-provider.hpp" 9 | #include "wayfire/view.hpp" 10 | #include "wayfire/touch/touch.hpp" 11 | #include "wayfire/option-wrapper.hpp" 12 | 13 | class wayfire_close : public wf::per_output_plugin_instance_t 14 | { 15 | wf::activator_callback callback; 16 | 17 | wf::plugin_activation_data_t grab_interface = { 18 | .name = "builtin-close-view", 19 | .capabilities = wf::CAPABILITY_GRAB_INPUT, 20 | }; 21 | 22 | public: 23 | void init() override; 24 | void fini() override; 25 | }; 26 | 27 | class wayfire_focus : public wf::plugin_interface_t 28 | { 29 | wf::signal::connection_t> on_pointer_button; 30 | std::unique_ptr tap_gesture; 31 | 32 | // @return True if the focus has changed 33 | bool check_focus_surface(wayfire_view view); 34 | 35 | wf::option_wrapper_t focus_modifiers{"core/focus_button_with_modifiers"}; 36 | wf::option_wrapper_t pass_btns{"core/focus_buttons_passthrough"}; 37 | wf::option_wrapper_t focus_btns{"core/focus_buttons"}; 38 | 39 | wf::plugin_activation_data_t grab_interface = { 40 | .name = "_wf_focus", 41 | .capabilities = wf::CAPABILITY_MANAGE_DESKTOP, 42 | }; 43 | 44 | public: 45 | void init() override; 46 | void fini() override; 47 | }; 48 | 49 | class wayfire_exit : public wf::per_output_plugin_instance_t 50 | { 51 | wf::key_callback key; 52 | 53 | public: 54 | void init() override; 55 | void fini() override; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/main.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_HPP 2 | #define MAIN_HPP 3 | 4 | #include 5 | 6 | extern struct wf_runtime_config 7 | { 8 | bool no_damage_track = false; 9 | bool legacy_wl_drm = false; 10 | bool damage_debug = false; 11 | } runtime_config; 12 | 13 | void restore_nofile_limit(void); 14 | 15 | static struct rlimit original_nofile_rlimit; 16 | 17 | #endif /* end of include guard: MAIN_HPP */ 18 | -------------------------------------------------------------------------------- /src/output/workarea.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "wayfire/geometry.hpp" 3 | #include "wayfire/signal-provider.hpp" 4 | #include 5 | #include 6 | 7 | struct wf::output_workarea_manager_t::impl 8 | { 9 | wf::geometry_t current_workarea; 10 | std::vector anchors; 11 | output_t *output; 12 | wf::signal::connection_t on_configuration_changed; 13 | }; 14 | 15 | wf::output_workarea_manager_t::output_workarea_manager_t(output_t *output) 16 | { 17 | priv = std::make_unique(); 18 | priv->output = output; 19 | priv->current_workarea = output->get_relative_geometry(); 20 | priv->on_configuration_changed = [=] (auto) 21 | { 22 | this->reflow_reserved_areas(); 23 | }; 24 | output->connect(&priv->on_configuration_changed); 25 | } 26 | 27 | wf::output_workarea_manager_t::~output_workarea_manager_t() = default; 28 | 29 | wf::geometry_t wf::output_workarea_manager_t::get_workarea() 30 | { 31 | return priv->current_workarea; 32 | } 33 | 34 | void wf::output_workarea_manager_t::add_reserved_area(anchored_area *area) 35 | { 36 | priv->anchors.push_back(area); 37 | } 38 | 39 | void wf::output_workarea_manager_t::remove_reserved_area(anchored_area *area) 40 | { 41 | auto it = std::remove(priv->anchors.begin(), priv->anchors.end(), area); 42 | priv->anchors.erase(it, priv->anchors.end()); 43 | } 44 | 45 | void wf::output_workarea_manager_t::reflow_reserved_areas() 46 | { 47 | auto old_workarea = priv->current_workarea; 48 | 49 | priv->current_workarea = priv->output->get_relative_geometry(); 50 | for (auto a : priv->anchors) 51 | { 52 | if (a->reflowed) 53 | { 54 | a->reflowed(priv->current_workarea); 55 | } 56 | 57 | switch (a->edge) 58 | { 59 | case ANCHORED_EDGE_TOP: 60 | priv->current_workarea.y += a->reserved_size; 61 | 62 | // fallthrough 63 | case ANCHORED_EDGE_BOTTOM: 64 | priv->current_workarea.height -= a->reserved_size; 65 | break; 66 | 67 | case ANCHORED_EDGE_LEFT: 68 | priv->current_workarea.x += a->reserved_size; 69 | 70 | // fallthrough 71 | case ANCHORED_EDGE_RIGHT: 72 | priv->current_workarea.width -= a->reserved_size; 73 | break; 74 | } 75 | } 76 | 77 | wf::workarea_changed_signal data; 78 | data.output = priv->output; 79 | data.old_workarea = old_workarea; 80 | data.new_workarea = priv->current_workarea; 81 | 82 | if (data.old_workarea != data.new_workarea) 83 | { 84 | priv->output->emit(&data); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/pch/pch.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "src/core/core-impl.hpp" 26 | #include "src/view/view-impl.hpp" 27 | -------------------------------------------------------------------------------- /src/version/git-branch.cpp.in: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace wf 4 | { 5 | namespace version 6 | { 7 | std::string git_branch = "@GIT_BRANCH@"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/version/git-commit.cpp.in: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace wf 4 | { 5 | namespace version 6 | { 7 | std::string git_commit = "@GIT_COMMIT@"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/view/layer-shell/layer-shell-node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/geometry.hpp" 4 | #include "wayfire/signal-provider.hpp" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace wf 11 | { 12 | /** 13 | * A surface root node for toplevel views. 14 | */ 15 | class layer_shell_node_t : public wf::scene::translation_node_t, 16 | public scene::zero_copy_texturable_node_t, public scene::opaque_region_node_t, public view_node_tag_t 17 | { 18 | public: 19 | layer_shell_node_t(wayfire_view view); 20 | 21 | wf::keyboard_focus_node_t keyboard_refocus(wf::output_t *output) override; 22 | keyboard_interaction_t& keyboard_interaction() override; 23 | std::string stringify() const override; 24 | 25 | void gen_render_instances(std::vector& instances, 26 | scene::damage_callback push_damage, wf::output_t *output) override; 27 | 28 | std::optional to_texture() const override; 29 | wf::region_t get_opaque_region() const override; 30 | 31 | protected: 32 | std::weak_ptr _view; 33 | std::unique_ptr kb_interaction; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /src/view/toplevel-node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/geometry.hpp" 4 | #include "wayfire/signal-provider.hpp" 5 | #include "wayfire/toplevel-view.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace wf 12 | { 13 | /** 14 | * A surface root node for toplevel views. 15 | */ 16 | class toplevel_view_node_t : public wf::scene::translation_node_t, 17 | public scene::zero_copy_texturable_node_t, public scene::opaque_region_node_t, public view_node_tag_t 18 | { 19 | public: 20 | toplevel_view_node_t(wayfire_toplevel_view view); 21 | 22 | wf::keyboard_focus_node_t keyboard_refocus(wf::output_t *output) override; 23 | keyboard_interaction_t& keyboard_interaction() override; 24 | std::string stringify() const override; 25 | 26 | void gen_render_instances(std::vector& instances, 27 | scene::damage_callback push_damage, wf::output_t *output) override; 28 | 29 | std::optional to_texture() const override; 30 | wf::region_t get_opaque_region() const override; 31 | 32 | protected: 33 | std::weak_ptr _view; 34 | std::unique_ptr kb_interaction; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/view/wlr-surface-touch-interaction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../core/core-impl.hpp" 3 | #include "../core/seat/seat-impl.hpp" 4 | #include "view-impl.hpp" 5 | #include "wayfire/unstable/wlr-surface-node.hpp" 6 | #include "wayfire/geometry.hpp" 7 | 8 | namespace wf 9 | { 10 | class wlr_surface_touch_interaction_t final : public wf::touch_interaction_t 11 | { 12 | wlr_surface *surface; 13 | 14 | public: 15 | wlr_surface_touch_interaction_t(wlr_surface *surface) 16 | { 17 | this->surface = surface; 18 | } 19 | 20 | void handle_touch_down(uint32_t time_ms, int finger_id, 21 | wf::pointf_t local) override 22 | { 23 | auto& seat = wf::get_core_impl().seat; 24 | seat->priv->last_press_release_serial = 25 | wlr_seat_touch_notify_down(seat->seat, surface, time_ms, finger_id, local.x, local.y); 26 | 27 | if (!seat->priv->drag_active) 28 | { 29 | wf::xwayland_bring_to_front(surface); 30 | } 31 | } 32 | 33 | void handle_touch_up(uint32_t time_ms, int finger_id, wf::pointf_t) override 34 | { 35 | auto& seat = wf::get_core_impl().seat; 36 | wlr_seat_touch_notify_up(seat->seat, time_ms, finger_id); 37 | // FIXME: wlroots does not give us the serial for touch up yet, so we just reset it to something 38 | // invalid. 39 | seat->priv->last_press_release_serial = 0; 40 | } 41 | 42 | void handle_touch_motion(uint32_t time_ms, int finger_id, 43 | wf::pointf_t local) override 44 | { 45 | auto& seat = wf::get_core_impl().seat; 46 | if (seat->priv->drag_active) 47 | { 48 | auto gc = wf::get_core().get_touch_position(finger_id); 49 | auto node = wf::get_core().scene()->find_node_at(gc); 50 | auto snode = node ? dynamic_cast(node->node.get()) : nullptr; 51 | if (snode && snode->get_surface()) 52 | { 53 | wlr_seat_touch_point_focus(seat->seat, snode->get_surface(), time_ms, finger_id, 54 | node->local_coords.x, node->local_coords.y); 55 | wlr_seat_touch_notify_motion(seat->seat, time_ms, finger_id, 56 | node->local_coords.x, node->local_coords.y); 57 | } else 58 | { 59 | wlr_seat_touch_point_clear_focus(seat->seat, time_ms, finger_id); 60 | } 61 | 62 | return; 63 | } 64 | 65 | wlr_seat_touch_notify_motion(seat->seat, time_ms, finger_id, local.x, local.y); 66 | } 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /src/view/xdg-shell/xdg-toplevel-view.hpp: -------------------------------------------------------------------------------- 1 | #include "view/toplevel-node.hpp" 2 | #include "wayfire/geometry.hpp" 3 | #include 4 | #include 5 | #include "wayfire/unstable/wlr-surface-controller.hpp" 6 | #include "wayfire/unstable/wlr-surface-node.hpp" 7 | #include 8 | 9 | #include 10 | #include "wayfire/toplevel.hpp" 11 | #include "wayfire/util.hpp" 12 | #include "xdg-toplevel.hpp" 13 | 14 | namespace wf 15 | { 16 | /** 17 | * An implementation of view_interface_t for xdg-shell toplevels. 18 | */ 19 | class xdg_toplevel_view_t : public xdg_toplevel_view_base_t, public wf::toplevel_view_interface_t 20 | { 21 | public: 22 | static std::shared_ptr create(wlr_xdg_toplevel *toplevel); 23 | 24 | void request_native_size() override; 25 | void set_activated(bool active) override; 26 | bool should_be_decorated() override; 27 | void set_decoration_mode(bool use_csd); 28 | bool is_mapped() const override; 29 | 30 | // start the map transaction 31 | void start_map_tx(); 32 | // start the unmap transaction 33 | void start_unmap_tx(); 34 | 35 | private: 36 | friend class wf::tracking_allocator_t; 37 | xdg_toplevel_view_t(wlr_xdg_toplevel *tlvl); 38 | bool has_client_decoration = true; 39 | wf::wl_listener_wrapper on_request_move, on_request_resize, on_request_minimize, on_request_maximize, 40 | on_request_fullscreen, on_set_parent, on_show_window_menu; 41 | 42 | std::shared_ptr surface_root_node; 43 | 44 | // A reference to 'this' used while unmapping, to ensure that the view lives until unmap happens. 45 | std::shared_ptr _self_ref; 46 | 47 | std::shared_ptr wtoplevel; 48 | wf::signal::connection_t on_toplevel_applied; 49 | 50 | void map() override; 51 | void destroy() override; 52 | void handle_toplevel_state_changed(toplevel_state_t old_state); 53 | }; 54 | 55 | void default_handle_new_xdg_toplevel(wlr_xdg_toplevel *toplevel); 56 | } 57 | -------------------------------------------------------------------------------- /src/view/xdg-shell/xdg-toplevel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "wayfire/geometry.hpp" 4 | #include "wayfire/util.hpp" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace wf 11 | { 12 | /** 13 | * A signal emitted on the xdg_toplevel after the committed state is applied. 14 | */ 15 | struct xdg_toplevel_applied_state_signal 16 | { 17 | toplevel_state_t old_state; 18 | }; 19 | 20 | class xdg_toplevel_t : public toplevel_t, public std::enable_shared_from_this 21 | { 22 | public: 23 | xdg_toplevel_t(wlr_xdg_toplevel *toplevel, 24 | std::shared_ptr surface); 25 | void commit() override; 26 | void apply() override; 27 | wf::geometry_t calculate_base_geometry(); 28 | void request_native_size(); 29 | 30 | wf::dimensions_t get_min_size() override; 31 | wf::dimensions_t get_max_size() override; 32 | 33 | private: 34 | std::shared_ptr main_surface; 35 | scene::surface_state_t pending_state; 36 | 37 | void apply_pending_state(); 38 | wf::dimensions_t get_current_wlr_toplevel_size(); 39 | 40 | wf::wl_listener_wrapper on_surface_commit; 41 | wf::wl_listener_wrapper on_toplevel_destroy; 42 | wlr_xdg_toplevel *toplevel; 43 | wf::point_t wm_offset = {0, 0}; 44 | 45 | void handle_surface_commit(); 46 | uint32_t target_configure = 0; 47 | 48 | void emit_ready(); 49 | bool pending_ready = false; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /src/view/xwayland/xwayland-helpers.cpp: -------------------------------------------------------------------------------- 1 | #include "xwayland-helpers.hpp" 2 | 3 | #if WF_HAS_XWAYLAND 4 | 5 | std::optional wf::xw::load_atom(xcb_connection_t *connection, const std::string& name) 6 | { 7 | std::optional result; 8 | auto cookie = xcb_intern_atom(connection, 0, name.length(), name.c_str()); 9 | xcb_generic_error_t *error = NULL; 10 | xcb_intern_atom_reply_t *reply; 11 | reply = xcb_intern_atom_reply(connection, cookie, &error); 12 | 13 | if (!error && reply) 14 | { 15 | result = reply->atom; 16 | } 17 | 18 | free(reply); 19 | free(error); 20 | return result; 21 | } 22 | 23 | bool wf::xw::load_basic_atoms(const char *server_name) 24 | { 25 | auto connection = xcb_connect(server_name, NULL); 26 | if (!connection || xcb_connection_has_error(connection)) 27 | { 28 | return false; 29 | } 30 | 31 | _NET_WM_WINDOW_TYPE_NORMAL = load_atom(connection, "_NET_WM_WINDOW_TYPE_NORMAL").value_or(-1); 32 | _NET_WM_WINDOW_TYPE_DIALOG = load_atom(connection, "_NET_WM_WINDOW_TYPE_DIALOG").value_or(-1); 33 | _NET_WM_WINDOW_TYPE_SPLASH = load_atom(connection, "_NET_WM_WINDOW_TYPE_SPLASH").value_or(-1); 34 | _NET_WM_WINDOW_TYPE_UTILITY = load_atom(connection, "_NET_WM_WINDOW_TYPE_UTILITY").value_or(-1); 35 | _NET_WM_WINDOW_TYPE_DND = load_atom(connection, "_NET_WM_WINDOW_TYPE_DND").value_or(-1); 36 | xcb_disconnect(connection); 37 | return true; 38 | } 39 | 40 | bool wf::xw::has_type(wlr_xwayland_surface *xw, xcb_atom_t type) 41 | { 42 | for (size_t i = 0; i < xw->window_type_len; i++) 43 | { 44 | if (xw->window_type[i] == type) 45 | { 46 | return true; 47 | } 48 | } 49 | 50 | return false; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/view/xwayland/xwayland-helpers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include 5 | #include 6 | 7 | #if WF_HAS_XWAYLAND 8 | 9 | #include 10 | #include 11 | 12 | namespace wf 13 | { 14 | namespace xw 15 | { 16 | enum class view_type 17 | { 18 | NORMAL, 19 | UNMANAGED, 20 | DND, 21 | }; 22 | 23 | extern xcb_atom_t _NET_WM_WINDOW_TYPE_NORMAL; 24 | extern xcb_atom_t _NET_WM_WINDOW_TYPE_DIALOG; 25 | extern xcb_atom_t _NET_WM_WINDOW_TYPE_SPLASH; 26 | extern xcb_atom_t _NET_WM_WINDOW_TYPE_UTILITY; 27 | extern xcb_atom_t _NET_WM_WINDOW_TYPE_DND; 28 | 29 | std::optional load_atom(xcb_connection_t *connection, const std::string& name); 30 | bool load_basic_atoms(const char *server_name); 31 | bool has_type(wlr_xwayland_surface *xw, xcb_atom_t type); 32 | } 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/view/xwayland/xwayland-toplevel-view.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lilydjwg/wayfire/9e7ad2bbdca011476da51f3a247f16680bf467bf/src/view/xwayland/xwayland-toplevel-view.cpp -------------------------------------------------------------------------------- /src/view/xwayland/xwayland-toplevel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include "wayfire/geometry.hpp" 5 | #include "wayfire/util.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if WF_HAS_XWAYLAND 12 | 13 | namespace wf 14 | { 15 | namespace xw 16 | { 17 | /** 18 | * A signal emitted on the xwayland_toplevel after the committed state is applied. 19 | */ 20 | struct xwayland_toplevel_applied_state_signal 21 | { 22 | toplevel_state_t old_state; 23 | }; 24 | 25 | class xwayland_toplevel_t : public wf::toplevel_t, public std::enable_shared_from_this 26 | { 27 | public: 28 | xwayland_toplevel_t(wlr_xwayland_surface *xw); 29 | void commit() override; 30 | void apply() override; 31 | 32 | wf::dimensions_t get_min_size() override; 33 | wf::dimensions_t get_max_size() override; 34 | 35 | void set_main_surface(std::shared_ptr main_surface); 36 | void set_output_offset(wf::point_t output_offset); 37 | 38 | wf::geometry_t calculate_base_geometry(); 39 | 40 | void request_native_size(); 41 | 42 | private: 43 | std::shared_ptr main_surface; 44 | scene::surface_state_t pending_state; 45 | 46 | void apply_pending_state(); 47 | wf::dimensions_t get_current_xw_size(); 48 | 49 | wf::wl_listener_wrapper on_surface_commit; 50 | wf::wl_listener_wrapper on_xw_destroy; 51 | wf::wl_idle_call idle_ready; 52 | 53 | wlr_xwayland_surface *xw; 54 | wf::point_t output_offset = {0, 0}; 55 | void handle_surface_commit(); 56 | 57 | void reconfigure_xwayland_surface(); 58 | void emit_ready(); 59 | bool pending_ready = false; 60 | }; 61 | } 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/view/xwayland/xwayland-view-base.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "wayfire/util.hpp" 10 | #include "xwayland-helpers.hpp" 11 | #include 12 | #include 13 | #include 14 | 15 | #if WF_HAS_XWAYLAND 16 | 17 | class wayfire_xwayland_view_internal_base : public wf::xwayland_view_base_t 18 | { 19 | protected: 20 | wf::wl_listener_wrapper on_configure; 21 | wf::wl_listener_wrapper on_surface_commit; 22 | 23 | /** The geometry requested by the client */ 24 | bool self_positioned = false; 25 | 26 | public: 27 | wayfire_xwayland_view_internal_base(wlr_xwayland_surface *xww) : xwayland_view_base_t(xww) 28 | {} 29 | 30 | /** 31 | * Get the current implementation type. 32 | */ 33 | virtual wf::xw::view_type get_current_impl_type() const = 0; 34 | 35 | virtual ~wayfire_xwayland_view_internal_base() = default; 36 | 37 | void _initialize() 38 | { 39 | on_configure.set_callback([&] (void *data) 40 | { 41 | handle_client_configure((wlr_xwayland_surface_configure_event*)data); 42 | }); 43 | 44 | on_configure.connect(&xw->events.request_configure); 45 | } 46 | 47 | virtual void handle_client_configure(wlr_xwayland_surface_configure_event *ev) 48 | {} 49 | 50 | virtual void handle_dissociate() 51 | {} 52 | 53 | void destroy() override 54 | { 55 | wf::xwayland_view_base_t::destroy(); 56 | on_configure.disconnect(); 57 | } 58 | 59 | virtual void handle_map_request(wlr_surface *surface) = 0; 60 | virtual void handle_unmap_request() = 0; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/wl-listener-wrapper.tpp: -------------------------------------------------------------------------------- 1 | /** Implementation for wf::wl_listener_wrapper */ 2 | #include 3 | 4 | namespace wf 5 | { 6 | static void handle_wrapped_listener(wl_listener *listener, void *data) 7 | { 8 | wf::wl_listener_wrapper::wrapper *wrap = 9 | wl_container_of(listener, wrap, listener); 10 | wrap->self->emit(data); 11 | } 12 | 13 | wl_listener_wrapper::wl_listener_wrapper() 14 | { 15 | _wrap.self = this; 16 | _wrap.listener.notify = handle_wrapped_listener; 17 | wl_list_init(&_wrap.listener.link); 18 | } 19 | 20 | wl_listener_wrapper::~wl_listener_wrapper() 21 | { 22 | disconnect(); 23 | } 24 | 25 | void wl_listener_wrapper::set_callback(callback_t _call) 26 | { 27 | this->call = _call; 28 | } 29 | 30 | bool wl_listener_wrapper::connect(wl_signal *signal) 31 | { 32 | if (is_connected()) 33 | { 34 | return false; 35 | } 36 | 37 | wl_signal_add(signal, &_wrap.listener); 38 | 39 | return true; 40 | } 41 | 42 | void wl_listener_wrapper::disconnect() 43 | { 44 | wl_list_remove(&_wrap.listener.link); 45 | wl_list_init(&_wrap.listener.link); 46 | } 47 | 48 | bool wl_listener_wrapper::is_connected() const 49 | { 50 | return !wl_list_empty(&_wrap.listener.link); 51 | } 52 | 53 | void wl_listener_wrapper::emit(void *data) 54 | { 55 | if (this->call) 56 | { 57 | this->call(data); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/geometry/geometry_test.cpp: -------------------------------------------------------------------------------- 1 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 2 | #include 3 | 4 | #include 5 | 6 | TEST_CASE("Point addition") 7 | { 8 | wf::point_t a = {1, 2}; 9 | wf::point_t b = {3, 4}; 10 | 11 | using namespace wf; 12 | REQUIRE_EQ(a + b, wf::point_t{4, 6}); 13 | } 14 | -------------------------------------------------------------------------------- /test/geometry/meson.build: -------------------------------------------------------------------------------- 1 | geometry_test = executable( 2 | 'geometry_test', 3 | 'geometry_test.cpp', 4 | dependencies: libwayfire, 5 | install: false) 6 | test('Geometry test', geometry_test) 7 | -------------------------------------------------------------------------------- /test/meson.build: -------------------------------------------------------------------------------- 1 | subdir('geometry') 2 | subdir('txn') 3 | subdir('misc') 4 | -------------------------------------------------------------------------------- /test/misc/meson.build: -------------------------------------------------------------------------------- 1 | tracking_allocator = executable( 2 | 'tracking_allocator', 3 | 'tracking-allocator.cpp', 4 | dependencies: libwayfire, 5 | install: false) 6 | test('Tracking factory test', tracking_allocator) 7 | 8 | safe_list = executable( 9 | 'safe_list', 10 | 'safe-list-test.cpp', 11 | include_directories: wayfire_api_inc, 12 | dependencies: doctest, 13 | install: false) 14 | test('Safe list test', safe_list) 15 | -------------------------------------------------------------------------------- /test/misc/safe-list-test.cpp: -------------------------------------------------------------------------------- 1 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 2 | #include 3 | 4 | #include 5 | 6 | TEST_CASE("Safe-list basics") 7 | { 8 | wf::safe_list_t list; 9 | 10 | list.push_back(5); 11 | list.push_back(6); 12 | REQUIRE(list.size() == 2); 13 | 14 | list.for_each([x = 0] (int i) mutable 15 | { 16 | if (x == 0) 17 | { 18 | REQUIRE(i == 5); 19 | } 20 | 21 | if (x == 1) 22 | { 23 | REQUIRE(i == 6); 24 | } 25 | 26 | REQUIRE(x <= 1); 27 | x++; 28 | }); 29 | 30 | list.remove_if([] (int i) { return i == 5; }); 31 | REQUIRE(list.size() == 1); 32 | 33 | list.for_each([x = 0] (int i) mutable 34 | { 35 | if (x == 0) 36 | { 37 | REQUIRE(i == 6); 38 | } 39 | 40 | REQUIRE(x <= 0); 41 | x++; 42 | }); 43 | } 44 | 45 | TEST_CASE("safe-list remove self") 46 | { 47 | using cb = std::function; 48 | wf::safe_list_t list; 49 | 50 | cb self; 51 | list.push_back(&self); 52 | list.for_each_reverse([&] (cb *c) 53 | { 54 | REQUIRE(c == &self); 55 | list.remove_all(c); 56 | }); 57 | } 58 | 59 | TEST_CASE("safe-list remove next") 60 | { 61 | using cb = std::function; 62 | wf::safe_list_t list; 63 | 64 | cb self, next; 65 | list.push_back(&self); 66 | list.push_back(&next); 67 | 68 | int calls = 0; 69 | list.for_each([&] (cb *c) 70 | { 71 | calls++; 72 | REQUIRE(calls <= 1); 73 | REQUIRE(c == &self); 74 | list.remove_all(&next); 75 | REQUIRE(list.back() == &self); 76 | }); 77 | } 78 | 79 | TEST_CASE("safe-list push next") 80 | { 81 | using cb = std::function; 82 | wf::safe_list_t list; 83 | 84 | cb self, next; 85 | list.push_back(&self); 86 | 87 | int calls = 0; 88 | list.for_each([&] (cb *c) 89 | { 90 | calls++; 91 | REQUIRE(calls <= 1); 92 | list.push_back(&next); 93 | }); 94 | 95 | REQUIRE(list.size() == 2); 96 | } 97 | -------------------------------------------------------------------------------- /test/misc/tracking-allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "wayfire/nonstd/tracking-allocator.hpp" 2 | #include "wayfire/signal-provider.hpp" 3 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 4 | #include 5 | 6 | class base_t : public wf::signal::provider_t 7 | { 8 | public: 9 | static int destroyed; 10 | virtual ~base_t() 11 | { 12 | ++destroyed; 13 | } 14 | }; 15 | 16 | class derived_t : public base_t 17 | { 18 | public: 19 | derived_t(int useless) 20 | { 21 | (void)useless; 22 | } 23 | 24 | virtual ~derived_t() = default; 25 | }; 26 | 27 | int base_t::destroyed = 0; 28 | 29 | 30 | TEST_CASE("Misc factory works") 31 | { 32 | auto& allocator = wf::tracking_allocator_t::get(); 33 | REQUIRE(&allocator == &wf::tracking_allocator_t::get()); 34 | REQUIRE((void*)&allocator != (void*)&wf::tracking_allocator_t::get()); 35 | 36 | auto obj_a = allocator.allocate(); 37 | REQUIRE(allocator.get_all().size() == 1); 38 | 39 | int destruct_events = 0; 40 | wf::signal::connection_t> on_destroy; 41 | 42 | { 43 | auto obj_b = allocator.allocate(5); 44 | on_destroy = [&destruct_events, expected = obj_b.get()] (wf::destruct_signal *ev) 45 | { 46 | REQUIRE(ev->object == expected); 47 | ++destruct_events; 48 | }; 49 | 50 | obj_b->connect(&on_destroy); 51 | REQUIRE(allocator.get_all().size() == 2); 52 | } 53 | 54 | REQUIRE(destruct_events == 1); 55 | REQUIRE(allocator.get_all().size() == 1); 56 | } 57 | -------------------------------------------------------------------------------- /test/txn/meson.build: -------------------------------------------------------------------------------- 1 | txn_test = executable( 2 | 'transaction-test', 3 | 'transaction-test.cpp', 4 | dependencies: libwayfire, 5 | install: false) 6 | test('Test transaction basic functionality', txn_test) 7 | 8 | txn_manager_test = executable( 9 | 'transaction-manager-test', 10 | 'transaction-manager-test.cpp', 11 | dependencies: libwayfire, 12 | install: false) 13 | test('Test transaction manager functionality', txn_manager_test) 14 | -------------------------------------------------------------------------------- /test/txn/transaction-test-object.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class txn_test_object_t : public wf::txn::transaction_object_t 7 | { 8 | public: 9 | int number_committed = 0; 10 | int number_applied = 0; 11 | std::function apply_callback; 12 | 13 | bool autoready; 14 | 15 | txn_test_object_t(bool autocommit) 16 | { 17 | this->autoready = autocommit; 18 | } 19 | 20 | void commit() override 21 | { 22 | number_committed++; 23 | if (autoready) 24 | { 25 | emit_ready(); 26 | } 27 | } 28 | 29 | void apply() override 30 | { 31 | number_applied++; 32 | if (apply_callback) 33 | { 34 | apply_callback(); 35 | } 36 | } 37 | 38 | void emit_ready() 39 | { 40 | wf::txn::object_ready_signal ev; 41 | ev.self = this; 42 | this->emit(&ev); 43 | } 44 | }; 45 | 46 | inline void setup_wayfire_debugging_state() 47 | { 48 | wf::log::initialize_logging(std::cout, wf::log::LOG_LEVEL_DEBUG, wf::log::LOG_COLOR_MODE_ON); 49 | wf::log::enabled_categories.set((size_t)wf::log::logging_category::TXN, 1); 50 | wf::log::enabled_categories.set((size_t)wf::log::logging_category::TXNI, 1); 51 | // Set wl_idle_call's loop to a fake loop so that the test doesn't crash when using signals which in turn 52 | // use safe_list_t which needs wl_idle_calls. 53 | wf::wl_idle_call::loop = wl_event_loop_create(); 54 | } 55 | -------------------------------------------------------------------------------- /wayfire.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Wayfire 3 | Exec=wayfire 4 | TryExec=wayfire 5 | Icon= 6 | Type=Application 7 | DesktopNames=Wayfire;wlroots 8 | --------------------------------------------------------------------------------