Submitted by: Zeckma Date: 2026-08-01 Initial Package Version: 0.10.0 Origin: Diff from 0.10.0 tarball to HEAD of https://github.com/WayfireWM/wayfire-plugins-extra Upstream Status: Upstream Description: Brings 0.10.0 to HEAD as there were multiple changes to the plugin API over time. All of these changes should land in 0.11.0 anyhow. diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/meson.build wayfire-plugins-extra/locale/meson.build --- wayfire-plugins-extra-0.10.0/locale/meson.build 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/meson.build 2026-08-01 16:00:35.432705142 -0600 @@ -0,0 +1,19 @@ +share_dir = join_paths(get_option('prefix'), 'share') +wayfire_locale_dir = join_paths(share_dir, 'locale') + +fs = import('fs') + +po_files_raw = run_command('find', '.', '-name', '*.po', check : true).stdout().strip().split('\n') +po_files = files(po_files_raw) + +foreach po_file : po_files + language = fs.name(fs.parent(fs.parent(po_file))) + install_path = join_paths(wayfire_locale_dir, language, 'LC_MESSAGES') + mo_dir = join_paths(meson.project_build_root(), 'locale', language, 'LC_MESSAGES') + mo_file = fs.stem(po_file) + '.mo' + mo_path = join_paths(mo_dir, mo_file) + run_command('mkdir', '-p', mo_dir, check : true) + run_command('msgfmt', po_file, '-o', mo_path, check : true) + install_data(mo_path, install_dir : install_path) +endforeach + diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-annotate.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-annotate.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-annotate.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-annotate.po 2026-08-01 16:00:35.432842092 -0600 @@ -0,0 +1,102 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 08:00+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:4 +msgid "Annotate" +msgstr "Adnotare" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:5 +msgid "Draw on the output." +msgstr "Desenează pe ecran." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:8 +msgid "Draw" +msgstr "Desenare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:9 +msgid "Begin drawing on workspace." +msgstr "Începe desenarea pe birou." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:13 +msgid "Clear Workspace" +msgstr "Ștergere birou" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:14 +msgid "Clear workspace." +msgstr "Șterge biroul." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:18 +msgid "Stroke Color" +msgstr "Culoarea conturului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:19 +msgid "Color used for drawing." +msgstr "Culoarea folosită pentru desen." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:23 +msgid "Drawing Method" +msgstr "Metoda desenului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:24 +msgid "Method used for drawing." +msgstr "Metoda folosită pentru desen." + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:28 +msgid "Free Draw" +msgstr "Desen liber" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:32 +msgid "Line" +msgstr "Linie" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:36 +msgid "Rectangle" +msgstr "Dreptunghi" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:40 +msgid "Circle" +msgstr "Cerc" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:44 +msgid "Line Width" +msgstr "Grosimea liniei" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:45 +msgid "Line width used for drawing." +msgstr "Grosimea liniei folosite pentru desen." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:51 +msgid "Draw Shapes From Center" +msgstr "Desenează formele din centru" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/annotate.xml:52 +msgid "Draw shapes from center of drag point." +msgstr "Desenează formele centrate pe punctul tragerii." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-autorotate-iio.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-autorotate-iio.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-autorotate-iio.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-autorotate-iio.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,42 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 08:54+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:4 +msgid "Auto Rotate" +msgstr "Rotire automată" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:7 +msgid "Lock Rotation" +msgstr "Blocare rotație" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:11 +msgid "Rotate Up" +msgstr "Rotire în sus" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:15 +msgid "Rotate Left" +msgstr "Rotire la stânga" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:19 +msgid "Rotate Down" +msgstr "Rotire în jos" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/autorotate-iio.xml:23 +msgid "Rotate Right" +msgstr "Rotire la dreapta" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-bench.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-bench.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-bench.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-bench.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,87 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 08:56+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:4 +msgid "Bench" +msgstr "Probă de performanță" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:5 +msgid "Display fps on each output." +msgstr "Afișează numărul de cadre pe secundă pe fiecare ecran." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:8 +msgid "Average frames" +msgstr "Cadre pentru medie" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:9 +msgid "How many frames to average to get the FPS value." +msgstr "Pe câte cadre să se facă media pentru a obține valoarea frecvenței cadrelor." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:14 +msgid "Position" +msgstr "Poziție" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:15 +msgid "Position of rendering." +msgstr "Poziția desenării." + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:19 +msgid "Top Left" +msgstr "Stânga-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:23 +msgid "Top Center" +msgstr "Centru-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:27 +msgid "Top Right" +msgstr "Dreapta-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:31 +msgid "Center Left" +msgstr "Stânga-centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:35 +msgid "Center" +msgstr "Centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:39 +msgid "Center Right" +msgstr "Dreapta-centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:43 +msgid "Bottom Left" +msgstr "Stânga-jos" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:47 +msgid "Bottom Center" +msgstr "Centru-jos" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/bench.xml:51 +msgid "Bottom Right" +msgstr "Dreapta-jos" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-crosshair.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-crosshair.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-crosshair.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-crosshair.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,42 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 08:58+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:4 +msgid "Crosshair" +msgstr "Reticulă" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:5 +msgid "Render fullscreen mouse crosshair" +msgstr "Desenează reticula mausului pe tot ecranul." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:8 +msgid "Line Width" +msgstr "Grosimea liniei" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:9 +msgid "Line width of crosshair" +msgstr "Grosimea liniei reticulei." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:14 +msgid "Line Color" +msgstr "Culoarea liniei" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/crosshair.xml:15 +msgid "Color used for rendering crosshair" +msgstr "Culoarea folosită pentru a desena reticula." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-extra-animations.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-extra-animations.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-extra-animations.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-extra-animations.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,207 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 12:09+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:4 +msgid "Extra Animations" +msgstr "Animații suplimentare" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:5 +msgid "Extra animations to extend animate plugin" +msgstr "Animații care suplimentează modulul de animații" + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:8 +msgid "Blinds Settings" +msgstr "Opțiuni jaluzele" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:10 +msgid "Blinds duration" +msgstr "Durata jaluzelelor" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:11 +msgid "Sets the duration for the blinds animation in milliseconds." +msgstr "Stabilește durata pentru animația de jaluzele, în milisecunde." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:15 +msgid "Blinds strip height" +msgstr "Înălțimea fâșiei de jaluzele" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:16 +msgid "Height of each blinds strip in pixels." +msgstr "Înălțimea fiecărei fâșii a jaluzelelor, în pixeli." + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:22 +msgid "Helix Settings" +msgstr "Opțiuni helix" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:24 +msgid "Helix duration" +msgstr "Durata helixului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:25 +msgid "Sets the duration for the helix animation in milliseconds." +msgstr "Stabilește durata pentru animația helix, în milisecunde." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:29 +msgid "Helix rotations" +msgstr "Rotații helix" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:30 +msgid "Number of rotations for the helix animation." +msgstr "Numărul de rotații pentru animația helix." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:35 +msgid "Helix strip height" +msgstr "Înălțimea fâșiei de helix" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:36 +msgid "Height of each helix strip in pixels." +msgstr "Înălțimea fiecărei fâșii a helixului, în pixeli." + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:42 +msgid "Shatter Settings" +msgstr "Opțiuni spargere" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:44 +msgid "Shatter duration" +msgstr "Durata spargerii" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:45 +msgid "Sets the duration for the shatter animation in milliseconds." +msgstr "Stabilește durata pentru animația de spargere, în milisecunde." + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:50 +msgid "Vortex Settings" +msgstr "Opțiuni vârtej" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:52 +msgid "Vortex duration" +msgstr "Durata vârtejului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:53 +msgid "Sets the duration for the vortex animation in milliseconds." +msgstr "Stabilește durata animației de vârtej, în milisecunde." + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:58 +msgid "Melt Settings" +msgstr "Opțiuni topire" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:60 +msgid "Melt duration" +msgstr "Durata topirii" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:61 +msgid "Sets the duration for the melt animation in milliseconds." +msgstr "Stabilește durata animației de topire, în milisecunde." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:65 +msgid "Melt distortion factor" +msgstr "Factor de deformare pentru topire" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:66 +msgid "Distortion factor for melt animation." +msgstr "Stabilește factorul de deformare folosit la animația de topire." + +#. (itstool) path: group/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:72 +msgid "Dodge Settings" +msgstr "Opțiuni suprapunere" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:74 +msgid "Enable Dodge" +msgstr "Activează suprapunerea" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:75 +msgid "Enables the Dodge focus animation." +msgstr "Activează animația de suprapunere la focalizare." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:79 +msgid "Duration" +msgstr "Durata" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:80 +msgid "Sets the animation duration in milliseconds." +msgstr "Stabilește durata animației, în milisecunde." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:84 +msgid "Rotate" +msgstr "Rotire" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:85 +msgid "Rotate windows during animation." +msgstr "Rotește ferestrele în timpul animației." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:89 +msgid "Zoom" +msgstr "Mărire" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:90 +msgid "Slightly increase zoom for the focusing window during animation." +msgstr "Mărește puțin fereastra ce se focalizează în animație." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:94 +msgid "Animation Direction" +msgstr "Direcția animației" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:95 +msgid "Sets the animation direction." +msgstr "Stabilește direcția animației." + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:98 +msgid "Cardinal" +msgstr "Cardinală" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:102 +msgid "Diagonal" +msgstr "Diagonală" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/extra-animations.xml:106 +msgid "Circular" +msgstr "Circulară" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-focus-change.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-focus-change.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-focus-change.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-focus-change.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,172 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 13:10+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:4 +msgid "Focus Change" +msgstr "Schimbare focalizare" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:7 +msgid "focus up" +msgstr "Focalizare în sus" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:8 +msgid "move focus to the closest window above" +msgstr "Mută focalizarea la cea mai apropiată fereastră de deasupra." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:12 +msgid "focus down" +msgstr "Focalizare în jos" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:13 +msgid "move focus to the closest window below" +msgstr "Mută focalizarea la cea mai apropiată fereastră de dedesubt." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:17 +msgid "focus right" +msgstr "Focalizare la dreapta" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:18 +msgid "move focus to the closest window to the right" +msgstr "Mută focalizarea la cea mai apropiată fereastră de la dreapta." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:22 +msgid "focus left" +msgstr "Focalizare la stânga" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:23 +msgid "move focus to the closest window to the left" +msgstr "Mută focalizarea la cea mai apropiată fereastră de la stânga." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:27 +msgid "upwards grace in pixels" +msgstr "Grație în sus în pixeli" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:28 +msgid "" +"add an amount of pixel upwards in which windows will be ignored. Can be " +"negative" +msgstr "" +"Adaugă pixeli în sus în care ferestrele vor fi ignorate. Poate fi negativ." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:32 +msgid "downwards grace in pixels" +msgstr "Grație în jos în pixeli" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:33 +msgid "" +"add an amount of pixel downwards in which windows will be ignored. Can be " +"negative" +msgstr "" +"Adaugă pixeli în jos în care ferestrele vor fi ignorate. Poate fi negativ." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:37 +msgid "rightwards grace in pixels" +msgstr "Grație în dreapta în pixeli" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:38 +msgid "" +"add an amount of pixel to the right in which windows will be ignored. Can be " +"negative" +msgstr "" +"Adaugă pixeli în dreapta în care ferestrele vor fi ignorate. Poate fi " +"negativ." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:42 +msgid "leftwards grace in pixels" +msgstr "Grație în stânga în pixeli" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:43 +msgid "" +"add an amount of pixel to the left in which windows will be ignored. Can be " +"negative" +msgstr "" +"Adaugă pixeli în stânga în care ferestrele vor fi ignorate. Poate fi negativ." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:47 +msgid "ignores output boundraries" +msgstr "Ignoră granițele ecranelor" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:48 +msgid "enables moving focus between different outputs" +msgstr "Permite mutarea focalizării între ecrane diferite." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:52 +msgid "ignores workspace boundraries" +msgstr "Ignoră granițele birourilor" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:53 +msgid "enables moving focus between workspaces on the same output" +msgstr "Permite mutarea focalizării între birouri de pe același ecran." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:57 +msgid "raise window on change" +msgstr "Ridică fereastra la schimbare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:58 +msgid "raise the newly focused window to the top" +msgstr "Mută fereastra nou focalizată deasupra." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:62 +msgid "scan height" +msgstr "Înălțime scanare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:63 +msgid "" +"the height of the bounding box used to scan for windows to the left or " +"right. If zero it will be the height of the view. If negative it will be the " +"height of the view subtracted by the value" +msgstr "" +"Înălțimea casetei care scanează ferestre în stânga sau în dreapta. Dacă este " +"0, va fi înălțimea ferestrei. Dacă este negativă, va fi înălțimea ferestrei " +"minus valoarea dată." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:67 +msgid "scan width" +msgstr "Lățime scanare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-change.xml:68 +msgid "" +"the width of the bounding box used to scan for window above or below. If " +"zero it will be the width of the view. If negative it will be the width of " +"the view subtracted by the value" +msgstr "" +"Lățimea casetei care scanează ferestre în sus sau în jos. Dacă este 0, va fi " +"lățimea ferestrei. Dacă este negativă, va fi lățimea ferestrei minus " +"valoarea dată." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-focus-steal-prevent.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-focus-steal-prevent.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-focus-steal-prevent.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-focus-steal-prevent.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,61 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 21:43+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:4 +msgid "Focus Stealing Prevention" +msgstr "Prevenirea furtului de focalizare" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:7 +msgid "The timeout (in ms) to prevent focus stealing" +msgstr "Timpul, în milisecunde, pentru care să se prevină furtul focalizării" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:8 +msgid "" +"A timer will be reset to the timeout (in ms) on every keystroke. If the " +"timer is active when another window would normally gain focus, the focus is " +"reset to the window that is accepting input." +msgstr "" +"Un cronometru va fi reînceput până la timpul stabilit (în milisecunde) la " +"fiecare batere a tastelor. Dacă cronometrul este activ când altă fereastră " +"ar deveni focalizată, focalizarea este restabilită la fereastra care " +"acceptă intrare." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:13 +msgid "Deny focus to views matching this criteria" +msgstr "Refuză focalizarea ferestrelor ce satisfac criteriile" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:14 +msgid "" +"If a view matches when mapped, focus is reset to the last view with focus." +msgstr "" +"Dacă o fereastră corespunde când i se alocă ecran, focalizarea este " +"restabilită la ultima fereastră focalizată." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:18 +msgid "Cancel focus stealing prevention on these keys" +msgstr "Anulează prevenirea furtului de focalizare la aceste taste" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/focus-steal-prevent.xml:19 +msgid "" +"Cancel focus stealing prevention when any of these keys are pressed. The " +"string consists of keycode names delimited by | character." +msgstr "" +"Anulează prevenirea furtului de focalizare când oricare dintre aceste taste " +"este apăsată. Șirul constă din coduri de taste delimitate de caracterul |." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-follow-focus.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-follow-focus.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-follow-focus.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-follow-focus.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,87 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 21:49+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:4 +msgid "Follow Focus" +msgstr "Urmărirea focalizării" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:7 +msgid "View focus follows mouse" +msgstr "Focalizarea ferestrelor urmărește mausul." + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:8 +msgid "" +"When the mouse pointer is moved, the view focus changes to the view under " +"the pointer." +msgstr "" +"Când se mișcă cursorul mausului, focalizarea se acordă ferestrei de sub " +"acesta." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:12 +msgid "Output focus follows mouse" +msgstr "Focalizarea ecranelor urmărește mausul." + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:13 +msgid "" +"When the mouse pointer is moved, the output focus changes to the output that " +"the pointer is currently on." +msgstr "" +"Când se mișcă cursorul mausului, focalizarea se acordă ecranului de sub " +"acesta." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:17 +msgid "Delay (in ms) before focus change will be triggered" +msgstr "Timp de așteptare (în ms) până se declanșează schimbarea focalizării" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:18 +msgid "" +"The delay in ms before the plugin will trigger a focus change after the " +"movement finished." +msgstr "" +"Timpul de așteptare, în milisecunde, înainte ca modulul să inițieze o " +"schimbare a focalizării după ce s-a terminat mișcarea." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:23 +msgid "Minimum cursor movement" +msgstr "Mișcarea minimă a cursorului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:24 +msgid "" +"The distance (x+y) the cursor should be moved at least before the plugin " +"gets activated" +msgstr "" +"Distanța minimă (x+y) pentru care să se miște cursorul înainte să se " +"activeze modului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:29 +msgid "Raise the focused view to the top" +msgstr "Ridică fereastra focalizată" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/follow-focus.xml:30 +msgid "" +"If disabled the focused view will only get keyboard focus, but will not be " +"raised to the top." +msgstr "" +"Dacă este dezactivată, fereastra focalizată va prelua doar focalizarea " +"tastaturii, dar nu va fi pusă deasupra." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-force-fullscreen.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-force-fullscreen.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-force-fullscreen.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-force-fullscreen.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,67 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:16+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:4 +msgid "Fullscreen Window" +msgstr "Fereastră pe ecran complet" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:7 +msgid "Key Toggle Fullscreen" +msgstr "Tastă pentru comutarea ecranului complet" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:11 +msgid "Preserve Aspect Ratio" +msgstr "Păstrează raportul de aspect" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:15 +msgid "Transparent Behind Views" +msgstr "Transparent în spatele ferestrelor" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:19 +msgid "Skew view width by multiplying by this factor" +msgstr "Întinde lățimea ferestrei înmulțind cu acest factor" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:25 +msgid "Skew view height by multiplying by this factor" +msgstr "Întinde înălțimea ferestrei înmulțind cu acest factor" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:31 +msgid "Constrain Mouse Pointer" +msgstr "Constrânge cursorul mausului" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:35 +msgid "Constraint Area" +msgstr "Zonă de constrângere" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:36 +msgid "If constrain pointer is enabled, constrain to this area." +msgstr "Dacă constrângerea cursorului este activată, constrânge la această zonă." + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:40 +msgid "View" +msgstr "Fereastră" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/force-fullscreen.xml:44 +msgid "Output" +msgstr "Ecran" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-ghost.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-ghost.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-ghost.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-ghost.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,37 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:22+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/ghost.xml:4 +msgid "Ghost Windows" +msgstr "Ferestre fantomă" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/ghost.xml:7 +msgid "Ghosted Windows" +msgstr "Ferestre fantomă" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/ghost.xml:8 +msgid "Automatically sets the matched windows to be click-through." +msgstr "Face automat ca clicul să treacă prin ferestrele corespunzătoare." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/ghost.xml:12 +msgid "Toggle Ghost Window" +msgstr "Comută fereastră fantomă" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/ghost.xml:13 +msgid "Toggles the active window being click-through to whatever is below." +msgstr "Comută dacă clicul în fereastra activă este transmis la fereastra de dedesubt." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-hide-cursor.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-hide-cursor.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-hide-cursor.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-hide-cursor.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,46 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:24+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:4 +msgid "Hide Cursor" +msgstr "Ascundere cursor" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:5 +msgid "A plugin that allows to toggle hide mouse cursor." +msgstr "Un modul care permite comutarea vizibilității cursorului mausului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:8 +msgid "Toggle" +msgstr "Comutare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:9 +msgid "Toggles hide mouse cursor." +msgstr "Comută vizibilitatea cursorului mausului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:13 +msgid "Delay (in ms) before cursor will be hidden" +msgstr "Timp de așteptare (în ms) până se ascunde cursorul" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/hide-cursor.xml:14 +msgid "" +"The delay in ms before the plugin will hide the cursor. The cursor is shown " +"again when cursor motion happens." +msgstr "" +"Timpul, în milisecunde, care să se aștepte înainte ca modulul să ascundă " +"cursorul. Cursorul este afișat din nou când se mișcă." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-join-views.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-join-views.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-join-views.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-join-views.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,17 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:25+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/join-views.xml:4 +msgid "Join Views" +msgstr "Alăturare ferestre" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-keycolor.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-keycolor.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-keycolor.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-keycolor.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,32 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:25+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/keycolor.xml:4 +msgid "Keycolor" +msgstr "Culoare-cheie" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/keycolor.xml:7 +msgid "Key Color" +msgstr "Culoare-cheie" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/keycolor.xml:11 +msgid "Opacity" +msgstr "Opacitate" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/keycolor.xml:15 +msgid "Threshold" +msgstr "Limită" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-mag.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-mag.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-mag.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-mag.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,32 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:26+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/mag.xml:4 +msgid "Magnifier" +msgstr "Lupă" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/mag.xml:7 +msgid "Toggle" +msgstr "Inițiere" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/mag.xml:11 +msgid "Zoom Level" +msgstr "Nivelul măririi" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/mag.xml:17 +msgid "Default View Height" +msgstr "Înălțimea standard a ferestrei" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-obs.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-obs.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-obs.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-obs.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,22 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:27+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/obs.xml:4 +msgid "OBS" +msgstr "OLS" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/obs.xml:5 +msgid "Change the opacity, brightness and saturation of windows using ipc scripts" +msgstr "Schimbă opacitatea, luminozitatea și saturația ferestrelor folosind scripturi IPC." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-pin-view.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-pin-view.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-pin-view.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-pin-view.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,22 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:28+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/pin-view.xml:4 +msgid "Pin View" +msgstr "Prindere fereastră" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/pin-view.xml:5 +msgid "Set a view layer, role and workspace" +msgstr "Stabilește un strat, rol și birou pentru o fereastră." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-showrepaint.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-showrepaint.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-showrepaint.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-showrepaint.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,50 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:31+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:4 +msgid "Show Repaint" +msgstr "Arată redesenările" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:5 +msgid "Show repainted areas on the screen." +msgstr "Arată zonele redesenate pe ecran." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:8 +msgid "Toggle" +msgstr "Inițiere" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:9 +msgid "Toggles the plugin state." +msgstr "Comută starea modulului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:13 +msgid "Reduce Flicker" +msgstr "Redu pâlpâirea" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showrepaint.xml:14 +msgid "" +"Reduce flicker by copying the client damage region from the last frame to " +"the current frame. This means that only the the damage region for all " +"surfaces of the frame are painted and the rest of the output is painted with " +"the contents of the last frame." +msgstr "" +"Redu pâlpâirea copiind regiunea de pătare a clientului de la cadrul anterior " +"la cadrul actual. Aceasta înseamnă că doar regiunea de pătare pentru fiecare " +"suprafață a cadrului este desenată și că restul ecranului este desenat cu " +"conținutul cadrului anterior." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-showtouch.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-showtouch.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-showtouch.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-showtouch.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,72 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:34+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:4 +msgid "Showtouch" +msgstr "Arată atingeri" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:5 +msgid "Render touchscreen fingers" +msgstr "Desenează degetele de pe un ecran tactil." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:8 +msgid "Finger Color" +msgstr "Culoarea degetului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:9 +msgid "Color used for rendering finger touches" +msgstr "Culoarea folosită pentru desenarea atingerilor cu degetul." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:13 +msgid "Center Color" +msgstr "Culoarea centrului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:14 +msgid "Color used for rendering computed center of fingers" +msgstr "Culoarea folosită pentru desenarea centrului calculat al degetelor." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:18 +msgid "Touch Radius" +msgstr "Raza atingerii" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:19 +msgid "Radius used to size the finger touch point renderings" +msgstr "Raza folosită pentru a dimensiona desenele punctelor de atingere cu degetul." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:23 +msgid "Touch Duration" +msgstr "Durata atingerii" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:24 +msgid "Milliseconds the visual finger indicator will stay on screen" +msgstr "Câte milisecunde să stea indicatorul vizual al degetului pe ecran" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:28 +msgid "Toggle" +msgstr "Comutare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/showtouch.xml:29 +msgid "Toggles the finger indicators off and on" +msgstr "Comută afișarea indicatorilor de degete" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-view-shot.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-view-shot.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-view-shot.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-view-shot.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,52 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-10-01 10:58+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:4 +msgid "View Shot" +msgstr "Captură fereastră" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:7 +msgid "Capture" +msgstr "Capturează" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:8 +msgid "Captures the cursor focus view." +msgstr "Capturează fereastra focalizată pentru cursor." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:12 +msgid "File Name" +msgstr "Numele fișierului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:13 +msgid "" +"C date format specifiers are repleaced by the time/date/etc. For example, %Y " +"is replaced by the current year." +msgstr "" +"Specificatorii formatului de dată C sunt înlocuiți de dată/oră/etc. De " +"exemplu, %Y este înlocuit cu anul actual." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:17 +msgid "Run Command" +msgstr "Execută comanda" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/view-shot.xml:18 +msgid "" +"Runs the command after the capturing. %f is replaced with the file name." +msgstr "Execută comanda după capturare. %f este înlocuit cu numele fișierului." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-water.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-water.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-water.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-water.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,32 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 22:36+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/water.xml:4 +msgid "Water" +msgstr "Apă" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/water.xml:5 +msgid "Water effect." +msgstr "Efect acvatic." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/water.xml:8 +msgid "Activate" +msgstr "Inițiere" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/water.xml:9 +msgid "Activates water effect." +msgstr "Activează efectul acvatic." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-window-zoom.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-window-zoom.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-window-zoom.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-window-zoom.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,86 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-09-30 23:36+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:4 +msgid "Window Zoom" +msgstr "Mărire fereastră" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:5 +msgid "A plugin to zoom windows." +msgstr "Un modul pentru a mări ferestre." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:8 +msgid "Modifier" +msgstr "Modificatoare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:9 +msgid "" +"When the modifier key is held down, you can scroll down and up to adjust the " +"zoom of the window." +msgstr "" +"Când tasta modificatoare este ținută apăsată, puteți derula în sus și în jos " +"pentru a regla gradul de mărire a ferestrei." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:13 +msgid "Zoom Step" +msgstr "Treaptă de mărire" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:14 +msgid "Sets the zoom increment per binding action." +msgstr "Stabilește treapta gradului de mărire pentru o acțiune de asociere." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:19 +msgid "Preserve Aspect" +msgstr "Păstrează raportul de aspect" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:20 +msgid "Preserve the aspect ratio of the view." +msgstr "Păstrează raportul de aspect al ferestrei." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:24 +msgid "Nearest Filtering" +msgstr "Filtru „cel mai apropiat”" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:25 +msgid "Use GL_NEAREST instead of GL_LINEAR." +msgstr "Folosește GL_NEAREST în locul lui GL_LINEAR." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:29 +msgid "Increment X" +msgstr "Incrementare X" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:33 +msgid "Decrement X" +msgstr "Decrementare X" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:37 +msgid "Increment Y" +msgstr "Incrementare Y" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/window-zoom.xml:41 +msgid "Decrement Y" +msgstr "Decrementare Y" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-workspace-names.po wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-workspace-names.po --- wayfire-plugins-extra-0.10.0/locale/ro/LC_MESSAGES/wf-plugin-workspace-names.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/LC_MESSAGES/wf-plugin-workspace-names.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,181 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-29 13:01+0300\n" +"PO-Revision-Date: 2025-10-01 10:56+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#. (itstool) path: plugin/_short +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:4 +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:92 +msgid "Workspace Names" +msgstr "Nume de birou" + +#. (itstool) path: plugin/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:5 +msgid "Name workspaces." +msgstr "Denumiți birourile." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:8 +msgid "Display Duration" +msgstr "Durata de afișare" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:9 +msgid "How long the name is displayed." +msgstr "Pentru cât timp se afișează numele." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:14 +msgid "Margin" +msgstr "Margine" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:15 +msgid "Distance from edge of screen to indicator." +msgstr "Distanța de la marginea ecranului la indicator." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:20 +msgid "Position" +msgstr "Poziție" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:21 +msgid "Position of rendering." +msgstr "Poziția desenării." + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:25 +msgid "Top Left" +msgstr "Stânga-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:29 +msgid "Top Center" +msgstr "Centru-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:33 +msgid "Top Right" +msgstr "Dreapta-sus" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:37 +msgid "Center Left" +msgstr "Stânga-centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:41 +msgid "Center" +msgstr "Centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:45 +msgid "Center Right" +msgstr "Dreapta-centru" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:49 +msgid "Bottom Left" +msgstr "Stânga-jos" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:53 +msgid "Bottom Center" +msgstr "Centru-jos" + +#. (itstool) path: desc/_name +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:57 +msgid "Bottom Right" +msgstr "Dreapta-jos" + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:61 +msgid "Background Color" +msgstr "Culoarea de fundal" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:62 +msgid "Background color for text." +msgstr "Culoarea de fundal a textului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:66 +msgid "Text Color" +msgstr "Culoarea textului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:67 +msgid "Text color." +msgstr "Culoarea textului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:71 +msgid "Text Font" +msgstr "Fontul textului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:72 +msgid "Font used for text rendering." +msgstr "Fontul folosit pentru desenarea textului." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:76 +msgid "Show Option Names" +msgstr "Arată numele opțiunilor" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:77 +msgid "Display option names on screen for convenience." +msgstr "Afișează numele opțiunilor pe ecran pentru comoditate." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:81 +msgid "Show Option Values" +msgstr "Arată valorile opțiunilor" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:82 +msgid "" +"Display option values instead of names, when show_option_names is enabled." +msgstr "" +"Afișează valorile opțiunilor în locul numelor când show_option_names este " +"activat." + +#. (itstool) path: option/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:86 +msgid "Background Corner Radius" +msgstr "Raza colțurilor fundalului" + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:87 +msgid "Radius for the corners of the background." +msgstr "Raza de folosit pentru colțurile fundalului." + +#. (itstool) path: option/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:93 +msgid "" +"Names of the workspaces. By default, they will have the name Workspace #N, " +"where #N is the workspace number." +msgstr "" +"Numele birourilor. În mod implicit, vor avea numele Workspace #N, unde #N " +"este numărul biroului." + +#. (itstool) path: entry/_short +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:95 +msgid "Workspace Name" +msgstr "Numele biroului" + +#. (itstool) path: entry/_long +#: /home/vlad/wayfire-plugins-extra/metadata/workspace-names.xml:96 +msgid "Sets the name of the workspace" +msgstr "Stabilește numele biroului." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/ro/wf-plugin-fisheye.po wayfire-plugins-extra/locale/ro/wf-plugin-fisheye.po --- wayfire-plugins-extra-0.10.0/locale/ro/wf-plugin-fisheye.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/ro/wf-plugin-fisheye.po 2026-08-01 16:00:35.432890271 -0600 @@ -0,0 +1,44 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-09-18 14:55+0300\n" +"PO-Revision-Date: 2025-09-18 18:31+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#. (itstool) path: plugin/_short +msgid "Fisheye" +msgstr "Ochi de pește" + +#. (itstool) path: plugin/_long +msgid "A plugin which provides fisheye effect." +msgstr "Un modul care furnizează un efect de obiectiv „ochi de pește”." + +#. (itstool) path: option/_short +msgid "Toggle" +msgstr "Inițiere" + +#. (itstool) path: option/_long +msgid "Toggles fisheye with the specified activator." +msgstr "Comută ochiul de pește cu activatorul specificat." + +#. (itstool) path: option/_short +msgid "Radius" +msgstr "Rază" + +#. (itstool) path: option/_long +msgid "Sets the border radius in pixels." +msgstr "Stabilește raza colțului în pixeli." + +#. (itstool) path: option/_short +msgid "Zoom" +msgstr "Mărire" + +#. (itstool) path: option/_long +msgid "Sets the zoom factor." +msgstr "Stabilește factorul de mărire." diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-annotate.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-annotate.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-annotate.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-annotate.po 2026-08-01 16:00:35.433260551 -0600 @@ -0,0 +1,83 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Annotate" +msgstr "标注" + +#. (itstool) path: plugin/_long +msgid "Draw on the output." +msgstr "在输出上绘制。" + +#. (itstool) path: option/_short +msgid "Draw" +msgstr "绘图" + +#. (itstool) path: option/_long +msgid "Begin drawing on workspace." +msgstr "开始在工作区上绘图。" + +#. (itstool) path: option/_short +msgid "Clear Workspace" +msgstr "清除工作区" + +#. (itstool) path: option/_long +msgid "Clear workspace." +msgstr "清除工作区。" + +#. (itstool) path: option/_short +msgid "Stroke Color" +msgstr "描边颜色" + +#. (itstool) path: option/_long +msgid "Color used for drawing." +msgstr "用于绘图的颜色。" + +#. (itstool) path: option/_short +msgid "Drawing Method" +msgstr "绘图方法" + +#. (itstool) path: option/_long +msgid "Method used for drawing." +msgstr "用于绘图的方法。" + +#. (itstool) path: desc/_name +msgid "Free Draw" +msgstr "自由绘图" + +#. (itstool) path: desc/_name +msgid "Line" +msgstr "直线" + +#. (itstool) path: desc/_name +msgid "Rectangle" +msgstr "矩形" + +#. (itstool) path: desc/_name +msgid "Circle" +msgstr "圆形" + +#. (itstool) path: option/_short +msgid "Line Width" +msgstr "线宽" + +#. (itstool) path: option/_long +msgid "Line width used for drawing." +msgstr "用于绘图的线宽。" + +#. (itstool) path: option/_short +msgid "Draw Shapes From Center" +msgstr "从中心绘制形状" + +#. (itstool) path: option/_long +msgid "Draw shapes from center of drag point." +msgstr "从拖动点的中心绘制形状。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-autorotate-iio.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-autorotate-iio.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-autorotate-iio.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-autorotate-iio.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,35 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Auto Rotate" +msgstr "自动旋转" + +#. (itstool) path: option/_short +msgid "Lock Rotation" +msgstr "锁定旋转" + +#. (itstool) path: option/_short +msgid "Rotate Up" +msgstr "向上旋转" + +#. (itstool) path: option/_short +msgid "Rotate Left" +msgstr "向左旋转" + +#. (itstool) path: option/_short +msgid "Rotate Down" +msgstr "向下旋转" + +#. (itstool) path: option/_short +msgid "Rotate Right" +msgstr "向右旋转" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-bench.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-bench.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-bench.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-bench.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,71 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Bench" +msgstr "基准测试" + +#. (itstool) path: plugin/_long +msgid "Display fps on each output." +msgstr "在每个输出上显示帧率。" + +#. (itstool) path: option/_short +msgid "Average frames" +msgstr "平均帧数" + +#. (itstool) path: option/_long +msgid "How many frames to average to get the FPS value." +msgstr "计算平均帧率所用的帧数。" + +#. (itstool) path: option/_short +msgid "Position" +msgstr "位置" + +#. (itstool) path: option/_long +msgid "Position of rendering." +msgstr "渲染位置。" + +#. (itstool) path: desc/_name +msgid "Top Left" +msgstr "左上" + +#. (itstool) path: desc/_name +msgid "Top Center" +msgstr "中上" + +#. (itstool) path: desc/_name +msgid "Top Right" +msgstr "右上" + +#. (itstool) path: desc/_name +msgid "Center Left" +msgstr "左中" + +#. (itstool) path: desc/_name +msgid "Center" +msgstr "居中" + +#. (itstool) path: desc/_name +msgid "Center Right" +msgstr "右中" + +#. (itstool) path: desc/_name +msgid "Bottom Left" +msgstr "左下" + +#. (itstool) path: desc/_name +msgid "Bottom Center" +msgstr "中下" + +#. (itstool) path: desc/_name +msgid "Bottom Right" +msgstr "右下" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-crosshair.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-crosshair.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-crosshair.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-crosshair.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,35 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Crosshair" +msgstr "十字线" + +#. (itstool) path: plugin/_long +msgid "Render fullscreen mouse crosshair" +msgstr "渲染全屏鼠标十字线" + +#. (itstool) path: option/_short +msgid "Line Width" +msgstr "线宽" + +#. (itstool) path: option/_long +msgid "Line width of crosshair" +msgstr "十字线的线宽" + +#. (itstool) path: option/_short +msgid "Line Color" +msgstr "线条颜色" + +#. (itstool) path: option/_long +msgid "Color used for rendering crosshair" +msgstr "用于渲染十字线的颜色" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-extra-animations.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-extra-animations.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-extra-animations.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-extra-animations.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,167 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Extra Animations" +msgstr "额外动画" + +#. (itstool) path: plugin/_long +msgid "Extra animations to extend animate plugin" +msgstr "扩展 animate 插件的额外动画" + +#. (itstool) path: group/_short +msgid "Blinds Settings" +msgstr "百叶窗设置" + +#. (itstool) path: option/_short +msgid "Blinds duration" +msgstr "百叶窗持续时间" + +#. (itstool) path: option/_long +msgid "Sets the duration for the blinds animation in milliseconds." +msgstr "以毫秒为单位设置百叶窗动画的持续时间。" + +#. (itstool) path: option/_short +msgid "Blinds strip height" +msgstr "百叶窗条高" + +#. (itstool) path: option/_long +msgid "Height of each blinds strip in pixels." +msgstr "每个百叶窗条的像素高度。" + +#. (itstool) path: group/_short +msgid "Helix Settings" +msgstr "螺旋设置" + +#. (itstool) path: option/_short +msgid "Helix duration" +msgstr "螺旋持续时间" + +#. (itstool) path: option/_long +msgid "Sets the duration for the helix animation in milliseconds." +msgstr "以毫秒为单位设置螺旋动画的持续时间。" + +#. (itstool) path: option/_short +msgid "Helix rotations" +msgstr "螺旋旋转次数" + +#. (itstool) path: option/_long +msgid "Number of rotations for the helix animation." +msgstr "螺旋动画的旋转次数。" + +#. (itstool) path: option/_short +msgid "Helix strip height" +msgstr "螺旋条高" + +#. (itstool) path: option/_long +msgid "Height of each helix strip in pixels." +msgstr "每个螺旋条的像素高度。" + +#. (itstool) path: group/_short +msgid "Shatter Settings" +msgstr "破碎设置" + +#. (itstool) path: option/_short +msgid "Shatter duration" +msgstr "破碎持续时间" + +#. (itstool) path: option/_long +msgid "Sets the duration for the shatter animation in milliseconds." +msgstr "以毫秒为单位设置破碎动画的持续时间。" + +#. (itstool) path: group/_short +msgid "Vortex Settings" +msgstr "旋涡设置" + +#. (itstool) path: option/_short +msgid "Vortex duration" +msgstr "旋涡持续时间" + +#. (itstool) path: option/_long +msgid "Sets the duration for the vortex animation in milliseconds." +msgstr "以毫秒为单位设置旋涡动画的持续时间。" + +#. (itstool) path: group/_short +msgid "Melt Settings" +msgstr "融化设置" + +#. (itstool) path: option/_short +msgid "Melt duration" +msgstr "融化持续时间" + +#. (itstool) path: option/_long +msgid "Sets the duration for the melt animation in milliseconds." +msgstr "以毫秒为单位设置融化动画的持续时间。" + +#. (itstool) path: option/_short +msgid "Melt distortion factor" +msgstr "融化变形系数" + +#. (itstool) path: option/_long +msgid "Distortion factor for melt animation." +msgstr "融化动画的变形系数。" + +#. (itstool) path: group/_short +msgid "Dodge Settings" +msgstr "闪避设置" + +#. (itstool) path: option/_short +msgid "Enable Dodge" +msgstr "启用闪避" + +#. (itstool) path: option/_long +msgid "Enables the Dodge focus animation." +msgstr "启用闪避焦点动画。" + +#. (itstool) path: option/_short +msgid "Duration" +msgstr "持续时间" + +#. (itstool) path: option/_long +msgid "Sets the animation duration in milliseconds." +msgstr "以毫秒为单位设置动画持续时间。" + +#. (itstool) path: option/_short +msgid "Rotate" +msgstr "旋转" + +#. (itstool) path: option/_long +msgid "Rotate windows during animation." +msgstr "动画期间旋转窗口。" + +#. (itstool) path: option/_short +msgid "Zoom" +msgstr "缩放" + +#. (itstool) path: option/_long +msgid "Slightly increase zoom for the focusing window during animation." +msgstr "在动画期间,将焦点窗口略微放大。" + +#. (itstool) path: option/_short +msgid "Animation Direction" +msgstr "动画方向" + +#. (itstool) path: option/_long +msgid "Sets the animation direction." +msgstr "设置动画方向。" + +#. (itstool) path: desc/_name +msgid "Cardinal" +msgstr "基数" + +#. (itstool) path: desc/_name +msgid "Diagonal" +msgstr "对角" + +#. (itstool) path: desc/_name +msgid "Circular" +msgstr "圆形" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-change.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-change.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-change.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-change.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,137 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Focus Change" +msgstr "焦点切换" + +#. (itstool) path: option/_short +msgid "focus up" +msgstr "上移焦点" + +#. (itstool) path: option/_long +msgid "move focus to the closest window above" +msgstr "将焦点移动到最靠近上方的窗口" + +#. (itstool) path: option/_short +msgid "focus down" +msgstr "下移焦点" + +#. (itstool) path: option/_long +msgid "move focus to the closest window below" +msgstr "将焦点移动到最靠近下方的窗口" + +#. (itstool) path: option/_short +msgid "focus right" +msgstr "右移焦点" + +#. (itstool) path: option/_long +msgid "move focus to the closest window to the right" +msgstr "将焦点移动到最靠近右侧的窗口" + +#. (itstool) path: option/_short +msgid "focus left" +msgstr "左移焦点" + +#. (itstool) path: option/_long +msgid "move focus to the closest window to the left" +msgstr "将焦点移动到最靠近左侧的窗口" + +#. (itstool) path: option/_short +msgid "upwards grace in pixels" +msgstr "向上容忍像素" + +#. (itstool) path: option/_long +msgid "" +"add an amount of pixel upwards in which windows will be ignored. Can be " +"negative" +msgstr "向上增加一定数量的像素,在此范围内将忽略窗口。可以是负值" + +#. (itstool) path: option/_short +msgid "downwards grace in pixels" +msgstr "向下容忍像素" + +#. (itstool) path: option/_long +msgid "" +"add an amount of pixel downwards in which windows will be ignored. Can be " +"negative" +msgstr "向下增加一定数量的像素,在此范围内将忽略窗口。可以是负值" + +#. (itstool) path: option/_short +msgid "rightwards grace in pixels" +msgstr "向右容忍像素" + +#. (itstool) path: option/_long +msgid "" +"add an amount of pixel to the right in which windows will be ignored. Can be " +"negative" +msgstr "向右增加一定数量的像素,在此范围内将忽略窗口。可以是负值" + +#. (itstool) path: option/_short +msgid "leftwards grace in pixels" +msgstr "向左容忍像素" + +#. (itstool) path: option/_long +msgid "" +"add an amount of pixel to the left in which windows will be ignored. Can be " +"negative" +msgstr "向左增加一定数量的像素,在此范围内将忽略窗口。可以是负值" + +#. (itstool) path: option/_short +msgid "ignores output boundraries" +msgstr "忽略输出边界" + +#. (itstool) path: option/_long +msgid "enables moving focus between different outputs" +msgstr "允许在不同输出之间移动焦点" + +#. (itstool) path: option/_short +msgid "ignores workspace boundraries" +msgstr "忽略工作区边界" + +#. (itstool) path: option/_long +msgid "enables moving focus between workspaces on the same output" +msgstr "允许在同一输出上的工作区之间移动焦点" + +#. (itstool) path: option/_short +msgid "raise window on change" +msgstr "切换时提升窗口" + +#. (itstool) path: option/_long +msgid "raise the newly focused window to the top" +msgstr "将新获得焦点的窗口提升到最顶层" + +#. (itstool) path: option/_short +msgid "scan height" +msgstr "扫描高度" + +#. (itstool) path: option/_long +msgid "" +"the height of the bounding box used to scan for windows to the left or " +"right. If zero it will be the height of the view. If negative it will be the " +"height of the view subtracted by the value" +msgstr "" +"用于扫描左侧或右侧窗口的边界框高度。如果为零,则为视图的高度。如果为负数,则" +"为视图高度减去该值" + +#. (itstool) path: option/_short +msgid "scan width" +msgstr "扫描宽度" + +#. (itstool) path: option/_long +msgid "" +"the width of the bounding box used to scan for window above or below. If " +"zero it will be the width of the view. If negative it will be the width of " +"the view subtracted by the value" +msgstr "" +"用于扫描上方或下方窗口的边界框宽度。如果为零,则为视图的宽度。如果为负数,则" +"为视图宽度减去该值" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-steal-prevent.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-steal-prevent.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-steal-prevent.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-focus-steal-prevent.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,49 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Focus Stealing Prevention" +msgstr "焦点防盗" + +#. (itstool) path: option/_short +msgid "The timeout (in ms) to prevent focus stealing" +msgstr "防止焦点被盗的超时(毫秒)" + +#. (itstool) path: option/_long +msgid "" +"A timer will be reset to the timeout (in ms) on every keystroke. If the " +"timer is active when another window would normally gain focus, the focus is " +"reset to the window that is accepting input." +msgstr "" +"每次按键时,计时器将重置为设定的超时(毫秒)。如果在另一个窗口通常会获得焦点" +"时计时器处于活动状态,则焦点将重置为正在接受输入的窗口。" + +#. (itstool) path: option/_short +msgid "Deny focus to views matching this criteria" +msgstr "拒绝焦点到符合此条件的视图" + +#. (itstool) path: option/_long +msgid "" +"If a view matches when mapped, focus is reset to the last view with focus." +msgstr "如果某个视图在映射时匹配,焦点将重置为上一个具有焦点的视图。" + +#. (itstool) path: option/_short +msgid "Cancel focus stealing prevention on these keys" +msgstr "在这些键上取消焦点防盗" + +#. (itstool) path: option/_long +msgid "" +"Cancel focus stealing prevention when any of these keys are pressed. The " +"string consists of keycode names delimited by | character." +msgstr "" +"按下这些键中的任何一个时,取消焦点防盗。该字符串由用 | 字符分隔的按键码名称组" +"成。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-follow-focus.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-follow-focus.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-follow-focus.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-follow-focus.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,65 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Follow Focus" +msgstr "跟随焦点" + +#. (itstool) path: option/_short +msgid "View focus follows mouse" +msgstr "视图焦点跟随鼠标" + +#. (itstool) path: option/_long +msgid "" +"When the mouse pointer is moved, the view focus changes to the view under " +"the pointer." +msgstr "当鼠标指针移动时,视图焦点会切换到指针下方的视图。" + +#. (itstool) path: option/_short +msgid "Output focus follows mouse" +msgstr "输出焦点跟随鼠标" + +#. (itstool) path: option/_long +msgid "" +"When the mouse pointer is moved, the output focus changes to the output that " +"the pointer is currently on." +msgstr "当鼠标指针移动时,输出焦点会切换到指针当前所在的输出。" + +#. (itstool) path: option/_short +msgid "Delay (in ms) before focus change will be triggered" +msgstr "焦点改变前的延迟(毫秒)" + +#. (itstool) path: option/_long +msgid "" +"The delay in ms before the plugin will trigger a focus change after the " +"movement finished." +msgstr "在移动结束后,插件触发焦点改变前的延迟(毫秒)。" + +#. (itstool) path: option/_short +msgid "Minimum cursor movement" +msgstr "最小光标移动" + +#. (itstool) path: option/_long +msgid "" +"The distance (x+y) the cursor should be moved at least before the plugin " +"gets activated" +msgstr "光标需要移动的最小距离 (x+y),在此之后插件才会激活。" + +#. (itstool) path: option/_short +msgid "Raise the focused view to the top" +msgstr "将焦点视图提升到顶部" + +#. (itstool) path: option/_long +msgid "" +"If disabled the focused view will only get keyboard focus, but will not be " +"raised to the top." +msgstr "如果禁用,焦点视图将只获得键盘焦点,但不会被提升到顶部。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-force-fullscreen.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-force-fullscreen.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-force-fullscreen.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-force-fullscreen.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,51 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Fullscreen Window" +msgstr "全屏窗口" + +#. (itstool) path: option/_short +msgid "Key Toggle Fullscreen" +msgstr "按键切换全屏" + +#. (itstool) path: option/_short +msgid "Preserve Aspect Ratio" +msgstr "保持长宽比" + +#. (itstool) path: option/_short +msgid "Transparent Behind Views" +msgstr "视图后方透明" + +#. (itstool) path: option/_short +msgid "Skew view width by multiplying by this factor" +msgstr "通过乘以该因子来扭曲视图宽度" + +#. (itstool) path: option/_short +msgid "Skew view height by multiplying by this factor" +msgstr "通过乘以该因子来扭曲视图高度" + +#. (itstool) path: option/_short +msgid "Constrain Mouse Pointer" +msgstr "限制鼠标指针" + +#. (itstool) path: option/_long +msgid "If constrain pointer is enabled, constrain to this area." +msgstr "如果启用了限制指针,则限制在此区域。" + +#. (itstool) path: desc/_name +msgid "View" +msgstr "视图" + +#. (itstool) path: desc/_name +msgid "Output" +msgstr "输出" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-ghost.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-ghost.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-ghost.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-ghost.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,31 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Ghost Windows" +msgstr "幽灵窗口" + +#. (itstool) path: option/_short +msgid "Ghosted Windows" +msgstr "幽灵化窗口" + +#. (itstool) path: option/_long +msgid "Automatically sets the matched windows to be click-through." +msgstr "自动将匹配的窗口设置为可穿透点击。" + +#. (itstool) path: option/_short +msgid "Toggle Ghost Window" +msgstr "切换幽灵窗口" + +#. (itstool) path: option/_long +msgid "Toggles the active window being click-through to whatever is below." +msgstr "将活动窗口切换为可穿透点击,点击会作用于下方的内容。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-hide-cursor.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-hide-cursor.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-hide-cursor.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-hide-cursor.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,37 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Hide Cursor" +msgstr "隐藏光标" + +#. (itstool) path: plugin/_long +msgid "A plugin that allows to toggle hide mouse cursor." +msgstr "一个允许切换隐藏鼠标光标的插件。" + +#. (itstool) path: option/_short +msgid "Toggle" +msgstr "切换" + +#. (itstool) path: option/_long +msgid "Toggles hide mouse cursor." +msgstr "切换隐藏鼠标光标。" + +#. (itstool) path: option/_short +msgid "Delay (in ms) before cursor will be hidden" +msgstr "光标隐藏前的延迟(毫秒)" + +#. (itstool) path: option/_long +msgid "" +"The delay in ms before the plugin will hide the cursor. The cursor is shown " +"again when cursor motion happens." +msgstr "插件隐藏光标前的延迟(毫秒)。当光标移动时,光标会再次显示。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-join-views.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-join-views.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-join-views.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-join-views.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,15 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Join Views" +msgstr "合并视图" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-keycolor.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-keycolor.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-keycolor.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-keycolor.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,27 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Keycolor" +msgstr "键色" + +#. (itstool) path: option/_short +msgid "Key Color" +msgstr "键色" + +#. (itstool) path: option/_short +msgid "Opacity" +msgstr "不透明度" + +#. (itstool) path: option/_short +msgid "Threshold" +msgstr "阈值" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-mag.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-mag.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-mag.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-mag.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,27 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Magnifier" +msgstr "放大镜" + +#. (itstool) path: option/_short +msgid "Toggle" +msgstr "切换" + +#. (itstool) path: option/_short +msgid "Zoom Level" +msgstr "缩放级别" + +#. (itstool) path: option/_short +msgid "Default View Height" +msgstr "默认视图高度" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-obs.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-obs.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-obs.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-obs.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,20 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "OBS" +msgstr "不透明度、亮度与饱和度" + +#. (itstool) path: plugin/_long +msgid "" +"Change the opacity, brightness and saturation of windows using ipc scripts" +msgstr "使用 ipc 脚本更改窗口的不透明度、亮度和饱和度" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-pin-view.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-pin-view.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-pin-view.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-pin-view.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,19 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Pin View" +msgstr "固定视图" + +#. (itstool) path: plugin/_long +msgid "Set a view layer, role and workspace" +msgstr "设置视图图层、角色和工作区" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-showrepaint.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-showrepaint.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-showrepaint.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-showrepaint.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,41 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Show Repaint" +msgstr "显示重绘" + +#. (itstool) path: plugin/_long +msgid "Show repainted areas on the screen." +msgstr "在屏幕上显示重绘区域。" + +#. (itstool) path: option/_short +msgid "Toggle" +msgstr "切换" + +#. (itstool) path: option/_long +msgid "Toggles the plugin state." +msgstr "切换插件状态。" + +#. (itstool) path: option/_short +msgid "Reduce Flicker" +msgstr "减少闪烁" + +#. (itstool) path: option/_long +msgid "" +"Reduce flicker by copying the client damage region from the last frame to " +"the current frame. This means that only the the damage region for all " +"surfaces of the frame are painted and the rest of the output is painted with " +"the contents of the last frame." +msgstr "" +"通过将客户端损坏区域从上一帧复制到当前帧来减少闪烁。这意味着只绘制帧中所有表" +"面的损坏区域,其余输出则用上一帧的内容绘制。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-showtouch.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-showtouch.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-showtouch.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-showtouch.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,59 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Showtouch" +msgstr "显示触控" + +#. (itstool) path: plugin/_long +msgid "Render touchscreen fingers" +msgstr "渲染触控笔划" + +#. (itstool) path: option/_short +msgid "Finger Color" +msgstr "手指颜色" + +#. (itstool) path: option/_long +msgid "Color used for rendering finger touches" +msgstr "用于渲染手指触控的颜色" + +#. (itstool) path: option/_short +msgid "Center Color" +msgstr "中心颜色" + +#. (itstool) path: option/_long +msgid "Color used for rendering computed center of fingers" +msgstr "用于渲染计算出的手指中心的颜色" + +#. (itstool) path: option/_short +msgid "Touch Radius" +msgstr "触控半径" + +#. (itstool) path: option/_long +msgid "Radius used to size the finger touch point renderings" +msgstr "用于调整手指触控点渲染大小的半径" + +#. (itstool) path: option/_short +msgid "Touch Duration" +msgstr "触控持续时间" + +#. (itstool) path: option/_long +msgid "Milliseconds the visual finger indicator will stay on screen" +msgstr "可视手指指示器在屏幕上停留的毫秒数" + +#. (itstool) path: option/_short +msgid "Toggle" +msgstr "切换" + +#. (itstool) path: option/_long +msgid "Toggles the finger indicators off and on" +msgstr "切换手指指示器的开启和关闭" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-view-shot.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-view-shot.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-view-shot.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-view-shot.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,42 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "View Shot" +msgstr "视图截图" + +#. (itstool) path: option/_short +msgid "Capture" +msgstr "捕捉" + +#. (itstool) path: option/_long +msgid "Captures the cursor focus view." +msgstr "捕捉光标焦点视图。" + +#. (itstool) path: option/_short +msgid "File Name" +msgstr "文件名" + +#. (itstool) path: option/_long +msgid "" +"C date format specifiers are repleaced by the time/date/etc. For example, %Y " +"is replaced by the current year." +msgstr "C 日期格式说明符将被替换为时间/日期等。例如,%Y 会被替换为当前年份。" + +#. (itstool) path: option/_short +msgid "Run Command" +msgstr "运行命令" + +#. (itstool) path: option/_long +msgid "" +"Runs the command after the capturing. %f is replaced with the file name." +msgstr "捕捉后运行命令。%f 会被替换为文件名。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-water.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-water.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-water.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-water.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,27 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Water" +msgstr "水" + +#. (itstool) path: plugin/_long +msgid "Water effect." +msgstr "水面效果。" + +#. (itstool) path: option/_short +msgid "Activate" +msgstr "激活" + +#. (itstool) path: option/_long +msgid "Activates water effect." +msgstr "激活水面效果。" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-window-zoom.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-window-zoom.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-window-zoom.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-window-zoom.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,69 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +msgid "Window Zoom" +msgstr "窗口缩放" + +#. (itstool) path: plugin/_long +msgid "A plugin to zoom windows." +msgstr "一个用于缩放窗口的插件。" + +#. (itstool) path: option/_short +msgid "Modifier" +msgstr "修饰键" + +#. (itstool) path: option/_long +msgid "" +"When the modifier key is held down, you can scroll down and up to adjust the " +"zoom of the window." +msgstr "按住修饰键时,您可以通过上下滚动来调整窗口的缩放。" + +#. (itstool) path: option/_short +msgid "Zoom Step" +msgstr "缩放步长" + +#. (itstool) path: option/_long +msgid "Sets the zoom increment per binding action." +msgstr "设置每个绑定操作的缩放增量。" + +#. (itstool) path: option/_short +msgid "Preserve Aspect" +msgstr "保持长宽比" + +#. (itstool) path: option/_long +msgid "Preserve the aspect ratio of the view." +msgstr "保持视图的长宽比。" + +#. (itstool) path: option/_short +msgid "Nearest Filtering" +msgstr "最近邻过滤" + +#. (itstool) path: option/_long +msgid "Use GL_NEAREST instead of GL_LINEAR." +msgstr "使用 GL_NEAREST 而不是 GL_LINEAR。" + +#. (itstool) path: option/_short +msgid "Increment X" +msgstr "X 增量" + +#. (itstool) path: option/_short +msgid "Decrement X" +msgstr "X 减量" + +#. (itstool) path: option/_short +msgid "Increment Y" +msgstr "Y 增量" + +#. (itstool) path: option/_short +msgid "Decrement Y" +msgstr "Y 减量" diff --color -Naurp wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-workspace-names.po wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-workspace-names.po --- wayfire-plugins-extra-0.10.0/locale/zh_CN/LC_MESSAGES/wf-plugin-workspace-names.po 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/locale/zh_CN/LC_MESSAGES/wf-plugin-workspace-names.po 2026-08-01 16:00:35.433292492 -0600 @@ -0,0 +1,144 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-09-28 22:10-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. (itstool) path: plugin/_short +#. (itstool) path: option/_short +msgid "Workspace Names" +msgstr "工作区名称" + +#. (itstool) path: plugin/_long +msgid "Name workspaces." +msgstr "为工作区命名。" + +#. (itstool) path: option/_short +msgid "Display Duration" +msgstr "显示持续时间" + +#. (itstool) path: option/_long +msgid "How long the name is displayed." +msgstr "名称的显示时长。" + +#. (itstool) path: option/_short +msgid "Margin" +msgstr "边距" + +#. (itstool) path: option/_long +msgid "Distance from edge of screen to indicator." +msgstr "指示器到屏幕边缘的距离。" + +#. (itstool) path: option/_short +msgid "Position" +msgstr "位置" + +#. (itstool) path: option/_long +msgid "Position of rendering." +msgstr "渲染位置。" + +#. (itstool) path: desc/_name +msgid "Top Left" +msgstr "左上" + +#. (itstool) path: desc/_name +msgid "Top Center" +msgstr "中上" + +#. (itstool) path: desc/_name +msgid "Top Right" +msgstr "右上" + +#. (itstool) path: desc/_name +msgid "Center Left" +msgstr "左中" + +#. (itstool) path: desc/_name +msgid "Center" +msgstr "居中" + +#. (itstool) path: desc/_name +msgid "Center Right" +msgstr "右中" + +#. (itstool) path: desc/_name +msgid "Bottom Left" +msgstr "左下" + +#. (itstool) path: desc/_name +msgid "Bottom Center" +msgstr "中下" + +#. (itstool) path: desc/_name +msgid "Bottom Right" +msgstr "右下" + +#. (itstool) path: option/_short +msgid "Background Color" +msgstr "背景颜色" + +#. (itstool) path: option/_long +msgid "Background color for text." +msgstr "文本的背景颜色。" + +#. (itstool) path: option/_short +msgid "Text Color" +msgstr "文本颜色" + +#. (itstool) path: option/_long +msgid "Text color." +msgstr "文本颜色。" + +#. (itstool) path: option/_short +msgid "Text Font" +msgstr "文本字体" + +#. (itstool) path: option/_long +msgid "Font used for text rendering." +msgstr "用于文本渲染的字体。" + +#. (itstool) path: option/_short +msgid "Show Option Names" +msgstr "显示选项名称" + +#. (itstool) path: option/_long +msgid "Display option names on screen for convenience." +msgstr "在屏幕上显示选项名称以方便使用。" + +#. (itstool) path: option/_short +msgid "Show Option Values" +msgstr "显示选项值" + +#. (itstool) path: option/_long +msgid "" +"Display option values instead of names, when show_option_names is enabled." +msgstr "当启用显示选项名称时,显示选项值而不是名称。" + +#. (itstool) path: option/_short +msgid "Background Corner Radius" +msgstr "背景圆角半径" + +#. (itstool) path: option/_long +msgid "Radius for the corners of the background." +msgstr "背景圆角的半径。" + +#. (itstool) path: option/_long +msgid "" +"Names of the workspaces. By default, they will have the name Workspace #N, " +"where #N is the workspace number." +msgstr "" +"工作区的名称。默认情况下,它们的名称为“工作区 #N”,其中 #N 是工作区编号。" + +#. (itstool) path: entry/_short +msgid "Workspace Name" +msgstr "工作区名称" + +#. (itstool) path: entry/_long +msgid "Sets the name of the workspace" +msgstr "设置工作区的名称" diff --color -Naurp wayfire-plugins-extra-0.10.0/meson.build wayfire-plugins-extra/meson.build --- wayfire-plugins-extra-0.10.0/meson.build 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/meson.build 2026-08-01 16:00:35.433292492 -0600 @@ -2,9 +2,9 @@ project( 'wayfire-plugins-extra', 'c', 'cpp', - version: '0.10.0', + version: '0.11.0', license: 'MIT', - meson_version: '>=0.51.0', + meson_version: '>=0.59.0', default_options: [ 'cpp_std=c++17', 'c_std=c11', @@ -13,7 +13,7 @@ project( ], ) -wayfire = dependency('wayfire', version: '>=0.9.0') +wayfire = dependency('wayfire', version: '>=0.11.0') giomm = dependency('giomm-2.4', required: false) wayland_protos = dependency('wayland-protocols', version: '>=1.12') wayland_server = dependency('wayland-server') @@ -43,6 +43,7 @@ add_project_arguments(['-Wno-unused-para subdir('proto') subdir('src') subdir('metadata') +subdir('locale') summary = [ '', diff --color -Naurp wayfire-plugins-extra-0.10.0/metadata/crosshair.xml wayfire-plugins-extra/metadata/crosshair.xml --- wayfire-plugins-extra-0.10.0/metadata/crosshair.xml 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/metadata/crosshair.xml 2026-08-01 16:00:35.433615642 -0600 @@ -4,7 +4,7 @@ <_short>Crosshair <_long>Render fullscreen mouse crosshair Utility - + + <_short>Burn Settings + + + + + + + + + <_short>Magic Carpet Settings + + + + + <_short>Dodge Settings + + + + + + diff --color -Naurp wayfire-plugins-extra-0.10.0/metadata/fisheye.xml wayfire-plugins-extra/metadata/fisheye.xml --- wayfire-plugins-extra-0.10.0/metadata/fisheye.xml 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/metadata/fisheye.xml 2026-08-01 16:00:35.433615642 -0600 @@ -0,0 +1,27 @@ + + + + <_short>Fisheye + <_long>A plugin which provides fisheye effect. + Effects + + + + + diff --color -Naurp wayfire-plugins-extra-0.10.0/metadata/meson.build wayfire-plugins-extra/metadata/meson.build --- wayfire-plugins-extra-0.10.0/metadata/meson.build 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/metadata/meson.build 2026-08-01 16:00:35.433615642 -0600 @@ -3,6 +3,7 @@ install_data('autorotate-iio.xml', insta install_data('bench.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('crosshair.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('extra-animations.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) +install_data('fisheye.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('focus-change.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('focus-steal-prevent.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) install_data('follow-focus.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir')) diff --color -Naurp wayfire-plugins-extra-0.10.0/src/annotate.cpp wayfire-plugins-extra/src/annotate.cpp --- wayfire-plugins-extra-0.10.0/src/annotate.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/annotate.cpp 2026-08-01 16:00:35.433615642 -0600 @@ -80,26 +80,23 @@ class simple_node_render_instance_t : pu node_t *self; damage_callback push_to_parent; std::shared_ptr overlay, shape_overlay; - int *x, *y, *w, *h; + wf::geometry_t *geometry; public: simple_node_render_instance_t(node_t *self, damage_callback push_dmg, - int *x, int *y, int *w, int *h, std::shared_ptr overlay, + wf::geometry_t *geometry, std::shared_ptr overlay, std::shared_ptr shape_overlay) { - this->x = x; - this->y = y; - this->w = w; - this->h = h; - this->self = self; - this->overlay = overlay; + this->geometry = geometry; + this->self = self; + this->overlay = overlay; this->shape_overlay = shape_overlay; this->push_to_parent = push_dmg; self->connect(&on_node_damaged); } void schedule_instructions(std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -111,15 +108,15 @@ class simple_node_render_instance_t : pu void render(const wf::scene::render_instruction_t& data) override { - auto ol = this->overlay; - wlr_box og = {*x, *y, *w, *h}; + auto ol = this->overlay; + wf::geometry_t og = *geometry; data.pass->custom_gles_subpass([&] { wf::gles::bind_render_buffer(data.target); for (auto& box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); if (ol->cr) { OpenGL::render_texture(wf::gles_texture_t{ol->texture->tex}, data.target, og, @@ -139,16 +136,16 @@ class simple_node_render_instance_t : pu class simple_node_t : public node_t { - int x, y, w, h; + wf::geometry_t geometry; public: std::shared_ptr overlay, shape_overlay; simple_node_t(int x, int y, int w, int h) : node_t(false) { - this->x = x; - this->y = y; - this->w = w; - this->h = h; + this->geometry.x = x; + this->geometry.y = y; + this->geometry.width = w; + this->geometry.height = h; overlay = std::make_shared(); shape_overlay = std::make_shared(); } @@ -161,10 +158,10 @@ class simple_node_t : public node_t // this simple nodes does not need any transformations, so the push_damage // callback is just passed along. instances.push_back(std::make_unique( - this, push_damage, &x, &y, &w, &h, overlay, shape_overlay)); + this, push_damage, &geometry, overlay, shape_overlay)); } - void do_push_damage(wf::region_t updated_region) + void do_push_damage(wf::regionf_t updated_region) { node_damage_signal ev; ev.region = updated_region; @@ -174,19 +171,19 @@ class simple_node_t : public node_t wf::geometry_t get_bounding_box() override { // Specify whatever geometry your node has - return {x, y, w, h}; + return geometry; } void set_position(int x, int y) { - this->x = x; - this->y = y; + this->geometry.x = x; + this->geometry.y = y; } void set_size(int w, int h) { - this->w = w; - this->h = h; + this->geometry.width = w; + this->geometry.height = h; } }; @@ -201,7 +198,7 @@ std::shared_ptr add_simpl class wayfire_annotate_screen : public wf::per_output_plugin_instance_t, public wf::pointer_interaction_t { uint32_t button; - wlr_box last_bbox; + wf::geometry_t last_bbox; annotate_draw_method draw_method; wf::pointf_t grab_point, last_cursor; std::vector>> overlays; @@ -519,15 +516,15 @@ class wayfire_annotate_screen : public w cairo_line_to(cr, to.x, to.y); cairo_stroke(cr); - wlr_box bbox; + wf::geometry_t bbox; int padding = line_width + 1; bbox.x = std::min(from.x, to.x) - padding; bbox.y = std::min(from.y, to.y) - padding; - bbox.width = abs(from.x - to.x) + padding * 2; - bbox.height = abs(from.y - to.y) + padding * 2; - get_node_overlay()->do_push_damage(wf::region_t(bbox)); + bbox.width = std::abs(from.x - to.x) + padding * 2; + bbox.height = std::abs(from.y - to.y) + padding * 2; + get_node_overlay()->do_push_damage(wf::regionf_t(bbox)); cairo_surface_upload_to_texture_with_damage(ol->cairo_surface, *ol->texture, - bbox); + wf::to_integer_box(bbox)); } bool should_damage_last() @@ -563,14 +560,14 @@ class wayfire_annotate_screen : public w cairo_line_to(cr, to.x, to.y); cairo_stroke(cr); - wlr_box bbox; + wf::geometry_t bbox; int padding = line_width + 1; bbox.x = std::min(from.x, to.x) - padding; bbox.y = std::min(from.y, to.y) - padding; - bbox.width = abs(from.x - to.x) + padding * 2; - bbox.height = abs(from.y - to.y) + padding * 2; + bbox.width = std::abs(from.x - to.x) + padding * 2; + bbox.height = std::abs(from.y - to.y) + padding * 2; output->render->damage(bbox); - wf::region_t damage_region{bbox}; + wf::regionf_t damage_region{bbox}; if (damage_last_bbox) { output->render->damage(last_bbox); @@ -579,14 +576,14 @@ class wayfire_annotate_screen : public w damage_region &= output->get_relative_geometry(); auto damage_extents = damage_region.get_extents(); - wlr_box damage_box = + auto damage_box = wf::to_integer_box(wf::geometry_t {damage_extents.x1, damage_extents.y1, damage_extents.x2 - damage_extents.x1, - damage_extents.y2 - damage_extents.y1}; + damage_extents.y2 - damage_extents.y1}); cairo_surface_upload_to_texture_with_damage(ol->cairo_surface, *ol->texture, damage_box); - get_node_overlay()->do_push_damage(wf::region_t(last_bbox)); - get_node_overlay()->do_push_damage(wf::region_t(bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(last_bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(bbox)); last_bbox = bbox; } @@ -632,14 +629,14 @@ class wayfire_annotate_screen : public w cairo_rectangle(cr, x, y, w, h); cairo_stroke(cr); - wlr_box bbox; + wf::geometry_t bbox; int padding = line_width + 1; bbox.x = x - padding; bbox.y = y - padding; bbox.width = w + padding * 2; bbox.height = h + padding * 2; output->render->damage(bbox); - wf::region_t damage_region{bbox}; + wf::regionf_t damage_region{bbox}; if (damage_last_bbox) { output->render->damage(last_bbox); @@ -648,14 +645,14 @@ class wayfire_annotate_screen : public w damage_region &= output->get_relative_geometry(); auto damage_extents = damage_region.get_extents(); - wlr_box damage_box = + auto damage_box = wf::to_integer_box(wf::geometry_t {damage_extents.x1, damage_extents.y1, damage_extents.x2 - damage_extents.x1, - damage_extents.y2 - damage_extents.y1}; + damage_extents.y2 - damage_extents.y1}); cairo_surface_upload_to_texture_with_damage(ol->cairo_surface, *ol->texture, damage_box); - get_node_overlay()->do_push_damage(wf::region_t(last_bbox)); - get_node_overlay()->do_push_damage(wf::region_t(bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(last_bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(bbox)); last_bbox = bbox; } @@ -695,14 +692,14 @@ class wayfire_annotate_screen : public w cairo_arc(cr, from.x, from.y, radius, 0, 2 * M_PI); cairo_stroke(cr); - wlr_box bbox; + wf::geometry_t bbox; int padding = line_width + 1; bbox.x = (from.x - radius) - padding; bbox.y = (from.y - radius) - padding; bbox.width = (radius * 2) + padding * 2; bbox.height = (radius * 2) + padding * 2; output->render->damage(bbox); - wf::region_t damage_region{bbox}; + wf::regionf_t damage_region{bbox}; if (damage_last_bbox) { output->render->damage(last_bbox); @@ -711,14 +708,14 @@ class wayfire_annotate_screen : public w damage_region &= output->get_relative_geometry(); auto damage_extents = damage_region.get_extents(); - wlr_box damage_box = + auto damage_box = wf::to_integer_box(wf::geometry_t {damage_extents.x1, damage_extents.y1, damage_extents.x2 - damage_extents.x1, - damage_extents.y2 - damage_extents.y1}; + damage_extents.y2 - damage_extents.y1}); cairo_surface_upload_to_texture_with_damage(ol->cairo_surface, *ol->texture, damage_box); - get_node_overlay()->do_push_damage(wf::region_t(last_bbox)); - get_node_overlay()->do_push_damage(wf::region_t(bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(last_bbox)); + get_node_overlay()->do_push_damage(wf::regionf_t(bbox)); last_bbox = bbox; } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/autorotate-iio.cpp wayfire-plugins-extra/src/autorotate-iio.cpp --- wayfire-plugins-extra-0.10.0/src/autorotate-iio.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/autorotate-iio.cpp 2026-08-01 16:00:35.433998821 -0600 @@ -22,6 +22,7 @@ extern "C" { #include #include +#include } using namespace Gio; @@ -105,6 +106,12 @@ class WayfireAutorotateIIO : public wf:: /* Transform coming from the iio-sensors, -1 means not set */ int32_t sensor_transform = -1; + /* Debounce: pending transform waiting to be confirmed stable */ + int32_t pending_transform = -1; + guint debounce_timer_id = 0; + static constexpr guint DEBOUNCE_ROTATE_MS = 500; + static constexpr guint DEBOUNCE_NORMAL_MS = 1200; + bool on_rotate_binding(int32_t target_rotation) { if (!output->can_activate_plugin(&grab_interface)) @@ -154,10 +161,18 @@ class WayfireAutorotateIIO : public wf:: return true; } - wf::effect_hook_t on_frame = [=] () + /* Wayland event loop timer — fires every 50ms to pump the GLib main context + * even when the display is idle and on_frame would not run. */ + wl_event_source *glib_timer = nullptr; + + static int glib_timer_cb(void *data) { + auto *self = static_cast(data); Glib::MainContext::get_default()->iteration(false); - }; + wl_event_source_timer_update(self->glib_timer, 50); + return 0; + } + Glib::RefPtr loop; public: @@ -185,7 +200,10 @@ class WayfireAutorotateIIO : public wf:: Gio::init(); loop = Glib::MainLoop::create(true); - output->render->add_effect(&on_frame, wf::OUTPUT_EFFECT_PRE); + + auto *evloop = wl_display_get_event_loop(wf::get_core().display); + glib_timer = wl_event_loop_add_timer(evloop, glib_timer_cb, this); + wl_event_source_timer_update(glib_timer, 50); watch_id = DBus::watch_name(DBus::BUS_TYPE_SYSTEM, "net.hadess.SensorProxy", sigc::mem_fun(this, &WayfireAutorotateIIO::on_iio_appeared), @@ -210,6 +228,7 @@ class WayfireAutorotateIIO : public wf:: iio_proxy->signal_properties_changed().connect_notify( sigc::mem_fun(this, &WayfireAutorotateIIO::on_properties_changed)); iio_proxy->call_sync("ClaimAccelerometer"); + update_orientation(); } void on_properties_changed( @@ -228,6 +247,11 @@ class WayfireAutorotateIIO : public wf:: Glib::Variant orientation; iio_proxy->get_cached_property(orientation, "AccelerometerOrientation"); + if (!orientation) + { + return; + } + LOGI("IIO Accelerometer orientation: %s", orientation.get().c_str()); static const std::map transform_by_name = @@ -238,10 +262,55 @@ class WayfireAutorotateIIO : public wf:: {"bottom-up", WL_OUTPUT_TRANSFORM_180}, }; - if (transform_by_name.count(orientation.get())) + if (!transform_by_name.count(orientation.get())) { - sensor_transform = transform_by_name.find(orientation.get())->second; - update_transform(); + return; + } + + int32_t new_transform = transform_by_name.find(orientation.get())->second; + + bool timer_running = (debounce_timer_id != 0); + bool new_is_normal = (new_transform == WL_OUTPUT_TRANSFORM_NORMAL); + bool pend_is_normal = (pending_transform == WL_OUTPUT_TRANSFORM_NORMAL); + + if (!timer_running) + { + if (new_transform == sensor_transform) + { + return; + } + + pending_transform = new_transform; + guint delay = new_is_normal ? DEBOUNCE_NORMAL_MS : DEBOUNCE_ROTATE_MS; + debounce_timer_id = g_timeout_add(delay, [] (gpointer data) -> gboolean + { + auto *self = static_cast(data); + self->debounce_timer_id = 0; + self->sensor_transform = self->pending_transform; + self->update_transform(); + return G_SOURCE_REMOVE; + }, this); + } else if (!pend_is_normal) + { + if (!new_is_normal) + { + pending_transform = new_transform; + } + } else + { + if (!new_is_normal) + { + g_source_remove(debounce_timer_id); + pending_transform = new_transform; + debounce_timer_id = g_timeout_add(DEBOUNCE_ROTATE_MS, [] (gpointer data) -> gboolean + { + auto *self = static_cast(data); + self->debounce_timer_id = 0; + self->sensor_transform = self->pending_transform; + self->update_transform(); + return G_SOURCE_REMOVE; + }, this); + } } } @@ -259,13 +328,20 @@ class WayfireAutorotateIIO : public wf:: output->rem_binding(&on_rotate_up); output->rem_binding(&on_rotate_down); + if (debounce_timer_id) + { + g_source_remove(debounce_timer_id); + debounce_timer_id = 0; + } + /* If loop is NULL, autorotate was disabled for the current output */ if (loop) { iio_proxy.reset(); DBus::unwatch_name(watch_id); loop->quit(); - output->render->rem_effect(&on_frame); + wl_event_source_remove(glib_timer); + glib_timer = nullptr; } } }; diff --color -Naurp wayfire-plugins-extra-0.10.0/src/crosshair.cpp wayfire-plugins-extra/src/crosshair.cpp --- wayfire-plugins-extra-0.10.0/src/crosshair.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/crosshair.cpp 2026-08-01 16:00:35.433998821 -0600 @@ -31,7 +31,7 @@ class wayfire_crosshair : public wf::per_output_plugin_instance_t { - wf::option_wrapper_t line_width{"crosshair/line_width"}; + wf::option_wrapper_t line_width{"crosshair/line_width"}; wf::option_wrapper_t line_color{"crosshair/line_color"}; wf::geometry_t geometry[2]; @@ -56,9 +56,9 @@ class wayfire_crosshair : public wf::per output->render->damage(geometry[1]); geometry[0] = - wf::geometry_t{int(oc.x - half_width), 0, line_width, og.height}; + wf::geometry_t{oc.x - half_width, 0, line_width, og.height}; geometry[1] = - wf::geometry_t{0, int(oc.y - half_width), og.width, line_width}; + wf::geometry_t{0, oc.y - half_width, og.width, line_width}; output->render->damage(geometry[0]); output->render->damage(geometry[1]); @@ -68,17 +68,17 @@ class wayfire_crosshair : public wf::per { auto target_fb = output->render->get_target_framebuffer(); auto gc = wf::get_core().get_cursor_position(); - wf::point_t coords{(int)gc.x, (int)gc.y}; + wf::pointf_t coords{gc.x, gc.y}; if (!(output->get_layout_geometry() & coords)) { return; } - wf::region_t region; + wf::regionf_t region; region |= geometry[0]; region |= geometry[1]; - region &= output->render->get_swap_damage(); + region &= target_fb.geometry_region_from_framebuffer_region(output->render->get_swap_damage()); auto alpha = wf::color_t(line_color).a; wf::color_t color = wf::color_t{ diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/blinds.hpp wayfire-plugins-extra/src/extra-animations/blinds.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/blinds.hpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/blinds.hpp 2026-08-01 16:00:35.433998821 -0600 @@ -82,14 +82,8 @@ using namespace wf::animation; static std::string blinds_transformer_name = "animation-blinds"; -wf::option_wrapper_t blinds_duration{"extra-animations/blinds_duration"}; wf::option_wrapper_t blinds_strip_height{"extra-animations/blinds_strip_height"}; -class blinds_animation_t : public duration_t -{ - public: - using duration_t::duration_t; -}; class blinds_transformer : public wf::scene::view_2d_transformer_t { public: @@ -97,7 +91,7 @@ class blinds_transformer : public wf::sc OpenGL::program_t program; wf::output_t *output; wf::geometry_t animation_geometry; - blinds_animation_t progression{blinds_duration}; + duration_t progression; class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t { @@ -128,7 +122,7 @@ class blinds_transformer : public wf::sc void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { instructions.push_back(render_instruction_t{ .instance = this, @@ -137,9 +131,9 @@ class blinds_transformer : public wf::sc }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { - damage |= wf::region_t{self->animation_geometry}; + damage |= self->animation_geometry; } void render(const wf::scene::render_instruction_t& data) override @@ -163,17 +157,17 @@ class blinds_transformer : public wf::sc auto y = src_box.height - i; auto inv_h = 1.0 / src_box.height; uv.push_back(1.0); - uv.push_back(std::max(0, y - line_height) * inv_h); + uv.push_back(std::max(0.0, y - line_height) * inv_h); uv.push_back(0.0); - uv.push_back(std::max(0, y - line_height) * inv_h); + uv.push_back(std::max(0.0, y - line_height) * inv_h); uv.push_back(0.0); uv.push_back(y * inv_h); uv.push_back(1.0); uv.push_back(y * inv_h); auto x1 = src_box.width / 2.0; auto x2 = -(src_box.width / 2.0); - auto y1 = -(std::min(src_box.height - i, line_height) / 2.0); - auto y2 = std::min(src_box.height - i, line_height) / 2.0; + auto y1 = -(std::min(src_box.height - i, (double)line_height) / 2.0); + auto y2 = std::min(src_box.height - i, (double)line_height) / 2.0; glm::vec4 v, r; glm::mat4 m(1.0); m = @@ -208,13 +202,14 @@ class blinds_transformer : public wf::sc glm::mat4 p = glm::perspective(float(M_PI / 64.0), 1.0f, 0.1f, 100.0f); glm::mat4 l = glm::lookAt( - glm::vec3(0., 0., 1.0 / std::tan(float(M_PI / 64.0) / 2)), + glm::vec3(0., 0., -1.0 / std::tan(float(M_PI / 64.0) / 2)), glm::vec3(0., 0., 0.), - glm::vec3(0., 1., 0.)); + glm::vec3(0., -1., 0.)); auto transform = p * l; wf::auxilliary_buffer_t slice_buffer; - slice_buffer.allocate({src_box.width + line_height * 2, static_cast(y2 - y1)}); + slice_buffer.allocate({static_cast(std::ceil(src_box.width + line_height * 2)), + static_cast(std::ceil(y2 - y1))}); wf::gles::bind_render_buffer(slice_buffer.get_renderbuffer()); OpenGL::clear(wf::color_t{0.0, 0.0, 0.0, 0.0}, GL_COLOR_BUFFER_BIT); self->program.use(wf::TEXTURE_TYPE_RGBA); @@ -227,16 +222,17 @@ class blinds_transformer : public wf::sc wf::gles_texture_t slice_tex{slice_buffer.get_texture()}; wf::gles::bind_render_buffer(data.target); - for (auto box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::render_transformed_texture(slice_tex, - gl_geometry{float(src_box.x - line_height), - float(src_box.y + i), - float((src_box.x - line_height) + src_box.width + line_height * 2.0), - float((src_box.y + i) + (y2 - y1))}, {}, - wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); - } + /* XXX: Scissoring wrong boxes here makes only top part of effect work */ + // for (auto box : data.damage) + // { + // wf::gles::render_target_logic_scissor(data.target, box); + OpenGL::render_transformed_texture(slice_tex, + gl_geometry{float(src_box.x - line_height), + float(src_box.y + i), + float((src_box.x - line_height) + src_box.width + line_height * 2.0), + float((src_box.y + i) + (y2 - y1))}, {}, + wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); + // } slice_buffer.free(); } @@ -244,9 +240,12 @@ class blinds_transformer : public wf::sc } }; - blinds_transformer(wayfire_view view, wf::geometry_t bbox) : wf::scene::view_2d_transformer_t(view) + blinds_transformer(wayfire_view view, wf::geometry_t bbox, wf::animation_description_t duration) : + wf::scene::view_2d_transformer_t(view) { this->view = view; + duration_t d; + this->progression = duration_t{wf::create_option(duration)}; if (view->get_output()) { output = view->get_output(); @@ -263,11 +262,6 @@ class blinds_transformer : public wf::sc }); } - wf::geometry_t get_bounding_box() override - { - return this->animation_geometry; - } - wf::effect_hook_t pre_hook = [=] () { output->render->damage(animation_geometry); @@ -316,7 +310,7 @@ class blinds_animation : public animatio pop_transformer(view); auto bbox = view->get_transformed_node()->get_bounding_box(); auto tmgr = view->get_transformed_node(); - auto node = std::make_shared(view, bbox); + auto node = std::make_shared(view, bbox, dur); tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, blinds_transformer_name); node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/burn.hpp wayfire-plugins-extra/src/extra-animations/burn.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/burn.hpp 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/src/extra-animations/burn.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -0,0 +1,451 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2025 Scott Moreau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + + +static const char *burn_vert_source = + R"( +#version 100 + +attribute highp vec2 position; +attribute highp vec2 uv_in; + +varying highp vec2 uvpos; + +void main() { + + gl_Position = vec4(position.xy, 0.0, 1.0); + uvpos = uv_in; +} +)"; + +static const char *burn_frag_source = + R"( +#version 100 +@builtin_ext@ +@builtin@ + +precision highp float; + +varying highp vec2 uvpos; +uniform vec2 size; +uniform float progress; +uniform int direction; +uniform float flame_speed; +uniform float flame_width; +uniform float flame_height; +uniform int flame_smooth_1; +uniform int flame_smooth_2; +uniform int flame_smooth_3; +uniform int flame_smooth_4; +uniform vec4 flame_color; + +// procedural noise from IQ +vec2 hash( vec2 p ) +{ + p = vec2(dot(p,vec2(127.1,311.7)), + dot(p,vec2(269.5,183.3))); + return -1.0 + 2.0 * fract(sin(p) * 43758.5453123); +} + +float noise( in vec2 p ) +{ + const float K1 = 0.366025404; // (sqrt(3) - 1) / 2; + const float K2 = 0.211324865; // (3 - sqrt(3)) / 6; + + vec2 i = floor( p + (p.x + p.y) * K1 ); + + vec2 a = p - i + (i.x + i.y) * K2; + vec2 o = (a.x > a.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + vec2 b = a - o + K2; + vec2 c = a - 1.0 + 2.0 * K2; + + vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c) ), 0.0); + + vec3 n = h * h * h * h * vec3(dot(a, hash(i)), dot(b, hash(i + o)), dot(c, hash(i + 1.0))); + + return dot(n, vec3(70.0)); +} + +float fbm(vec2 uv) +{ + float f; + mat2 m = mat2(1.7, 1.2, -1.2, 1.7); + f = 0.5000 * noise( uv ); uv = m * uv; + if (flame_smooth_1 == 1) + { + f += 0.2500 * noise( uv ); uv = m * uv; + } + if (flame_smooth_2 == 1) + { + f += 0.1250 * noise( uv ); uv = m * uv; + } + if (flame_smooth_3 == 1) + { + f += 0.0625 * noise( uv ); uv = m * uv; + } + if (flame_smooth_4 == 1) + { + f += 0.0125 * noise( uv ); uv = m * uv; + } + return 0.5 + 0.3 * f; +} + +void main() +{ + float width = size.x; + float height = size.y; + vec2 uv = vec2(uvpos.x * width * 0.02, (uvpos.y - progress) * height * 0.002); + vec2 q = vec2(uv.x, uv.y); + q.x *= (1.05 - flame_width) * 3.0; + q.y *= pow(0.4 / ((flame_height * 0.3) + 0.1), clamp(uvpos.y + 0.2 - progress, 0.1, 0.7) * 20.0); + float burn_progress = progress; + if (direction == 1) + { + burn_progress = 1.0 - burn_progress; + } + float T3 = burn_progress * flame_speed; + q.x -= 0.2; + q.y -= 0.1; + float n = fbm(q - vec2(0, T3)); + float c = 1.0 - 12.0 * pow(max(0., length(vec2(q.x * 0.0001, q.y) * vec2(1.8 + q.y * 1.5, 0.75) ) - n * max(0.0, q.y + 0.25)), 1.2); + float c1 = n * c * (1.5 - pow(1.25 * uv.y, 4.0)); + c = clamp(c, 0.0, 1.0); + c1 = clamp(c1, 0.0, 1.0); + + float r = 1.0 / flame_color.r; + float g = 1.0 / flame_color.g; + float b = 1.0 / flame_color.b; + + vec3 col = vec3(1.5 * pow(c1, r), 1.5 * pow(c1, g), 1.5 * pow(c1, b)); + + float a = clamp(c * (1.0 - pow(uvpos.y, 10.0)), 0.0, 1.0); + vec4 wfrag = get_pixel(uvpos); + if (uvpos.x < 0.0 || uvpos.x > 1.0 || + uvpos.y < 0.0 || uvpos.y > 1.0 || + uvpos.y < progress) + { + wfrag = vec4(0.0); + } + a *= clamp(progress * 10.0, 0.0, 1.0); + a *= 1.0 - pow(clamp(-uvpos.x * (width * 0.05), 0.0, 1.0), 0.7); + a *= 1.0 - pow(clamp((1.0 - (2.0 - uvpos.x)) * (width * 0.05), 0.0, 1.0), 0.7); + vec4 color = vec4(col * a, a); + gl_FragColor = color + wfrag * (1.0 - a); +} +)"; + +namespace wf +{ +namespace burn +{ +using namespace wf::scene; +using namespace wf::animate; +using namespace wf::animation; + +static std::string burn_transformer_name = "animation-burn"; + +wf::option_wrapper_t burn_flame_speed{"extra-animations/burn_flame_speed"}; +wf::option_wrapper_t burn_flame_width{"extra-animations/burn_flame_width"}; +wf::option_wrapper_t burn_flame_height{"extra-animations/burn_flame_height"}; +wf::option_wrapper_t burn_flame_color{"extra-animations/burn_flame_color"}; +wf::option_wrapper_t burn_flame_smoothness{"extra-animations/burn_flame_smoothness"}; + +class burn_transformer : public wf::scene::view_2d_transformer_t +{ + public: + wayfire_view view; + wf::output_t *output; + OpenGL::program_t program; + wf::auxilliary_buffer_t buffer; + duration_t progression; + + class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t + { + wf::signal::connection_t on_node_damaged = + [=] (node_damage_signal *ev) + { + push_to_parent(ev->region); + }; + + burn_transformer *self; + wayfire_view view; + damage_callback push_to_parent; + + public: + simple_node_render_instance_t(burn_transformer *self, damage_callback push_damage, + wayfire_view view) : wf::scene::transformer_render_instance_t(self, + push_damage, + view->get_output()) + { + this->self = self; + this->view = view; + this->push_to_parent = push_damage; + self->connect(&on_node_damaged); + } + + ~simple_node_render_instance_t() + {} + + void schedule_instructions( + std::vector& instructions, + const wf::render_target_t& target, wf::regionf_t& damage) override + { + instructions.push_back(render_instruction_t{ + .instance = this, + .target = target, + .damage = damage & self->get_bounding_box(), + }); + } + + void transform_damage_region(wf::regionf_t& damage) override + { + damage |= self->get_bounding_box(); + } + + void render(const wf::scene::render_instruction_t& data) override + { + auto bb = self->get_children_bounding_box(); + auto pbb = self->get_padded_bounding_box(); + auto tex = wf::gles_texture_t{get_texture(1.0)}; + + const float vertices[] = { + -1.0, -1.0, + 1.0f, -1.0, + 1.0f, 1.0f, + -1.0, 1.0f + }; + wf::pointf_t offset1{-float(bb.x - pbb.x) / bb.width, + -float(pbb.height - ((bb.y - pbb.y) + bb.height)) / bb.height}; + wf::pointf_t offset2{float(pbb.width) / bb.width + offset1.x, + float(pbb.height) / bb.height + offset1.y}; + const float uv[] = { + float(offset1.x), float(offset2.y), + float(offset2.x), float(offset2.y), + float(offset2.x), float(offset1.y), + float(offset1.x), float(offset1.y), + }; + auto progress = self->progression.progress(); + + data.pass->custom_gles_subpass([&] + { + self->buffer.allocate({int(pbb.width), int(pbb.height)}); + wf::gles::bind_render_buffer(self->buffer.get_renderbuffer()); + wf::gles_texture_t final_tex{self->buffer.get_texture()}; + OpenGL::clear(wf::color_t{0.0, 0.0, 0.0, 0.0}, GL_COLOR_BUFFER_BIT); + self->program.use(wf::TEXTURE_TYPE_RGBA); + self->program.attrib_pointer("position", 2, 0, vertices); + self->program.attrib_pointer("uv_in", 2, 0, uv); + self->program.uniform2f("size", bb.width * 1.0, bb.height * 1.0); + self->program.uniform1f("progress", 1.0 - progress); + self->program.uniform1i("direction", self->progression.get_direction()); + self->program.uniform1f("flame_speed", burn_flame_speed); + self->program.uniform1f("flame_width", burn_flame_width); + self->program.uniform1f("flame_height", burn_flame_height); + if (std::string(burn_flame_smoothness) == "softest") + { + self->program.uniform1i("flame_smooth_1", 0); + self->program.uniform1i("flame_smooth_2", 0); + self->program.uniform1i("flame_smooth_3", 0); + self->program.uniform1i("flame_smooth_4", 0); + } else if (std::string(burn_flame_smoothness) == "soft") + { + self->program.uniform1i("flame_smooth_1", 0); + self->program.uniform1i("flame_smooth_2", 1); + self->program.uniform1i("flame_smooth_3", 1); + self->program.uniform1i("flame_smooth_4", 1); + } else if (std::string(burn_flame_smoothness) == "hard") + { + self->program.uniform1i("flame_smooth_1", 1); + self->program.uniform1i("flame_smooth_2", 1); + self->program.uniform1i("flame_smooth_3", 1); + self->program.uniform1i("flame_smooth_4", 1); + } else // "normal" + { + self->program.uniform1i("flame_smooth_1", 1); + self->program.uniform1i("flame_smooth_2", 0); + self->program.uniform1i("flame_smooth_3", 1); + self->program.uniform1i("flame_smooth_4", 0); + } + + glm::vec4 flame_color{ + wf::color_t(burn_flame_color).r, + wf::color_t(burn_flame_color).g, + wf::color_t(burn_flame_color).b, + wf::color_t(burn_flame_color).a}; + self->program.uniform4f("flame_color", flame_color); + + self->program.set_active_texture(tex); + GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); + + wf::gles::bind_render_buffer(data.target); + for (auto box : data.damage) + { + wf::gles::render_target_logic_scissor(data.target, box); + OpenGL::render_transformed_texture(final_tex, pbb, + wf::gles::render_target_orthographic_projection(data.target), + glm::vec4(1.0, 1.0, 1.0, std::clamp((progress - 0.07) * 10.0, 0.0, 1.0)), 0); + } + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + self->program.deactivate(); + self->buffer.free(); + }); + } + }; + + burn_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) + { + this->view = view; + this->progression = duration_t{wf::create_option(duration)}; + if (view->get_output()) + { + output = view->get_output(); + output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); + } + + wf::gles::run_in_context([&] + { + program.compile(burn_vert_source, burn_frag_source); + }); + } + + wf::geometry_t get_padded_bounding_box() + { + auto box = this->get_children_bounding_box(); + auto padding = 50; + box.x -= padding; + box.y -= padding; + box.width += padding * 2; + box.height += padding * 2; + return box; + } + + wf::effect_hook_t pre_hook = [=] () + { + output->render->damage(this->get_bounding_box()); + }; + + void gen_render_instances(std::vector& instances, + damage_callback push_damage, wf::output_t *shown_on) override + { + instances.push_back(std::make_unique( + this, push_damage, view)); + } + + void init_animation(bool burn) + { + if (burn) + { + this->progression.reverse(); + } + + this->progression.start(); + } + + virtual ~burn_transformer() + { + if (output) + { + output->render->rem_effect(&pre_hook); + } + + wf::gles::run_in_context_if_gles([&] + { + program.free_resources(); + }); + } +}; + +class burn_animation : public animation_base_t +{ + wayfire_view view; + + public: + void init(wayfire_view view, wf::animation_description_t dur, animation_type type) override + { + this->view = view; + pop_transformer(view); + auto bbox = view->get_transformed_node()->get_bounding_box(); + auto tmgr = view->get_transformed_node(); + auto node = std::make_shared(view, bbox, dur); + tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, burn_transformer_name); + node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); + } + + void pop_transformer(wayfire_view view) + { + if (view->get_transformed_node()->get_transformer(burn_transformer_name)) + { + view->get_transformed_node()->rem_transformer(burn_transformer_name); + } + } + + bool step() override + { + if (!view) + { + return false; + } + + auto tmgr = view->get_transformed_node(); + if (!tmgr) + { + return false; + } + + if (auto tr = + tmgr->get_transformer(burn_transformer_name)) + { + auto running = tr->progression.running(); + if (!running) + { + pop_transformer(view); + return false; + } + + return running; + } + + return false; + } + + void reverse() override + { + if (auto tr = + view->get_transformed_node()->get_transformer( + burn_transformer_name)) + { + tr->progression.reverse(); + } + } +}; +} +} diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/carpet.hpp wayfire-plugins-extra/src/extra-animations/carpet.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/carpet.hpp 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/src/extra-animations/carpet.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -0,0 +1,584 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2025 Scott Moreau + * Copyright (c) 2025 Andrew Pliatsikas + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + + +static const char *carpet_vert_source = + R"( +#version 100 + +attribute highp vec2 position; +attribute highp vec2 uv_in; + +varying highp vec2 uvpos_var; + +void main() { + + gl_Position = vec4(position.xy, 0.0, 1.0); + uvpos_var = uv_in; +} +)"; + +static const char *carpet_frag_source = + R"( +#version 100 +@builtin_ext@ +@builtin@ + +precision highp float; + +varying highp vec2 uvpos_var; + +uniform float progress; +uniform int direction; + +#define M_PI 3.1415926535897932384626433832795 + +// Original single roll effect +vec4 single_roll(vec2 uvpos_var, float progress, int direction) +{ + vec4 wfrag; + vec2 uv; + vec2 uvpos; + if (direction == 1) // right + { + uvpos = vec2(1.0 - uvpos_var.x, uvpos_var.y); + } else if (direction == 2) // top + { + uvpos = vec2(1.0 - uvpos_var.y, uvpos_var.x); + } else if (direction == 3) // bottom + { + uvpos = vec2(uvpos_var.y, uvpos_var.x); + } else // left + { + uvpos = uvpos_var; + } + float offset = 0.1; + float p = progress * 1.2 - 0.2; + + // initial color (transparent) + wfrag = vec4(0.0); + // get pixel from default position if left of peel line + if (uvpos.x < p + offset + 0.05) + { + if (uvpos_var.x >= 0.0 && uvpos_var.x <= 1.0 && + uvpos_var.y >= 0.0 && uvpos_var.y <= 1.0) + { + // sample the texture, but only if within 0-1 range to avoid clamping + wfrag = get_pixel(uvpos_var); + } + } + // back of roll + if (uvpos.x > p + offset + 0.05 && uvpos.x < p + offset + 0.1) + { + // trigonometric sine + float tsin = (uvpos.x - (p + offset + 0.05)) * 20.0; + // angle from arcsine + float angle = asin(tsin); + // compute x sampling coordinate + if (direction == 0 || direction == 1) + { + uv.x = (angle / (M_PI)) * 0.15 + p + offset + 0.05; + } else + { + uv.x = (uvpos.y - 0.5) * pow(cos(angle), 0.02) + 0.5; + } + // compute y sampling coordinate + if (direction == 2 || direction == 3) + { + uv.y = (angle / (M_PI)) * 0.15 + p + offset + 0.05; + } else + { + uv.y = (uvpos.y - 0.5) * pow(cos(angle), 0.02) + 0.5; + } + vec4 pfrag = vec4(0.0); + if (uv.x >= 0.0 && uv.x <= 1.0 && + uv.y >= 0.0 && uv.y <= 1.0) + { + // sample the texture, but only if within 0-1 range to avoid clamping + if (direction == 1) + { + pfrag = get_pixel(vec2(1.0 - uv.x, uv.y)); + } else if (direction == 2) + { + pfrag = get_pixel(vec2(uv.x, 1.0 - uv.y)); + } else + { + pfrag = get_pixel(uv); + } + } + // store color for fragment mixing with current fragment if translucent + wfrag = mix(pfrag, wfrag, wfrag.a); + } + // front of roll + if (uvpos.x > p + offset && uvpos.x < p + offset + 0.1) + { + // trigonometric sine + float tsin = (uvpos.x - (p + offset + 0.1)) * 20.0 + 1.0; + // angle from arcsine + float angle = asin(tsin); + // compute x sampling coordinate + if (direction == 0 || direction == 1) + { + uv.x = (angle / (-M_PI)) * 0.1 + p + offset + 0.2; + } else + { + uv.x = (uvpos.y - 0.5) * 0.9 * pow(cos(angle), -0.04) + 0.5; + } + // compute y sampling coordinate + if (direction == 2 || direction == 3) + { + uv.y = (angle / (-M_PI)) * 0.1 + p + offset + 0.2; + } else + { + uv.y = (uvpos.y - 0.5) * 0.9 * pow(cos(angle), -0.04) + 0.5; + } + vec4 pfrag = vec4(0.0); + if (uv.x >= 0.0 && uv.x <= 1.0 && + uv.y >= 0.0 && uv.y <= 1.0) + { + // sample the texture, but only if within 0-1 range to avoid clamping + if (direction == 1) + { + pfrag = get_pixel(vec2(1.0 - uv.x, uv.y)); + } else if (direction == 2) + { + pfrag = get_pixel(vec2(uv.x, 1.0 - uv.y)); + } else + { + pfrag = get_pixel(uv); + } + } + // compute lighting + pfrag = vec4(clamp(pfrag.rgb + (angle / -M_PI), 0.0, 1.0), pfrag.a); + // store color for fragment mixing with current fragment if translucent + wfrag = mix(wfrag, pfrag, pfrag.a); + } + + return wfrag; +} + +// Dual scroll effect (both sides rolling toward/from middle) by Phodius +vec4 dual_scroll(vec2 uvpos_var, float progress, int dir) +{ + vec4 wfrag = vec4(0.0); + vec2 uv; + + float coord; + float other_coord; + + // dir 5 = vertical, dir 4 = horizontal + if (dir == 5) + { + coord = uvpos_var.y; + other_coord = uvpos_var.x; + } + else + { + coord = uvpos_var.x; + other_coord = uvpos_var.y; + } + + // Determine which half we're on + bool second_half = (coord > 0.5); + + // Map to local coordinate: 0 at middle, 1 at edge + float local_coord; + if (second_half) + { + local_coord = (coord - 0.5) * 2.0; + } + else + { + local_coord = (0.5 - coord) * 2.0; + } + + float offset = 0.1; + float p = progress * 1.2 - 0.2; + + // Get pixel from default position if before peel line + if (local_coord < p + offset + 0.05) + { + if (uvpos_var.x >= 0.0 && uvpos_var.x <= 1.0 && + uvpos_var.y >= 0.0 && uvpos_var.y <= 1.0) + { + wfrag = get_pixel(uvpos_var); + } + } + + // Back of roll + if (local_coord > p + offset + 0.05 && local_coord < p + offset + 0.1) + { + float tsin = (local_coord - (p + offset + 0.05)) * 20.0; + float angle = asin(tsin); + + float local_sample = (angle / M_PI) * 0.15 + p + offset + 0.05; + + float global_sample; + if (second_half) + { + global_sample = 0.5 + local_sample * 0.5; + } + else + { + global_sample = 0.5 - local_sample * 0.5; + } + + float perp_sample = (other_coord - 0.5) * pow(cos(angle), 0.02) + 0.5; + + if (dir == 5) + { + uv.y = global_sample; + uv.x = perp_sample; + } + else + { + uv.x = global_sample; + uv.y = perp_sample; + } + + vec4 pfrag = vec4(0.0); + if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) + { + pfrag = get_pixel(uv); + } + wfrag = mix(pfrag, wfrag, wfrag.a); + } + + // Front of roll + if (local_coord > p + offset && local_coord < p + offset + 0.1) + { + float tsin = (local_coord - (p + offset + 0.1)) * 20.0 + 1.0; + float angle = asin(tsin); + + float local_sample = (angle / (-M_PI)) * 0.1 + p + offset + 0.2; + + float global_sample; + if (second_half) + { + global_sample = 0.5 + local_sample * 0.5; + } + else + { + global_sample = 0.5 - local_sample * 0.5; + } + + float perp_sample = (other_coord - 0.5) * 0.9 * pow(cos(angle), -0.04) + 0.5; + + if (dir == 5) + { + uv.y = global_sample; + uv.x = perp_sample; + } + else + { + uv.x = global_sample; + uv.y = perp_sample; + } + + vec4 pfrag = vec4(0.0); + if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) + { + pfrag = get_pixel(uv); + } + pfrag = vec4(clamp(pfrag.rgb + (angle / -M_PI), 0.0, 1.0), pfrag.a); + wfrag = mix(wfrag, pfrag, pfrag.a); + } + + return wfrag; +} + +void main() +{ + vec4 wfrag; + + if (direction <= 3) + { + // single roll: left, right, top, bottom + wfrag = single_roll(uvpos_var, progress, direction); + } + else + { + // dual scroll: horizontal or vertical from middle + wfrag = dual_scroll(uvpos_var, progress, direction); + } + + gl_FragColor = wfrag; +} +)"; + +namespace wf +{ +namespace carpet +{ +using namespace wf::scene; +using namespace wf::animate; +using namespace wf::animation; + +static std::string carpet_transformer_name = "animation-carpet"; + +wf::option_wrapper_t carpet_roll_direction{"extra-animations/carpet_roll_direction"}; + +class carpet_transformer : public wf::scene::view_2d_transformer_t +{ + public: + wayfire_view view; + wf::output_t *output; + OpenGL::program_t program; + wf::auxilliary_buffer_t buffer; + duration_t progression; + + class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t + { + wf::signal::connection_t on_node_damaged = + [=] (node_damage_signal *ev) + { + push_to_parent(ev->region); + }; + + carpet_transformer *self; + wayfire_view view; + damage_callback push_to_parent; + + public: + simple_node_render_instance_t(carpet_transformer *self, damage_callback push_damage, + wayfire_view view) : wf::scene::transformer_render_instance_t(self, + push_damage, + view->get_output()) + { + this->self = self; + this->view = view; + this->push_to_parent = push_damage; + self->connect(&on_node_damaged); + } + + ~simple_node_render_instance_t() + {} + + void schedule_instructions( + std::vector& instructions, + const wf::render_target_t& target, wf::regionf_t& damage) override + { + instructions.push_back(render_instruction_t{ + .instance = this, + .target = target, + .damage = damage & self->get_bounding_box(), + }); + } + + void transform_damage_region(wf::regionf_t& damage) override + { + damage |= self->get_bounding_box(); + } + + void render(const wf::scene::render_instruction_t& data) override + { + auto bb = self->get_children_bounding_box(); + auto pbb = self->get_padded_bounding_box(); + auto tex = wf::gles_texture_t{get_texture(1.0)}; + + const float vertices[] = { + -1.0, -1.0, + 1.0f, -1.0, + 1.0f, 1.0f, + -1.0, 1.0f + }; + wf::pointf_t offset1{-float(bb.x - pbb.x) / bb.width, + -float(pbb.height - ((bb.y - pbb.y) + bb.height)) / bb.height}; + wf::pointf_t offset2{float(pbb.width) / bb.width + offset1.x, + float(pbb.height) / bb.height + offset1.y}; + const float uv[] = { + float(offset1.x), float(offset2.y), + float(offset2.x), float(offset2.y), + float(offset2.x), float(offset1.y), + float(offset1.x), float(offset1.y), + }; + auto progress = self->progression.progress(); + + data.pass->custom_gles_subpass([&] + { + self->buffer.allocate({int(pbb.width), int(pbb.height)}); + wf::gles::bind_render_buffer(self->buffer.get_renderbuffer()); + wf::gles_texture_t final_tex{self->buffer.get_texture()}; + OpenGL::clear(wf::color_t{0.0, 0.0, 0.0, 0.0}, GL_COLOR_BUFFER_BIT); + self->program.use(wf::TEXTURE_TYPE_RGBA); + self->program.attrib_pointer("position", 2, 0, vertices); + self->program.attrib_pointer("uv_in", 2, 0, uv); + self->program.uniform1f("progress", progress); + self->program.uniform1i("direction", carpet_roll_direction); + + self->program.set_active_texture(tex); + GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); + + wf::gles::bind_render_buffer(data.target); + for (auto box : data.damage) + { + wf::gles::render_target_logic_scissor(data.target, box); + OpenGL::render_transformed_texture(final_tex, pbb, + wf::gles::render_target_orthographic_projection(data.target), + glm::vec4(1.0, 1.0, 1.0, 1.0), 0); + } + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + self->program.deactivate(); + self->buffer.free(); + }); + } + }; + + carpet_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) + { + this->view = view; + this->progression = duration_t{wf::create_option(duration)}; + if (view->get_output()) + { + output = view->get_output(); + output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); + } + + wf::gles::run_in_context([&] + { + program.compile(carpet_vert_source, carpet_frag_source); + }); + } + + wf::geometry_t get_padded_bounding_box() + { + auto box = this->get_children_bounding_box(); + auto padding = (box.width > box.height ? box.width : box.height) * 0.07; + box.x -= padding; + box.y -= padding; + box.width += padding * 2; + box.height += padding * 2; + return box; + } + + wf::effect_hook_t pre_hook = [=] () + { + output->render->damage(this->get_bounding_box()); + }; + + void gen_render_instances(std::vector& instances, + damage_callback push_damage, wf::output_t *shown_on) override + { + instances.push_back(std::make_unique( + this, push_damage, view)); + } + + void init_animation(bool carpet) + { + if (carpet) + { + this->progression.reverse(); + } + + this->progression.start(); + } + + virtual ~carpet_transformer() + { + if (output) + { + output->render->rem_effect(&pre_hook); + } + + wf::gles::run_in_context_if_gles([&] + { + program.free_resources(); + }); + } +}; + +class carpet_animation : public animation_base_t +{ + wayfire_view view; + + public: + void init(wayfire_view view, wf::animation_description_t dur, animation_type type) override + { + this->view = view; + pop_transformer(view); + auto bbox = view->get_transformed_node()->get_bounding_box(); + auto tmgr = view->get_transformed_node(); + auto node = std::make_shared(view, bbox, dur); + tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, carpet_transformer_name); + node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); + } + + void pop_transformer(wayfire_view view) + { + if (view->get_transformed_node()->get_transformer(carpet_transformer_name)) + { + view->get_transformed_node()->rem_transformer(carpet_transformer_name); + } + } + + bool step() override + { + if (!view) + { + return false; + } + + auto tmgr = view->get_transformed_node(); + if (!tmgr) + { + return false; + } + + if (auto tr = + tmgr->get_transformer(carpet_transformer_name)) + { + auto running = tr->progression.running(); + if (!running) + { + pop_transformer(view); + return false; + } + + return running; + } + + return false; + } + + void reverse() override + { + if (auto tr = + view->get_transformed_node()->get_transformer( + carpet_transformer_name)) + { + tr->progression.reverse(); + } + } +}; +} +} diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/dodge.hpp wayfire-plugins-extra/src/extra-animations/dodge.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/dodge.hpp 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/src/extra-animations/dodge.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -0,0 +1,550 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2025 Scott Moreau + * Copyright (c) 2025 Andrew Pliatsikas + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace wf +{ +namespace dodge +{ +static std::string dodge_transformer_name = "dodge"; + +struct dodge_view_data +{ + wayfire_view view; + wf::geometry_t from_bb, to_bb; + std::shared_ptr transformer; + wf::pointf_t direction; +}; + +bool boxes_intersect(const wayfire_view & a, const wayfire_view & b) +{ + auto ao = a->get_output(); + auto bo = b->get_output(); + if (!ao || !bo || (ao != bo)) + { + return false; + } + + auto a_bb = wf::toplevel_cast(a)->get_geometry(); + auto b_bb = wf::toplevel_cast(b)->get_geometry(); + return !(b_bb.x > a_bb.x + a_bb.width || + a_bb.x > b_bb.x + b_bb.width || + b_bb.y > a_bb.y + a_bb.height || + a_bb.y > b_bb.y + b_bb.height); +} + +class wayfire_dodge +{ + std::vector views_from; + std::list minimized_views; + wayfire_view view_to, last_focused_view; + wf::option_wrapper_t dodge_zoom{"extra-animations/dodge_zoom"}; + wf::option_wrapper_t dodge_rotate{"extra-animations/dodge_rotate"}; + wf::option_wrapper_t direction{"extra-animations/dodge_direction"}; + wf::option_wrapper_t animation_duration{"extra-animations/dodge_duration"}; + wf::animation::simple_animation_t progression{animation_duration}; + bool view_to_focused; + wf::output_t *view_to_output; + bool hook_set = false; + bool view_unminimized = false; + bool from_mapped_event = false; + bool from_unmapped_event = false; + std::vector outputs; + + public: + void init() + { + wf::get_core().connect(&view_mapped); + wf::get_core().connect(&view_unmapped); + this->progression.set(0, 0); + for (auto& view : wf::get_core().get_all_views()) + { + if (wf::toplevel_cast(view)) + { + view->connect(&view_activated); + view->get_output()->connect(&view_minimize_request); + if (std::find_if(outputs.begin(), outputs.end(), [=] (wf::output_t*& o) + { + return view->get_output() == o; + }) == outputs.end()) + { + outputs.push_back(view->get_output()); + } + } + } + + for (auto output : outputs) + { + output->connect(&view_minimize_request); + } + } + + wf::signal::connection_t view_minimize_request = + [=] (wf::view_minimize_request_signal *ev) + { + if (ev->state) + { + minimized_views.push_back(ev->view); + } else + { + minimized_views.remove(ev->view); + view_unminimized = true; + wf::view_activated_state_signal data; + data.view = ev->view; + view_activated.emit(&data); + } + }; + + wf::signal::connection_t view_activated = + [=] (wf::view_activated_state_signal *ev) + { + if (ev->view == wf::get_core().seat->get_active_view()) + { + last_focused_view = wf::get_core().seat->get_active_view(); + if (!from_mapped_event) + { + return; + } + } + + if (from_unmapped_event) + { + from_unmapped_event = false; + return; + } + + view_to = ev->view; + + auto toplevel = wf::toplevel_cast(view_to); + if (!toplevel) + { + return; + } + + if (!last_focused_view || !view_to || !view_to->is_mapped() || + toplevel->parent) + { + return; + } + + auto to_bb = toplevel->get_geometry(); + + if (from_mapped_event) + { + view_bring_to_front(view_to); + } + + /* Find overlapping views */ + std::vector overlapping_views; + auto all_views = wf::get_core().get_all_views(); + std::sort(all_views.begin(), all_views.end(), [] (const wayfire_view& a, const wayfire_view& b) + { + return wf::get_focus_timestamp(a) < wf::get_focus_timestamp(b); + }); + for (auto& view : all_views) + { + if (!view || !view->is_mapped()) + { + continue; + } + + toplevel = wf::toplevel_cast(view); + if (!toplevel) + { + continue; + } + + if ((wf::get_focus_timestamp(view_to) < wf::get_focus_timestamp(view)) || + ((from_mapped_event || view_unminimized) && + (wf::get_focus_timestamp(view_to) > wf::get_focus_timestamp(view)))) + { + if ((boxes_intersect(view, view_to) || from_mapped_event || + view->get_transformed_node()->get_transformer( + dodge_transformer_name)) && + (std::find_if(minimized_views.begin(), minimized_views.end(), + [view] (const wayfire_view& v) { return v == view; }) == minimized_views.end())) + { + overlapping_views.push_back(view); + view_bring_to_front(view); + } + } + + if (!from_mapped_event) + { + view_bring_to_front(view); + } + } + + view_unminimized = false; + + if (overlapping_views.empty()) + { + return; + } + + if (!hook_set) + { + view_to_output = view_to->get_output(); + view_to_output->render->add_effect(&dodge_animation_hook, wf::OUTPUT_EFFECT_PRE); + hook_set = true; + } + + view_to_focused = false; + if (!this->progression.running()) + { + views_from.clear(); + this->progression.animate(0, 1); + } + + for (size_t i = 0; i < overlapping_views.size(); i++) + { + dodge_view_data view_data; + view_data.view = overlapping_views[i]; + + view_data.from_bb = view_data.view->get_bounding_box(); + view_data.to_bb = view_to->get_bounding_box(); + + bool view_found = false; + for (auto vd : views_from) + { + if (vd.view == view_data.view) + { + view_found = true; + if (dodge_rotate && from_mapped_event) + { + auto direction = compute_direction(view_data.from_bb, to_bb); + vd.direction.x = direction.x; + vd.direction.y = direction.y; + vd.transformer->angle = 0.1; + } + + break; + } + } + + if (view_found) + { + continue; + } + + if (auto tr = + view_data.view->get_transformed_node()->get_transformer( + dodge_transformer_name)) + { + view_data.transformer = tr; + if (dodge_rotate && from_mapped_event) + { + view_data.transformer->angle = 0.1; + } + } else + { + view_data.transformer = std::make_shared(view_data.view); + view_data.view->get_transformed_node()->add_transformer(view_data.transformer, + wf::TRANSFORMER_2D, + dodge_transformer_name); + auto d = compute_direction(view_data.from_bb, to_bb); + view_data.direction.x = d.x; + view_data.direction.y = d.y; + + auto & x = view_data.direction.x; + auto & y = view_data.direction.y; + if ((((x < 0.001) && (x > -0.001)) && ((y < 0.001) && (y > -0.001))) || std::isnan(x) || + std::isnan(y)) + { + if ((std::string(direction) == "cardinal") || (std::string(direction) == "diagonal")) + { + srand(wf::get_current_time() + rand()); + x = (rand() % 2) * 2 - 1; + srand(wf::get_current_time() + rand()); + y = (rand() % 2) * 2 - 1; + } else if (std::string(direction) == "circular") + { + srand(wf::get_current_time() + rand()); + x = (double(rand()) / RAND_MAX) * 2.0 - 1.0; + srand(wf::get_current_time() + rand()); + y = (double(rand()) / RAND_MAX) * 2.0 - 1.0; + } + } + + if (dodge_rotate) + { + view_data.transformer->angle = 0.1; + } + } + + views_from.push_back(view_data); + } + + from_mapped_event = false; + }; + + wf::signal::connection_t view_mapped = + [=] (wf::view_mapped_signal *ev) + { + from_mapped_event = true; + ev->view->connect(&view_activated); + if (std::find_if(outputs.begin(), outputs.end(), [=] (wf::output_t*& o) + { + return ev->view->get_output() == o; + }) == outputs.end()) + { + ev->view->get_output()->connect(&view_minimize_request); + outputs.push_back(ev->view->get_output()); + } + }; + + wf::signal::connection_t view_unmapped = + [=] (wf::view_unmapped_signal *ev) + { + from_unmapped_event = true; + last_focused_view = wf::get_core().seat->get_active_view(); + if (ev->view == view_to) + { + view_bring_to_front(view_to); + view_to = nullptr; + } + + if (ev->view == last_focused_view) + { + last_focused_view = nullptr; + } + + views_from.erase(std::remove_if(views_from.begin(), views_from.end(), + [ev] (const dodge_view_data& data) + { + return data.view == ev->view; + }), views_from.end()); + }; + + double magnitude(int x, int y) + { + return std::sqrt(x * x + y * y); + } + + wf::pointf_t compute_direction(wf::geometry_t from_bb, wf::geometry_t to_bb) + { + auto from_center = wf::pointf_t{from_bb.x + from_bb.width / 2, from_bb.y + from_bb.height / 2}; + auto to_center = wf::pointf_t{to_bb.x + to_bb.width / 2, to_bb.y + to_bb.height / 2}; + auto x = double(from_center.x - to_center.x); + auto y = double(from_center.y - to_center.y); + auto m = magnitude(x, y); + if (m == 0) + { + return wf::pointf_t{0, 0}; + } + + x /= m; + y /= m; + if (std::string(direction) != "circular") + { + x = x * std::abs(1.0 / x); + y = y * std::abs(1.0 / y); + } + + return wf::pointf_t{x, y}; + } + + void damage_views() + { + for (auto& view_data : views_from) + { + view_data.view->damage(); + } + + if (view_to) + { + view_to->damage(); + } + } + + void finish_animation() + { + for (auto& view : wf::get_core().get_all_views()) + { + view->get_transformed_node()->rem_transformer(dodge_transformer_name); + } + + if (hook_set) + { + view_to_output->render->rem_effect(&dodge_animation_hook); + hook_set = false; + } + + views_from.clear(); + view_to = nullptr; + } + + bool step_animation() + { + if (!view_to) + { + return false; + } + + double progress = progression.progress(); + progress = (1.0 - progress) * (1.0 - progress); + progress = 1.0 - progress; + + std::shared_ptr view_to_transformer; + if (std::find_if(minimized_views.begin(), minimized_views.end(), [&] (const wayfire_view& v) + { + return v == last_focused_view; + }) == minimized_views.end()) + { + if (auto tr = + view_to->get_transformed_node()->get_transformer( + dodge_transformer_name)) + { + view_to_transformer = tr; + } else + { + view_to_transformer = std::make_shared(view_to); + view_to->get_transformed_node()->add_transformer(view_to_transformer, wf::TRANSFORMER_2D, + dodge_transformer_name); + } + } else + { + view_to_focused = true; + } + + if (dodge_zoom && view_to_transformer) + { + view_to_transformer->scale_x = view_to_transformer->scale_y = 1.0 + std::sin( + progression.progress() * M_PI) * 0.02; + } + + for (auto& view_data : views_from) + { + auto to_bb = view_data.to_bb; + auto from_bb = view_data.from_bb; + double move_dist_x = std::min(from_bb.x + from_bb.width - to_bb.x, + to_bb.x + to_bb.width - from_bb.x); + double move_dist_y = std::min(from_bb.y + from_bb.height - to_bb.y, + to_bb.y + to_bb.height - from_bb.y); + + if (dodge_zoom) + { + if (view_data.transformer->scale_x <= 1.0) + { + view_data.transformer->scale_x = view_data.transformer->scale_y = 1.0 - std::sin( + progression.progress() * M_PI) * 0.25; + } else + { + view_data.transformer->scale_x = view_data.transformer->scale_y = 1.0 + std::sin( + progression.progress() * M_PI) * 0.02; + } + } + + if (dodge_rotate && (view_data.transformer->angle != 0.0)) + { + view_data.transformer->angle = progress * M_PI * 2 * (view_data.direction.x > 0 ? 1 : -1); + if (view_data.transformer->angle == 0.0) + { + view_data.transformer->angle = 0.1; + } + } + + if (std::string(direction) == "cardinal") + { + if (move_dist_x < move_dist_y) + { + move_dist_y = 0; + } else + { + move_dist_x = 0; + } + } else if (std::string(direction) == "circular") + { + auto direction_x = std::abs(view_data.direction.x); + auto direction_y = std::abs(view_data.direction.y); + if (direction_x < direction_y) + { + move_dist_x *= direction_x; + auto& y = view_data.direction.y; + y = y * std::abs(1.0 / y); + } else + { + move_dist_y *= direction_y; + auto& x = view_data.direction.x; + x = x * std::abs(1.0 / x); + } + } + + double move_x = move_dist_x * view_data.direction.x; + double move_y = move_dist_y * view_data.direction.y; + + view_data.transformer->translation_x = std::sin(progress * M_PI) * move_x; + view_data.transformer->translation_y = std::sin(progress * M_PI) * move_y; + } + + if ((progress > 0.5) && !view_to_focused) + { + wf::get_core().seat->focus_view(view_to); + view_bring_to_front(view_to); + view_to_focused = true; + } + + return progression.running(); + } + + wf::effect_hook_t dodge_animation_hook = [=] () + { + damage_views(); + bool result = step_animation(); + damage_views(); + + if (!result) + { + finish_animation(); + } + }; + + void fini() + { + finish_animation(); + view_mapped.disconnect(); + view_unmapped.disconnect(); + view_activated.disconnect(); + } +}; +} +} diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/helix.hpp wayfire-plugins-extra/src/extra-animations/helix.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/helix.hpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/helix.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -82,15 +82,9 @@ using namespace wf::animation; static std::string transformer_name = "animation-helix"; -wf::option_wrapper_t helix_duration{"extra-animations/helix_duration"}; wf::option_wrapper_t helix_strip_height{"extra-animations/helix_strip_height"}; wf::option_wrapper_t helix_rotations{"extra-animations/helix_rotations"}; -class helix_animation_t : public duration_t -{ - public: - using duration_t::duration_t; -}; class helix_transformer : public wf::scene::view_2d_transformer_t { public: @@ -98,7 +92,7 @@ class helix_transformer : public wf::sce OpenGL::program_t program; wf::output_t *output; wf::geometry_t animation_geometry; - helix_animation_t progression{helix_duration}; + duration_t progression; class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t { @@ -129,7 +123,7 @@ class helix_transformer : public wf::sce void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { instructions.push_back(render_instruction_t{ .instance = this, @@ -138,9 +132,9 @@ class helix_transformer : public wf::sce }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { - damage |= wf::region_t{self->animation_geometry}; + damage |= self->animation_geometry; } void render(const wf::scene::render_instruction_t& data) override @@ -165,9 +159,9 @@ class helix_transformer : public wf::sce auto y = src_box.height - i; auto inv_h = 1.0 / src_box.height; uv.push_back(0.0); - uv.push_back(std::max(0, y - line_height) * inv_h); + uv.push_back(std::max(0.0, y - line_height) * inv_h); uv.push_back(1.0); - uv.push_back(std::max(0, y - line_height) * inv_h); + uv.push_back(std::max(0.0, y - line_height) * inv_h); uv.push_back(0.0); uv.push_back(y * inv_h); uv.push_back(1.0); @@ -175,7 +169,7 @@ class helix_transformer : public wf::sce uv.push_back(0.0); uv.push_back(y * inv_h); uv.push_back(1.0); - uv.push_back(std::max(0, y - line_height) * inv_h); + uv.push_back(std::max(0.0, y - line_height) * inv_h); glm::vec4 v, r; glm::mat4 m(1.0); m = glm::rotate(m, float(M_PI), glm::vec3(1.0, 0.0, 0.0)); @@ -237,7 +231,7 @@ class helix_transformer : public wf::sce wf::gles::bind_render_buffer(data.target); for (auto box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); self->program.use(wf::TEXTURE_TYPE_RGBA); self->program.uniformMatrix4f("matrix", transform); self->program.attrib_pointer("position", 3, 0, vertices.data()); @@ -249,9 +243,11 @@ class helix_transformer : public wf::sce } }; - helix_transformer(wayfire_view view, wf::geometry_t bbox) : wf::scene::view_2d_transformer_t(view) + helix_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) { this->view = view; + this->progression = duration_t{wf::create_option(duration)}; if (view->get_output()) { output = view->get_output(); @@ -318,7 +314,7 @@ class helix_animation : public animation pop_transformer(view); auto bbox = view->get_transformed_node()->get_bounding_box(); auto tmgr = view->get_transformed_node(); - auto node = std::make_shared(view, bbox); + auto node = std::make_shared(view, bbox, dur); tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, transformer_name); node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/melt.hpp wayfire-plugins-extra/src/extra-animations/melt.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/melt.hpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/melt.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -22,9 +22,12 @@ * SOFTWARE. */ +#include #include #include #include +#include +#include static const char *melt_vert_source = @@ -53,10 +56,11 @@ precision highp float; varying highp vec2 uvpos; uniform float time; +uniform float random; uniform float distortion; float rand(vec2 n) { - return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); + return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453 * random); } // Noise function from: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 @@ -95,22 +99,17 @@ using namespace wf::animation; static std::string melt_transformer_name = "animation-melt"; -wf::option_wrapper_t melt_duration{"extra-animations/melt_duration"}; wf::option_wrapper_t melt_distortion_factor{"extra-animations/melt_distortion_factor"}; -class melt_animation_t : public duration_t -{ - public: - using duration_t::duration_t; -}; class melt_transformer : public wf::scene::view_2d_transformer_t { public: wayfire_view view; + float random_number; wf::output_t *output; OpenGL::program_t program; wf::auxilliary_buffer_t buffer; - melt_animation_t progression{melt_duration}; + duration_t progression; class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t { @@ -141,7 +140,7 @@ class melt_transformer : public wf::scen void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { instructions.push_back(render_instruction_t{ .instance = this, @@ -150,14 +149,14 @@ class melt_transformer : public wf::scen }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { damage |= self->get_padded_bounding_box(); } void render(const wf::scene::render_instruction_t& data) override { - auto bb = self->get_bounding_box(); + auto bb = self->get_children_bounding_box(); auto pbb = self->get_padded_bounding_box(); auto tex = wf::gles_texture_t{get_texture(1.0)}; @@ -181,7 +180,7 @@ class melt_transformer : public wf::scen data.pass->custom_gles_subpass([&] { - self->buffer.allocate({pbb.width, pbb.height}); + self->buffer.allocate({int(pbb.width), int(pbb.height)}); wf::gles::bind_render_buffer(self->buffer.get_renderbuffer()); wf::gles_texture_t final_tex{self->buffer.get_texture()}; OpenGL::clear(wf::color_t{0.0, 0.0, 0.0, 0.0}, GL_COLOR_BUFFER_BIT); @@ -189,6 +188,7 @@ class melt_transformer : public wf::scen self->program.attrib_pointer("position", 2, 0, vertices); self->program.attrib_pointer("uv_in", 2, 0, uv); self->program.uniform1f("time", progress); + self->program.uniform1f("random", self->random_number); self->program.uniform1f("distortion", float(melt_distortion_factor)); self->program.set_active_texture(tex); GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); @@ -196,7 +196,7 @@ class melt_transformer : public wf::scen wf::gles::bind_render_buffer(data.target); for (auto box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); OpenGL::render_transformed_texture(final_tex, pbb, wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0, 1.0, 1.0, 1.0 / (1.0 + pow(2.718, -(progress * 15.0 - 3.0)))), 0); @@ -209,9 +209,11 @@ class melt_transformer : public wf::scen } }; - melt_transformer(wayfire_view view, wf::geometry_t bbox) : wf::scene::view_2d_transformer_t(view) + melt_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) { this->view = view; + this->progression = duration_t{wf::create_option(duration)}; if (view->get_output()) { output = view->get_output(); @@ -222,12 +224,15 @@ class melt_transformer : public wf::scen { program.compile(melt_vert_source, melt_frag_source); }); + + srand(wf::get_current_time()); + this->random_number = (rand() % 1000000) / 1000000.0; } wf::geometry_t get_padded_bounding_box() { auto box = this->get_children_bounding_box(); - auto padding = 100; + auto padding = 50; box.x -= padding; box.y -= padding; box.width += padding * 2; @@ -282,7 +287,7 @@ class melt_animation : public animation_ pop_transformer(view); auto bbox = view->get_transformed_node()->get_bounding_box(); auto tmgr = view->get_transformed_node(); - auto node = std::make_shared(view, bbox); + auto node = std::make_shared(view, bbox, dur); tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, melt_transformer_name); node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/plugin.cpp wayfire-plugins-extra/src/extra-animations/plugin.cpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/plugin.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/plugin.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -32,10 +32,23 @@ #include "shatter.hpp" #include "vortex.hpp" #include "melt.hpp" +#include "dodge.hpp" +#include "burn.hpp" +#include "carpet.hpp" class wayfire_extra_animations : public wf::plugin_interface_t { wf::shared_data::ref_ptr_t effects_registry; + wf::option_wrapper_t dodge_toggle{"extra-animations/dodge_toggle"}; + wf::option_wrapper_t blinds_duration{"extra-animations/blinds_duration"}; + wf::option_wrapper_t helix_duration{"extra-animations/helix_duration"}; + wf::option_wrapper_t shatter_duration{"extra-animations/shatter_duration"}; + wf::option_wrapper_t vortex_duration{"extra-animations/vortex_duration"}; + wf::option_wrapper_t melt_duration{"extra-animations/melt_duration"}; + wf::option_wrapper_t burn_duration{"extra-animations/burn_duration"}; + wf::option_wrapper_t carpet_roll_duration{ + "extra-animations/carpet_roll_duration"}; + std::unique_ptr dodge_plugin; public: void init() override @@ -48,24 +61,47 @@ class wayfire_extra_animations : public effects_registry->register_effect("blinds", wf::animate::effect_description_t{ .generator = [] { return std::make_unique(); }, - .default_duration = [=] { return wf::blinds::blinds_duration.value(); }, + .default_duration = [=] { return blinds_duration.value(); }, }); effects_registry->register_effect("helix", wf::animate::effect_description_t{ .generator = [] { return std::make_unique(); }, - .default_duration = [=] { return wf::helix::helix_duration.value(); }, + .default_duration = [=] { return helix_duration.value(); }, }); effects_registry->register_effect("shatter", wf::animate::effect_description_t{ .generator = [] { return std::make_unique(); }, - .default_duration = [=] { return wf::shatter::shatter_duration.value(); }, + .default_duration = [=] { return shatter_duration.value(); }, }); effects_registry->register_effect("vortex", wf::animate::effect_description_t{ .generator = [] { return std::make_unique(); }, - .default_duration = [=] { return wf::vortex::vortex_duration.value(); }, + .default_duration = [=] { return vortex_duration.value(); }, }); effects_registry->register_effect("melt", wf::animate::effect_description_t{ .generator = [] { return std::make_unique(); }, - .default_duration = [=] { return wf::melt::melt_duration.value(); }, + .default_duration = [=] { return melt_duration.value(); }, }); + effects_registry->register_effect("burn", wf::animate::effect_description_t{ + .generator = [] { return std::make_unique(); }, + .default_duration = [=] { return burn_duration.value(); }, + }); + effects_registry->register_effect("carpet", wf::animate::effect_description_t{ + .generator = [] { return std::make_unique(); }, + .default_duration = [=] { return carpet_roll_duration.value(); }, + }); + dodge_toggle.set_callback([=] {dodge_option_changed();}); + dodge_option_changed(); + } + + void dodge_option_changed() + { + if (dodge_toggle && !dodge_plugin) + { + dodge_plugin = std::make_unique(); + dodge_plugin->init(); + } else if (!dodge_toggle && dodge_plugin) + { + dodge_plugin->fini(); + dodge_plugin.reset(); + } } void fini() override @@ -75,6 +111,14 @@ class wayfire_extra_animations : public effects_registry->unregister_effect("shatter"); effects_registry->unregister_effect("vortex"); effects_registry->unregister_effect("melt"); + effects_registry->unregister_effect("burn"); + effects_registry->unregister_effect("carpet"); + + if (dodge_plugin) + { + dodge_plugin->fini(); + dodge_plugin.reset(); + } } }; diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/shatter.hpp wayfire-plugins-extra/src/extra-animations/shatter.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/shatter.hpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/shatter.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -89,14 +89,6 @@ using namespace wf::animation; static std::string shatter_transformer_name = "animation-shatter"; -wf::option_wrapper_t shatter_duration{"extra-animations/shatter_duration"}; - -class shatter_animation_t : public duration_t -{ - public: - using duration_t::duration_t; - timed_transition_t shatter{*this}; -}; class shatter_transformer : public wf::scene::view_2d_transformer_t { public: @@ -104,7 +96,7 @@ class shatter_transformer : public wf::s OpenGL::program_t program; wf::output_t *output; wf::geometry_t animation_geometry; - shatter_animation_t progression{shatter_duration}; + duration_t progression; voronoi_diagram vd; std::vector rotations; std::vector> points; @@ -138,7 +130,7 @@ class shatter_transformer : public wf::s void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { instructions.push_back(render_instruction_t{ .instance = this, @@ -147,9 +139,9 @@ class shatter_transformer : public wf::s }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { - damage |= wf::region_t{self->animation_geometry}; + damage |= self->animation_geometry; } void render(const wf::scene::render_instruction_t& data) override @@ -289,9 +281,11 @@ class shatter_transformer : public wf::s } }; - shatter_transformer(wayfire_view view, wf::geometry_t bbox) : wf::scene::view_2d_transformer_t(view) + shatter_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) { this->view = view; + this->progression = duration_t{wf::create_option(duration)}; if (view->get_output()) { output = view->get_output(); @@ -378,7 +372,7 @@ class shatter_animation : public animati pop_transformer(view); auto bbox = view->get_transformed_node()->get_bounding_box(); auto tmgr = view->get_transformed_node(); - auto node = std::make_shared(view, bbox); + auto node = std::make_shared(view, bbox, dur); tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, shatter_transformer_name); node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/extra-animations/vortex.hpp wayfire-plugins-extra/src/extra-animations/vortex.hpp --- wayfire-plugins-extra-0.10.0/src/extra-animations/vortex.hpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/extra-animations/vortex.hpp 2026-08-01 16:00:35.434368211 -0600 @@ -110,13 +110,6 @@ using namespace wf::animation; static std::string vortex_transformer_name = "animation-vortex"; -wf::option_wrapper_t vortex_duration{"extra-animations/vortex_duration"}; - -class vortex_animation_t : public duration_t -{ - public: - using duration_t::duration_t; -}; class vortex_transformer : public wf::scene::view_2d_transformer_t { public: @@ -124,7 +117,7 @@ class vortex_transformer : public wf::sc OpenGL::program_t program; wf::output_t *output; wf::geometry_t animation_geometry; - vortex_animation_t progression{vortex_duration}; + duration_t progression; class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t { @@ -155,7 +148,7 @@ class vortex_transformer : public wf::sc void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { instructions.push_back(render_instruction_t{ .instance = this, @@ -164,9 +157,9 @@ class vortex_transformer : public wf::sc }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { - damage |= wf::region_t{self->animation_geometry}; + damage |= self->animation_geometry; } void render(const wf::scene::render_instruction_t& data) override @@ -183,13 +176,13 @@ class vortex_transformer : public wf::sc }; const float vertex_data_pos[] = { - 1.0f * src_box.x, - 1.0f * src_box.y + src_box.height, - 1.0f * src_box.x + src_box.width, - 1.0f * src_box.y + src_box.height, - 1.0f * src_box.x + src_box.width, - 1.0f * src_box.y, - 1.0f * src_box.x, 1.0f * src_box.y, + (float)src_box.x, + (float)src_box.y + (float)src_box.height, + (float)src_box.x + (float)src_box.width, + (float)src_box.y + (float)src_box.height, + (float)src_box.x + (float)src_box.width, + (float)src_box.y, + (float)src_box.x, (float)src_box.y, }; data.pass->custom_gles_subpass([&] @@ -207,9 +200,11 @@ class vortex_transformer : public wf::sc } }; - vortex_transformer(wayfire_view view, wf::geometry_t bbox) : wf::scene::view_2d_transformer_t(view) + vortex_transformer(wayfire_view view, wf::geometry_t bbox, + wf::animation_description_t duration) : wf::scene::view_2d_transformer_t(view) { this->view = view; + this->progression = duration_t{wf::create_option(duration)}; if (view->get_output()) { output = view->get_output(); @@ -223,11 +218,6 @@ class vortex_transformer : public wf::sc }); } - wf::geometry_t get_bounding_box() override - { - return this->animation_geometry; - } - wf::effect_hook_t pre_hook = [=] () { output->render->damage(animation_geometry); @@ -275,7 +265,7 @@ class vortex_animation : public animatio pop_transformer(view); auto bbox = view->get_transformed_node()->get_bounding_box(); auto tmgr = view->get_transformed_node(); - auto node = std::make_shared(view, bbox); + auto node = std::make_shared(view, bbox, dur); tmgr->add_transformer(node, wf::TRANSFORMER_HIGHLEVEL + 1, vortex_transformer_name); node->init_animation(type & WF_ANIMATE_HIDING_ANIMATION); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/fisheye.cpp wayfire-plugins-extra/src/fisheye.cpp --- wayfire-plugins-extra-0.10.0/src/fisheye.cpp 1969-12-31 17:00:00.000000000 -0700 +++ wayfire-plugins-extra/src/fisheye.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -0,0 +1,237 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Moreau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +static const char *vertex_shader = + R"( +#version 100 + +attribute highp vec2 position; + +void main() { + + gl_Position = vec4(position.xy, 0.0, 1.0); +} +)"; + +static const char *fragment_shader = + R"( +#version 100 +precision highp float; + +uniform vec2 u_resolution; +uniform vec2 u_mouse; +uniform float u_radius; +uniform float u_zoom; +uniform sampler2D u_texture; + +const float PI = 3.1415926535; + +void main() +{ + float radius = u_radius; + + float zoom = u_zoom; + float pw = 1.0 / u_resolution.x; + float ph = 1.0 / u_resolution.y; + + vec4 p0 = vec4(u_mouse.x, u_resolution.y - u_mouse.y, 1.0 / radius, 0.0); + vec4 p1 = vec4(pw, ph, PI / radius, (zoom - 1.0) * zoom); + vec4 p2 = vec4(0, 0, -PI / 2.0, 0.0); + + vec4 t0, t1, t2, t3; + + vec3 tc = vec3(1.0, 0.0, 0.0); + vec2 uv = vec2(gl_FragCoord.x, gl_FragCoord.y); + + t1 = p0.xyww - vec4(uv, 0.0, 0.0); + t2.x = t2.y = t2.z = t2.w = 1.0 / sqrt(dot(t1.xyz, t1.xyz)); + t0 = t2 - p0; + + t3.x = t3.y = t3.z = t3.w = 1.0 / t2.x; + t3 = t3 * p1.z + p2.z; + t3.x = t3.y = t3.z = t3.w = cos(t3.x); + + t3 = t3 * p1.w; + + t1 = t2 * t1; + t1 = t1 * t3 + vec4(uv, 0.0, 0.0); + + if (t0.z < 0.0) { + t1.x = uv.x; + t1.y = uv.y; + } + + t1 = t1 * p1 + p2; + + tc = texture2D(u_texture, t1.xy).rgb; + + gl_FragColor = vec4(tc, 1.0); +} +)"; + +class wayfire_fisheye : public wf::per_output_plugin_instance_t +{ + wf::animation::simple_animation_t progression{wf::create_option(300)}; + + float target_zoom; + bool active, hook_set; + + wf::option_wrapper_t radius{"fisheye/radius"}; + wf::option_wrapper_t zoom{"fisheye/zoom"}; + + OpenGL::program_t program; + + wf::plugin_activation_data_t grab_interface = { + .name = "fisheye", + .capabilities = 0, + }; + + public: + void init() override + { + if (!wf::get_core().is_gles2()) + { + const char *render_type = + wf::get_core().is_vulkan() ? "vulkan" : (wf::get_core().is_pixman() ? "pixman" : "unknown"); + LOGE("fisheye: requires GLES2 support, but current renderer is ", render_type); + return; + } + + wf::gles::run_in_context_if_gles([&] + { + program.set_simple(OpenGL::compile_program(vertex_shader, fragment_shader)); + }); + + hook_set = active = false; + output->add_activator(wf::option_wrapper_t{"fisheye/toggle"}, &toggle_cb); + + target_zoom = zoom; + zoom.set_callback([=] () + { + if (active) + { + this->progression.animate(zoom); + } + }); + } + + wf::activator_callback toggle_cb = [=] (auto) + { + if (!output->can_activate_plugin(&grab_interface)) + { + return false; + } + + if (active) + { + active = false; + progression.animate(0); + } else + { + active = true; + progression.animate(zoom); + if (!hook_set) + { + hook_set = true; + output->render->add_post(&render_hook); + output->render->set_redraw_always(); + } + } + + return true; + }; + + wf::post_hook_t render_hook = [=] (wf::auxilliary_buffer_t& source, + const wf::render_buffer_t& dest) + { + auto oc = output->get_cursor_position(); + wf::geometry_t box = {oc.x, oc.y, 1, 1}; + auto fb_box = output->render->get_target_framebuffer(). + framebuffer_box_from_geometry_box(box); + oc.x = fb_box.x; + oc.y = fb_box.y; + + static const float vertexData[] = { + -1.0f, -1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f, + -1.0f, 1.0f + }; + + wf::gles::run_in_context_if_gles([&] + { + wf::gles::bind_render_buffer(dest); + program.use(wf::TEXTURE_TYPE_RGBA); + GL_CALL(glBindTexture(GL_TEXTURE_2D, wf::gles_texture_t::from_aux(source).tex_id)); + GL_CALL(glActiveTexture(GL_TEXTURE0)); + + program.uniform2f("u_mouse", oc.x, dest.get_size().height - oc.y); + program.uniform2f("u_resolution", dest.get_size().width, dest.get_size().height); + program.uniform1f("u_radius", radius); + program.uniform1f("u_zoom", progression); + + program.attrib_pointer("position", 2, 0, vertexData); + + GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + + program.deactivate(); + }); + + if (!active && !progression.running()) + { + finalize(); + } + }; + + void finalize() + { + output->render->rem_post(&render_hook); + output->render->set_redraw_always(false); + hook_set = false; + } + + void fini() override + { + if (hook_set) + { + finalize(); + } + + wf::gles::run_in_context_if_gles([&] + { + program.free_resources(); + }); + + output->rem_binding(&toggle_cb); + } +}; + +DECLARE_WAYFIRE_PLUGIN(wf::per_output_plugin_t); diff --color -Naurp wayfire-plugins-extra-0.10.0/src/follow-focus.cpp wayfire-plugins-extra/src/follow-focus.cpp --- wayfire-plugins-extra-0.10.0/src/follow-focus.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/follow-focus.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -43,7 +43,7 @@ class wayfire_follow_focus : public wf:: private: wayfire_view focus_view = nullptr; wf::wl_timer change_output_focus, change_view_focus; - wf::point_t last_output_coords, last_view_coords; + wf::pointf_t last_output_coords, last_view_coords; wf::option_wrapper_t should_change_view{"follow-focus/change_view"}; wf::option_wrapper_t should_change_output{"follow-focus/change_output"}; @@ -67,7 +67,7 @@ class wayfire_follow_focus : public wf:: void change_output() { auto cpf = wf::get_core().get_cursor_position(); - wf::point_t coords{static_cast(cpf.x), static_cast(cpf.y)}; + wf::pointf_t coords{cpf.x, cpf.y}; if (output->get_layout_geometry() & coords && (output == focus_output)) { @@ -90,7 +90,7 @@ class wayfire_follow_focus : public wf:: } auto cpf = wf::get_core().get_cursor_position(); - wf::point_t coords{static_cast(cpf.x), static_cast(cpf.y)}; + wf::pointf_t coords{cpf.x, cpf.y}; if (output->get_layout_geometry() & coords && (output != focus_output)) { @@ -98,7 +98,7 @@ class wayfire_follow_focus : public wf:: focus_output = output; } - if (abs(coords - last_output_coords) < threshold) + if (wf::abs(coords - last_output_coords) < threshold) { return; } @@ -142,14 +142,14 @@ class wayfire_follow_focus : public wf:: } auto cpf = wf::get_core().get_cursor_position(); - wf::point_t coords{static_cast(cpf.x), static_cast(cpf.y)}; + wf::pointf_t coords{cpf.x, cpf.y}; if (view != focus_view) { last_view_coords = coords; focus_view = view; } - if (abs(coords - last_view_coords) < threshold) + if (wf::abs(coords - last_view_coords) < threshold) { return; } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/force-fullscreen.cpp wayfire-plugins-extra/src/force-fullscreen.cpp --- wayfire-plugins-extra-0.10.0/src/force-fullscreen.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/force-fullscreen.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -55,21 +55,18 @@ class simple_node_render_instance_t : pu node_t *self; wayfire_toplevel_view view; damage_callback push_to_parent; - int *x, *y, *w, *h; - wlr_box *transparent_box; + wf::geometry_t *geometry; + wf::geometry_t *transparent_box; wf::option_wrapper_t transparent_behind_views{ "force-fullscreen/transparent_behind_views"}; public: simple_node_render_instance_t(node_t *self, damage_callback push_damage, - wayfire_toplevel_view view, int *x, int *y, int *w, int *h, wlr_box *transparent_box) + wayfire_toplevel_view view, wf::geometry_t *geometry, wf::geometry_t *transparent_box) { - this->x = x; - this->y = y; - this->w = w; - this->h = h; - this->self = self; - this->view = view; + this->geometry = geometry; + this->self = self; + this->view = view; this->transparent_box = transparent_box; this->push_to_parent = push_damage; self->connect(&on_node_damaged); @@ -77,7 +74,7 @@ class simple_node_render_instance_t : pu void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -96,7 +93,7 @@ class simple_node_render_instance_t : pu return; } - wf::region_t scissor_region{data.damage}; + wf::regionf_t scissor_region{data.damage}; if (transparent_behind_views) { auto bbox = *transparent_box; @@ -104,7 +101,7 @@ class simple_node_render_instance_t : pu bbox.y += 1; bbox.width -= 2; bbox.height -= 2; - scissor_region ^= wf::region_t{bbox}; + scissor_region ^= wf::regionf_t{bbox}; } data.pass->clear(scissor_region, {0, 0, 0, 1}); @@ -114,18 +111,18 @@ class simple_node_render_instance_t : pu class black_border_node_t : public node_t { wayfire_toplevel_view view; - wlr_box transparent_box; + wf::geometry_t transparent_box; public: - int x, y, w, h; + wf::geometry_t geometry; black_border_node_t(wayfire_toplevel_view view, int x, int y, int w, - int h, wlr_box transparent_box) : node_t(false) + int h, wf::geometry_t transparent_box) : node_t(false) { - this->x = x; - this->y = y; - this->w = w; - this->h = h; + this->geometry.x = x; + this->geometry.y = y; + this->geometry.width = w; + this->geometry.height = h; this->view = view; this->transparent_box = transparent_box; } @@ -138,13 +135,13 @@ class black_border_node_t : public node_ // this simple nodes does not need any transformations, so the push_damage // callback is just passed along. instances.push_back(std::make_unique( - this, push_damage, view, &x, &y, &w, &h, &transparent_box)); + this, push_damage, view, &geometry, &transparent_box)); } wf::geometry_t get_bounding_box() override { // Specify whatever geometry your node has - return {x, y, w, h}; + return geometry; } }; @@ -156,7 +153,7 @@ class fullscreen_background std::shared_ptr transformer; std::shared_ptr black_border_node; bool black_border = false; - wlr_box transformed_view_box; + wf::geometry_t transformed_view_box; fullscreen_background(wayfire_toplevel_view view) {} @@ -216,11 +213,11 @@ class wayfire_force_fullscreen : public int x = offset.x * og.width; int y = offset.y * og.height; b.second->transformed_view_box.x = x + w; - b.second->black_border_node->x = x; - b.second->black_border_node->y = y; - b.second->black_border_node->w = og.width; - b.second->black_border_node->h = og.height; - b.second->transformed_view_box.y = b.second->black_border_node->y = + b.second->black_border_node->geometry.x = x; + b.second->black_border_node->geometry.y = y; + b.second->black_border_node->geometry.width = og.width; + b.second->black_border_node->geometry.height = og.height; + b.second->transformed_view_box.y = b.second->black_border_node->geometry.y = y; } @@ -228,7 +225,7 @@ class wayfire_force_fullscreen : public } }; - void ensure_subsurface(wayfire_toplevel_view view, wlr_box transformed_view_box) + void ensure_subsurface(wayfire_toplevel_view view, wf::geometry_t transformed_view_box) { auto pair = backgrounds.find(view); @@ -289,7 +286,7 @@ class wayfire_force_fullscreen : public scale_x = scale_y = std::min(scale_x, scale_y); } - wlr_box box; + wf::geometry_t box; box.width = std::floor(vg.width * scale_x); box.height = std::floor(vg.height * scale_y); box.x = std::ceil((og.width - box.width) / 2.0); @@ -332,7 +329,7 @@ class wayfire_force_fullscreen : public return false; } - wlr_box saved_geometry = view->get_geometry(); + wf::geometry_t saved_geometry = view->get_geometry(); auto background = backgrounds.find(view); bool fullscreen = background == backgrounds.end() ? true : false; @@ -340,7 +337,7 @@ class wayfire_force_fullscreen : public view->toplevel()->pending().fullscreen = fullscreen; wf::get_core().tx_manager->schedule_object(view->toplevel()); - wlr_box undecorated_geometry = view->get_geometry(); + wf::geometry_t undecorated_geometry = view->get_geometry(); if (!fullscreen) { @@ -505,7 +502,7 @@ class wayfire_force_fullscreen : public for (auto& b : backgrounds) { auto view = wf::get_active_view_for_output(output); - wlr_box box; + wf::geometry_t box; box = b.second->transformed_view_box; box.x += og.x; @@ -519,7 +516,8 @@ class wayfire_force_fullscreen : public if ((b.first == view) && !(box & wf::pointf_t{cursor.x, cursor.y})) { - wlr_box_closest_point(&box, cursor.x, cursor.y, + auto ibox = wf::to_integer_box(box); + wlr_box_closest_point(&ibox, cursor.x, cursor.y, &cursor.x, &cursor.y); ev->event->delta_x = ev->event->unaccel_dx = cursor.x - last_cursor.x; diff --color -Naurp wayfire-plugins-extra-0.10.0/src/keycolor.cpp wayfire-plugins-extra/src/keycolor.cpp --- wayfire-plugins-extra-0.10.0/src/keycolor.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/keycolor.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -130,7 +130,7 @@ class simple_node_render_instance_t : pu void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -196,7 +196,7 @@ class simple_node_render_instance_t : pu for (const auto& box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); } diff --color -Naurp wayfire-plugins-extra-0.10.0/src/mag.cpp wayfire-plugins-extra/src/mag.cpp --- wayfire-plugins-extra-0.10.0/src/mag.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/mag.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -71,7 +71,8 @@ class mag_view_t : public wf::toplevel_v /* Draw the inside of the rect, if we have already captured the output's contents */ if (view->mag_tex.get_buffer() != NULL) { - data.pass->add_texture({view->mag_tex.get_texture()}, data.target, geometry, data.damage); + data.pass->add_texture(wf::texture_t::from_aux( + view->mag_tex), data.target, geometry, data.damage); } } }; @@ -296,7 +297,7 @@ class wayfire_magnifier : public wf::per { auto og = output->get_relative_geometry(); float aspect = (float)og.width / og.height; - wf::geometry_t start_geometry = {100, 100, (int)(default_height * aspect), default_height}; + wf::geometry_t start_geometry = {100, 100, default_height *aspect, (double)default_height}; return start_geometry; } @@ -344,7 +345,7 @@ class wayfire_magnifier : public wf::per glm::translate(glm::mat4(1.0), glm::vec3(0.5, 0.5, 0.0)) * glm::scale(glm::mat4(1.0), glm::vec3{0.5, -0.5, 1.0}) * ortho; - glm::vec4 cursor = glm::vec4(cursor_position.x, cursor_position.y, 0.0, 1.0); + glm::vec4 cursor = glm::vec4((int)cursor_position.x, (int)cursor_position.y, 0.0, 1.0); cursor = cursor_transform * cursor; float x = cursor.x; @@ -399,10 +400,10 @@ class wayfire_magnifier : public wf::per zoom_box.y2 = 1.0; } - zoom_box.x1 *= width - 1; - zoom_box.x2 *= width - 1; - zoom_box.y1 *= height - 1; - zoom_box.y2 *= height - 1; + zoom_box.x1 *= width; + zoom_box.x2 *= width; + zoom_box.y1 *= height; + zoom_box.y2 *= height; /* Copy zoom_box part of the output to our own texture to be * read by the mag_view_t. */ diff --color -Naurp wayfire-plugins-extra-0.10.0/src/meson.build wayfire-plugins-extra/src/meson.build --- wayfire-plugins-extra-0.10.0/src/meson.build 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/meson.build 2026-08-01 16:00:35.434368211 -0600 @@ -16,6 +16,10 @@ crosshair = shared_module('crosshair', ' dependencies: [wayfire], install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) +fisheye = shared_module('fisheye', 'fisheye.cpp', + dependencies: [wayfire], + install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) + focus_change = shared_module('focus-change', 'focus-change.cpp', dependencies: [wayfire], install: true, install_dir: join_paths(get_option('libdir'), 'wayfire')) diff --color -Naurp wayfire-plugins-extra-0.10.0/src/obs.cpp wayfire-plugins-extra/src/obs.cpp --- wayfire-plugins-extra-0.10.0/src/obs.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/obs.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -138,7 +138,7 @@ class wf_obs : public wf::scene::view_2d } void schedule_instructions(std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -190,7 +190,7 @@ class wf_obs : public wf::scene::view_2d for (const auto& box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); OpenGL::render_transformed_texture(final_tex, view_box, wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); diff --color -Naurp wayfire-plugins-extra-0.10.0/src/showrepaint.cpp wayfire-plugins-extra/src/showrepaint.cpp --- wayfire-plugins-extra-0.10.0/src/showrepaint.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/showrepaint.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -119,13 +119,13 @@ class wayfire_showrepaint : public wf::p wf::effect_hook_t overlay_hook = [=] () { auto target_fb = output->render->get_target_framebuffer(); - wf::region_t swap_damage = target_fb.geometry_region_from_framebuffer_region( + wf::regionf_t swap_damage = target_fb.geometry_region_from_framebuffer_region( output->render->get_swap_damage()); - wf::region_t scheduled_damage = output->render->get_scheduled_damage(); - wf::region_t output_region{target_fb.geometry}; - wf::region_t inverted_damage; - wf::region_t damage; + wf::regionf_t scheduled_damage = output->render->get_scheduled_damage(); + wf::regionf_t output_region{target_fb.geometry}; + wf::regionf_t inverted_damage; + wf::regionf_t damage; /* Show scheduled client damage. Scheduled damage is the client damage * in union with last frame client damage. If this region is empty, we @@ -167,9 +167,8 @@ class wayfire_showrepaint : public wf::p */ if (last_buffer.get_size().width > 0) { - wf::texture_t texture; - texture.texture = last_buffer.get_texture(); - texture.transform = target_fb.wl_transform; + std::shared_ptr texture = wf::texture_t::from_aux(last_buffer); + texture->set_transform(target_fb.wl_transform); rpass->add_texture(texture, target_fb, target_fb.geometry, inverted_damage); } }; @@ -189,8 +188,8 @@ class wayfire_showrepaint : public wf::p */ auto target_fb = output->render->get_target_framebuffer(); last_buffer.allocate(target_fb.get_size()); - wlr_box full = wf::construct_box({0, 0}, target_fb.get_size()); - last_buffer.get_renderbuffer().blit(target_fb, wf::geometry_to_fbox(full), full); + wf::geometry_t full = wf::construct_box({0, 0}, target_fb.get_size()); + last_buffer.get_renderbuffer().blit(target_fb, full, full); }; void fini() override diff --color -Naurp wayfire-plugins-extra-0.10.0/src/showtouch.cpp wayfire-plugins-extra/src/showtouch.cpp --- wayfire-plugins-extra-0.10.0/src/showtouch.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/showtouch.cpp 2026-08-01 16:00:35.434368211 -0600 @@ -324,6 +324,7 @@ class wayfire_showtouch : public wf::per wf::gles::run_in_context([&] { + wf::gles::bind_render_buffer(dest); program.use(wf::TEXTURE_TYPE_RGBA); program.set_active_texture(tex); diff --color -Naurp wayfire-plugins-extra-0.10.0/src/window-zoom.cpp wayfire-plugins-extra/src/window-zoom.cpp --- wayfire-plugins-extra-0.10.0/src/window-zoom.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/window-zoom.cpp 2026-08-01 16:00:35.434602314 -0600 @@ -60,14 +60,14 @@ class simple_node_render_instance_t : pu node_t *self; wayfire_toplevel_view view; float *scale_x, *scale_y; - wlr_box *transformed_view_geometry; + wf::geometry_t *transformed_view_geometry; damage_callback push_damage; wf::option_wrapper_t nearest_filtering{"winzoom/nearest_filtering"}; public: simple_node_render_instance_t(transformer_base_node_t *self, damage_callback push_damage, wayfire_toplevel_view view, float *scale_x, float *scale_y, - wlr_box *transformed_view_geometry) : + wf::geometry_t *transformed_view_geometry) : transformer_render_instance_t(self, push_damage, view->get_output()) { @@ -89,7 +89,7 @@ class simple_node_render_instance_t : pu void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -99,16 +99,16 @@ class simple_node_render_instance_t : pu }); } - void transform_damage_region(wf::region_t& damage) override + void transform_damage_region(wf::regionf_t& damage) override { damage |= view->get_transformed_node()->get_children_bounding_box(); } - wlr_box get_scaled_geometry() + wf::geometry_t get_scaled_geometry() { auto vg = view->get_geometry(); auto midpoint = get_center(vg); - auto result = wf::pointf_t{float(vg.x), float(vg.y)} - midpoint; + auto result = wf::pointf_t{vg.x, vg.y} - midpoint; result.x *= *scale_x; result.y *= *scale_y; result += midpoint; @@ -123,7 +123,7 @@ class simple_node_render_instance_t : pu { auto src_tex = get_texture(1.0); auto scaled_geometry = get_scaled_geometry(); - src_tex.filter_mode = nearest_filtering ? WLR_SCALE_FILTER_NEAREST : WLR_SCALE_FILTER_BILINEAR; + src_tex->set_filter_mode(nearest_filtering ? WLR_SCALE_FILTER_NEAREST : WLR_SCALE_FILTER_BILINEAR); data.pass->add_texture(src_tex, data.target, scaled_geometry, data.damage); } }; @@ -131,7 +131,7 @@ class simple_node_render_instance_t : pu class winzoom_t : public view_2d_transformer_t { wayfire_toplevel_view view; - wlr_box transformed_view_geometry; + wf::geometry_t transformed_view_geometry; public: winzoom_t(wayfire_toplevel_view view) : view_2d_transformer_t(view) diff --color -Naurp wayfire-plugins-extra-0.10.0/src/workspace-names.cpp wayfire-plugins-extra/src/workspace-names.cpp --- wayfire-plugins-extra-0.10.0/src/workspace-names.cpp 2025-08-11 22:03:47.000000000 -0600 +++ wayfire-plugins-extra/src/workspace-names.cpp 2026-08-01 16:00:35.434602314 -0600 @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2023 Scott Moreau + * Copyright (c) 2026 Scott Moreau * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -91,7 +91,7 @@ class simple_node_render_instance_t : pu void schedule_instructions( std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override + const wf::render_target_t& target, wf::regionf_t& damage) override { // We want to render ourselves only, the node does not have children instructions.push_back(render_instruction_t{ @@ -113,7 +113,7 @@ class simple_node_render_instance_t : pu wf::gles::bind_render_buffer(data.target); for (auto& box : data.damage) { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); + wf::gles::render_target_logic_scissor(data.target, box); OpenGL::render_texture(wf::gles_texture_t{workspace->texture->get_texture()}, data.target, g, glm::vec4(1, 1, 1, *alpha_fade), 0); } @@ -132,13 +132,20 @@ class simple_node_t : public node_t public: std::shared_ptr workspace; - simple_node_t(wf::point_t offset) : node_t(false) + wf::point_t ws; + simple_node_t(wf::point_t offset, wf::point_t ws) : node_t(false) { - this->offset = offset; + this->ws = ws; + this->offset = offset; this->alpha_fade = 0.0; workspace = std::make_shared(); } + ~simple_node_t() + { + workspace = nullptr; + } + void gen_render_instances(std::vector& instances, damage_callback push_damage, wf::output_t *shown_on) override { @@ -150,7 +157,7 @@ class simple_node_t : public node_t this, push_damage, &offset, &alpha_fade, workspace)); } - void do_push_damage(wf::region_t updated_region) + void do_push_damage(wf::regionf_t updated_region) { node_damage_signal ev; ev.region = updated_region; @@ -164,10 +171,14 @@ class simple_node_t : public node_t workspace->rect.width, workspace->rect.height}; } - void set_offset(int x, int y) + void set_offset(wf::point_t offset) + { + this->offset = offset; + } + + wf::point_t get_ws() { - this->offset.x = x; - this->offset.y = y; + return this->ws; } void set_alpha(double alpha) @@ -177,9 +188,9 @@ class simple_node_t : public node_t }; std::shared_ptr add_simple_node(wf::output_t *output, - wf::point_t offset) + wf::point_t offset, wf::point_t ws) { - auto subnode = std::make_shared(offset); + auto subnode = std::make_shared(offset, ws); wf::scene::add_front(output->node_for_layer(wf::scene::layer::OVERLAY), subnode); return subnode; } @@ -187,8 +198,7 @@ std::shared_ptr add_simpl class wayfire_workspace_names_output : public wf::per_output_plugin_instance_t { wf::wl_timer timer; - bool hook_set = false; - bool timed_out = false; + bool hook_set = false; std::vector>> workspaces; wf::option_wrapper_t font{"workspace-names/font"}; wf::option_wrapper_t position{"workspace-names/position"}; @@ -208,76 +218,90 @@ class wayfire_workspace_names_output : p void init() override { alpha_fade.set(0, 0); - timed_out = false; + output->wset()->connect(&workspace_grid_changed); + output->connect(&workarea_changed); + output->connect(&viewport_changed); + output->connect(&viewport_change_request); + font.set_callback(option_changed); + position.set_callback(option_changed); + background_color.set_callback(option_changed); + text_color.set_callback(option_changed); + show_option_values.set_callback(option_changed); + show_option_names.set_callback(show_options_changed); + + if (show_option_names) + { + show_options_changed(); + } + } + + void init_workspace_name_nodes() + { auto wsize = output->wset()->get_workspace_grid_size(); + auto og = output->get_relative_geometry(); workspaces.resize(wsize.width); for (int x = 0; x < wsize.width; x++) { workspaces[x].resize(wsize.height); } - auto og = output->get_relative_geometry(); for (int x = 0; x < wsize.width; x++) { for (int y = 0; y < wsize.height; y++) { - workspaces[x][y] = add_simple_node(output, {x *og.width, - y * og.height}); + workspaces[x][y] = add_simple_node(output, {int(x * og.width), + int(y * og.height)}, {x, y}); } } + } - output->connect(&workarea_changed); - output->connect(&viewport_changed); - font.set_callback(option_changed); - position.set_callback(option_changed); - background_color.set_callback(option_changed); - text_color.set_callback(option_changed); - show_option_names.set_callback(show_options_changed); - - if (show_option_names) - { - show_options_changed(); - } else + void fini_workspace_name_nodes() + { + for (auto & x : workspaces) { - update_names(); + for (auto & workspace : x) + { + auto& wsn = workspace->workspace; + cairo_surface_destroy(wsn->cairo_surface); + cairo_destroy(wsn->cr); + wf::scene::remove_child(workspace); + workspace.reset(); + } } - - wf::get_core().connect(&reload_config); } - wf::signal::connection_t reload_config{[this] (wf::reload_config_signal *ev) + wf::signal::connection_t workspace_grid_changed{[this] (wf:: + workspace_grid_changed_signal + *ev) { - update_names(); + deactivate(); + init_workspace_name_nodes(); } }; wf::config::option_base_t::updated_callback_t show_options_changed = [=] () { - update_names(); - - viewport_changed.emit(nullptr); - if (show_option_names) { - timer.disconnect(); - output->render->rem_effect(&post_hook); + activate(); + update_names(); + viewport_changed.emit(nullptr); + alpha_fade.animate(alpha_fade, 1); } else { - output->connect(&viewport_changed); - output->render->add_effect(&post_hook, wf::OUTPUT_EFFECT_POST); + alpha_fade.animate(alpha_fade, 0); } - alpha_fade.animate(alpha_fade, 1.0); output->render->damage_whole(); }; - void update_name(int x, int y) + void update_name(std::shared_ptr workspace) { auto section = wf::get_core().config->get_section("workspace-names"); auto wsize = output->wset()->get_workspace_grid_size(); - auto wsn = workspaces[x][y]->workspace; - int ws_num = x + y * wsize.width + 1; + auto wsn = workspace->workspace; + int ws_num = workspace->get_ws().x + workspace->get_ws().y * wsize.width + 1; // Get the option name (key) of the target workspace std::string key = output->to_string() + "_workspace_" + std::to_string(ws_num); @@ -327,13 +351,12 @@ class wayfire_workspace_names_output : p void update_names() { - auto wsize = output->wset()->get_workspace_grid_size(); - for (int x = 0; x < wsize.width; x++) + for (auto & x : workspaces) { - for (int y = 0; y < wsize.height; y++) + for (auto & workspace : x) { - update_name(x, y); - update_texture(workspaces[x][y]->workspace); + update_name(workspace); + update_texture(workspace->workspace); } } } @@ -400,7 +423,11 @@ class wayfire_workspace_names_output : p wf::config::option_base_t::updated_callback_t option_changed = [=] () { - update_textures(); + if (hook_set) + { + update_names(); + update_textures(); + } }; void update_texture_position(std::shared_ptr wsn) @@ -455,6 +482,7 @@ class wayfire_workspace_names_output : p wf::signal::connection_t workarea_changed{[this] (wf::workarea_changed_signal *ev) { + update_workspace_names_timeout(); update_textures(); } }; @@ -528,73 +556,68 @@ class wayfire_workspace_names_output : p if (alpha_fade.running()) { set_alpha(); - output->render->damage_whole(); } }; - wf::signal::connection_t viewport_changed{[this] (wf:: - workspace_changed_signal* - ev) - { - auto wsize = output->wset()->get_workspace_grid_size(); - auto nvp = output->wset()->get_current_workspace(); - auto og = output->get_relative_geometry(); + void update_workspace_names_timeout() + { + auto wsize = output->wset()->get_workspace_grid_size(); + auto nvp = output->wset()->get_current_workspace(); + auto og = output->get_relative_geometry(); + + activate(); + update_textures(); + update_names(); - for (int x = 0; x < wsize.width; x++) + for (int x = 0; x < wsize.width; x++) + { + for (int y = 0; y < wsize.height; y++) { - for (int y = 0; y < wsize.height; y++) - { - workspaces[x][y]->set_offset((x - nvp.x) * og.width, - (y - nvp.y) * og.height); - } + workspaces[x][y]->set_offset({int((x - nvp.x) * og.width), int((y - nvp.y) * og.height)}); } + } - output->render->damage_whole(); + output->render->damage_whole(); - activate(); + if (show_option_names) + { + return; + } - if (show_option_names) - { - return; - } + alpha_fade.animate(alpha_fade, 1); - if (!alpha_fade.running()) - { - if (!timer.is_connected()) - { - alpha_fade.animate(alpha_fade, 1.0); - } - } else if (timed_out) - { - timed_out = false; - alpha_fade.animate(alpha_fade, 1.0); - } + timer.disconnect(); + timer.set_timeout((int)display_duration, timeout); + } - timer.disconnect(); - timer.set_timeout((int)display_duration, timeout); + wf::signal::connection_t viewport_change_request{[this] (wf:: + workspace_change_request_signal + * + ev) + { + update_workspace_names_timeout(); + } + }; + + wf::signal::connection_t viewport_changed{[this] (wf:: + workspace_changed_signal* + ev) + { + update_workspace_names_timeout(); } }; wf::wl_timer::callback_t timeout = [=] () { output->render->damage_whole(); - alpha_fade.animate(1.0, 0.0); - timed_out = true; + alpha_fade.animate(alpha_fade, 0); }; wf::effect_hook_t post_hook = [=] () { - if (!alpha_fade.running()) + if (!alpha_fade.running() && !timer.is_connected() && !show_option_names) { - if (timed_out) - { - deactivate(); - timed_out = false; - output->render->damage_whole(); - } else if (!timer.is_connected()) - { - timer.set_timeout((int)display_duration, timeout); - } + deactivate(); } else { set_alpha(); @@ -608,6 +631,7 @@ class wayfire_workspace_names_output : p return; } + init_workspace_name_nodes(); output->render->add_effect(&post_hook, wf::OUTPUT_EFFECT_POST); output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); output->render->damage_whole(); @@ -621,6 +645,8 @@ class wayfire_workspace_names_output : p return; } + timer.disconnect(); + fini_workspace_name_nodes(); output->render->rem_effect(&post_hook); output->render->rem_effect(&pre_hook); hook_set = false; @@ -629,18 +655,10 @@ class wayfire_workspace_names_output : p void fini() override { deactivate(); - auto wsize = output->wset()->get_workspace_grid_size(); - for (int x = 0; x < wsize.width; x++) - { - for (int y = 0; y < wsize.height; y++) - { - auto& wsn = workspaces[x][y]->workspace; - cairo_surface_destroy(wsn->cairo_surface); - cairo_destroy(wsn->cr); - wf::scene::remove_child(workspaces[x][y]); - workspaces[x][y].reset(); - } - } + workspace_grid_changed.disconnect(); + viewport_change_request.disconnect(); + viewport_changed.disconnect(); + workarea_changed.disconnect(); output->render->damage_whole(); } diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/filter-tiled.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/filter-tiled.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/filter-tiled.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/filter-tiled.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,45 +0,0 @@ -#!/usr/bin/python3 - -# A simple script to apply a filter to untiled views. - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 2: - print("Required arguments: ") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) -sock.watch() - -def toggle_filter(view): - try: - if view["tiled-edges"] == 0: - if wpe.view_has_shader(int(view["id"]))["has-shader"] is False: - wpe.set_view_shader(int(view["id"]), os.path.abspath(str(sys.argv[1]))) - else: - if wpe.view_has_shader(int(view["id"]))["has-shader"] is True: - wpe.unset_view_shader(int(view["id"])) - except: - pass - -views = sock.list_views() -for view in views: - toggle_filter(view) - -while True: - try: - msg = sock.read_next_event() - if "event" in msg and "view" in msg and (msg["view"] is not None): - toggle_filter(msg["view"]) - except KeyboardInterrupt: - views = sock.list_views() - for view in views: - try: - wpe.unset_view_shader(int(view["id"])) - except: - pass - exit(0) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/fs-has-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/fs-has-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/fs-has-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/fs-has-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,11 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -sock = WayfireSocket() -wpe = WPE(sock) - -print(f'Output {sys.argv[1]} has shader: {wpe.fs_has_shader(sys.argv[1])["has-shader"]}') diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-fs-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-fs-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-fs-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-fs-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,15 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 3: - print("Required arguments: ") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) - -wpe.set_fs_shader(str(sys.argv[1]), os.path.abspath(str(sys.argv[2]))) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-inactive-views.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-inactive-views.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-inactive-views.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-inactive-views.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,48 +0,0 @@ -#!/usr/bin/python3 - -# A simple script to apply a shader to all views except the active view -# When a new view is focused, the shader is applied to the previously -# active view. It skips app-id "panel", as this is wf-panel's app-id. - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) == 1: - print(f"Usage: {sys.argv[0]} /path/to/filters/shader") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) -sock.watch(['view-focused']) - -def unset_view_shaders(): - for view in sock.list_views(): - wpe.unset_view_shader(view["id"]) - -active_view_id = sock.get_focused_view()["id"] -active_view_app_id = sock.get_focused_view()["app-id"] -for view in sock.list_views(): - view_id = view["id"] - if view_id != active_view_id and view["app-id"] != "panel": - wpe.set_view_shader(view_id, os.path.abspath(str(sys.argv[1]))) -last_active_view_id = active_view_id -last_active_view_app_id = active_view_app_id - -while True: - try: - msg = sock.read_next_event() - if "event" in msg: - active_view_id = sock.get_focused_view()["id"] - active_view_app_id = sock.get_focused_view()["app-id"] - if last_active_view_id != active_view_id and last_active_view_app_id != "panel": - wpe.set_view_shader(last_active_view_id, os.path.abspath(str(sys.argv[1]))) - wpe.unset_view_shader(active_view_id) - last_active_view_id = active_view_id - last_active_view_app_id = active_view_app_id - except KeyboardInterrupt: - unset_view_shaders() - exit(0) - except: - pass diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-view-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-view-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/set-view-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/set-view-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,15 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 3: - print("Required arguments: ") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) - -wpe.set_view_shader(int(sys.argv[1]), os.path.abspath(str(sys.argv[2]))) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/toggle-fs-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/toggle-fs-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/toggle-fs-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/toggle-fs-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,22 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 2: - print("Required argument: Output name") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) - -has_shader = wpe.fs_has_shader(str(sys.argv[1]))["has-shader"] - -print(f'Fullscreen {sys.argv[1]} has shader: {has_shader}') - -if has_shader: - wpe.unset_fs_shader(str(sys.argv[1])) -else: - wpe.set_fs_shader(str(sys.argv[1]), os.path.abspath(os.path.join(os.path.dirname(__file__), '../shaders/crt'))) \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/unset-fs-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/unset-fs-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/unset-fs-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/unset-fs-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,15 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 2: - print("Required argument: Output name") - exit(-1) - -sock = WayfireSocket() -wpe = WPE(sock) - -wpe.unset_fs_shader(str(sys.argv[1])) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/unset-view-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/unset-view-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/unset-view-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/unset-view-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,11 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -sock = WayfireSocket() -wpe = WPE(sock) - -wpe.unset_view_shader(int(sys.argv[1])) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/view-has-shader.py wayfire-plugins-extra/subprojects/filters/ipc-scripts/view-has-shader.py --- wayfire-plugins-extra-0.10.0/subprojects/filters/ipc-scripts/view-has-shader.py 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/ipc-scripts/view-has-shader.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,11 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -sock = WayfireSocket() -wpe = WPE(sock) - -print(f'View {sys.argv[1]} has shader: {wpe.view_has_shader(int(sys.argv[1]))["has-shader"]}') diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/meson.build wayfire-plugins-extra/subprojects/filters/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/filters/meson.build 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,22 +0,0 @@ -project( - 'filters', - 'c', - 'cpp', - version: '0.1.0', - license: 'MIT', - meson_version: '>=0.51.0', - default_options: [ - 'cpp_std=c++17', - 'c_std=c11', - ], -) - -add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c']) -add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c']) -add_project_link_arguments(['-rdynamic','-fPIC'], language:'cpp') - -wayfire = dependency('wayfire', version: '>=0.8.1') - - -subdir('src') -subdir('metadata') diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/metadata/filters.xml wayfire-plugins-extra/subprojects/filters/metadata/filters.xml --- wayfire-plugins-extra-0.10.0/subprojects/filters/metadata/filters.xml 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/metadata/filters.xml 1969-12-31 17:00:00.000000000 -0700 @@ -1,8 +0,0 @@ - - - - <_short>Shader Filters - <_long>Apply shaders via ipc. - Effects - - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/metadata/meson.build wayfire-plugins-extra/subprojects/filters/metadata/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/filters/metadata/meson.build 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/metadata/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1 +0,0 @@ -install_data( 'filters.xml', install_dir: wayfire.get_variable( pkgconfig: 'metadatadir' ) ) \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/README.md wayfire-plugins-extra/subprojects/filters/README.md --- wayfire-plugins-extra-0.10.0/subprojects/filters/README.md 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/README.md 1969-12-31 17:00:00.000000000 -0700 @@ -1,36 +0,0 @@ -# Filters - -## Installation -``` -$ meson setup build --prefix=/usr -$ ninja -C build -# ninja -C build install -``` - -## Requirements - -Install [pywayfire](https://github.com/WayfireWM/pywayfire) with pip. - -## Usage - -To set shader on view with view-id: - -`./ipc-scripts/set-view-shader.py shaders/` - -To unset shader on view with view-id: - -`./ipc-scripts/unset-view-shader.py ` - -To set shader on output with output-name: - -`./ipc-scripts/set-fs-shader.py shaders/` - -To unset shader on output with output-name: - -`./ipc-scripts/unset-fs-shader.py ` - -Hints: - -View ID can be obtained with [wf-info](https://github.com/soreau/wf-info). - -Requires ipc plugin to function. diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/blur wayfire-plugins-extra/subprojects/filters/shaders/blur --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/blur 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/blur 1969-12-31 17:00:00.000000000 -0700 @@ -1,40 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; - -// Shader adapted from: https://www.shadertoy.com/view/Xltfzj - -float PI_2 = 6.28318530718; - -// GAUSSIAN BLUR SETTINGS -float directions = 32.0; // BLUR DIRECTIONS (Default 16.0 - More is better but slower) -float quality = 3.0; // BLUR QUALITY (Default 4.0 - More is better but slower) -float radius = 8.0; // BLUR SIZE (Radius) - -void main() -{ - ivec2 size = textureSize(in_tex, 0); - vec2 s = vec2(size); - vec2 r = radius / s; - vec2 uv = uvpos; - vec4 c = get_pixel(uv); - vec4 oc = c; - - for (float d = 0.0; d < PI_2; d += PI_2 / directions) - { - for(float i = 1.0 / quality; i <= 1.0; i += 1.0 / quality) - { - c += get_pixel(uv + vec2(cos(d), sin(d)) * r * i); - } - } - - c /= quality * directions - 15.0; - out_color = mix(oc, c, progress); -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/border wayfire-plugins-extra/subprojects/filters/shaders/border --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/border 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/border 1969-12-31 17:00:00.000000000 -0700 @@ -1,63 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec4 oc = c; - ivec2 size = textureSize(in_tex, 0); - vec2 texelSize = 1.0 / vec2(size); - vec4 border_color = vec4(0.0, 1.0, 0.0, 1.0); - float border_size = 2.0; - float corner_radius = 10.0; - float d; - // Sides - if ((uvpos.x <= (texelSize.x * border_size) || uvpos.x >= 1.0 - (texelSize.x * border_size)) && uvpos.y > (texelSize.y * corner_radius) && uvpos.y < 1.0 - (texelSize.y * corner_radius) || - ((uvpos.y <= (texelSize.y * border_size) || uvpos.y >= 1.0 - (texelSize.y * border_size)) && uvpos.x > (texelSize.x * corner_radius) && uvpos.x < 1.0 - (texelSize.x * corner_radius))) - { - c = border_color; - } else - // Corners - if (uvpos.x <= (texelSize.x * corner_radius) && uvpos.y <= (texelSize.y * corner_radius)) - { - // Bottom Left - d = distance(vec2(corner_radius), uvpos * vec2(size)); - if (d - corner_radius <= 0.0 && d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else if (uvpos.x >= 1.0 - (texelSize.x * corner_radius) && uvpos.y <= (texelSize.y * corner_radius)) - { - // Bottom Right - d = distance(vec2(float(size.x) - corner_radius, corner_radius), uvpos * vec2(size)); - if (d - corner_radius <= 0.0 && d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else if (uvpos.x <= (texelSize.x * corner_radius) && uvpos.y >= 1.0 - (texelSize.y * corner_radius)) - { - // Top Left - d = distance(vec2(corner_radius, float(size.y) - corner_radius), uvpos * vec2(size)); - if (d - corner_radius <= 0.0 && d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else if (uvpos.x >= 1.0 - (texelSize.x * corner_radius) && uvpos.y >= 1.0 - (texelSize.y * corner_radius)) - { - // Top Right - d = distance(vec2(vec2(size) - corner_radius), uvpos * vec2(size)); - if (d - corner_radius <= 0.0 && d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } - out_color = mix(oc, c, progress); -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/crt wayfire-plugins-extra/subprojects/filters/shaders/crt --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/crt 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/crt 1969-12-31 17:00:00.000000000 -0700 @@ -1,28 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec4 oc = c; - if (mod(gl_FragCoord.x - 0.5, 3.0) == 0.0 || mod(gl_FragCoord.y - 0.5, 3.0) == 0.0) - { - c.r *= 0.75; - c.g *= 0.75; - c.b *= 0.75; - } else - { - c.r *= 1.25; - c.g *= 1.25; - c.b *= 1.25; - } - out_color = mix(oc, c, progress); -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/invert wayfire-plugins-extra/subprojects/filters/shaders/invert --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/invert 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/invert 1969-12-31 17:00:00.000000000 -0700 @@ -1,24 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec4 oc = c; - // Invert - c.r = 1.0 - c.r; - c.g = 1.0 - c.g; - c.b = 1.0 - c.b; - c.r *= c.a; - c.g *= c.a; - c.b *= c.a; - out_color = mix(oc, c, progress); -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/monochrome wayfire-plugins-extra/subprojects/filters/shaders/monochrome --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/monochrome 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/monochrome 1969-12-31 17:00:00.000000000 -0700 @@ -1,21 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec4 oc = c; - float color_factor = 0.0; // 1.0 = color, 0.0 = greyscale - // Monochrome - float grey = 0.21 * c.r + 0.71 * c.g + 0.07 * c.b; - c = vec4(c.r * color_factor + grey * (1.0 - color_factor), c.g * color_factor + grey * (1.0 - color_factor), c.b * color_factor + grey * (1.0 - color_factor), 1.0); - out_color = mix(oc, c, progress); -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/passthrough wayfire-plugins-extra/subprojects/filters/shaders/passthrough --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/passthrough 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/passthrough 1969-12-31 17:00:00.000000000 -0700 @@ -1,19 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -// progress is for fade in/out -uniform float progress; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec4 oc = c; - // pointless, because the two colors are the same - out_color = mix(oc, c, progress); -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/rounded-corners wayfire-plugins-extra/subprojects/filters/shaders/rounded-corners --- wayfire-plugins-extra-0.10.0/subprojects/filters/shaders/rounded-corners 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/shaders/rounded-corners 1969-12-31 17:00:00.000000000 -0700 @@ -1,95 +0,0 @@ -#version 300 es -@builtin_ext@ -@builtin@ - -precision mediump float; - -uniform sampler2D in_tex; -out vec4 out_color; -in mediump vec2 uvpos; -uniform float progress; -uniform vec4 margins; - -void main() -{ - vec4 c = get_pixel(uvpos); - vec2 uv = uvpos; - vec4 m = margins; - vec4 oc = c; - vec4 shadow_color = vec4(0.0, 0.0, 0.2, 0.5); - ivec2 size = textureSize(in_tex, 0); - vec2 texelSize = 1.0 / vec2(size); - m.x *= texelSize.x; // left - m.y *= texelSize.y; // top - m.z *= texelSize.x; // right - m.w *= texelSize.y; // bottom - vec4 border_color = vec4(0.1, 0.1, 0.1, 1.0); - float border_size = 1.0; - float corner_radius = 15.0; - float shadow_radius = 12.0; - float d; - float diffuse = 1.0 / max(shadow_radius / 2.0, 1.0); - - // Edges - if ((((uv.x >= m.x - texelSize.x * border_size && uv.x <= m.x) || (uv.x <= 1.0 - (m.z - texelSize.x * border_size) && uv.x >= 1.0 - m.z)) && - (uv.y > texelSize.y * (corner_radius - border_size) + m.w && uv.y < 1.0 - texelSize.y * (corner_radius - border_size) - m.y)) || - (((uv.y >= m.w - texelSize.y * border_size && uv.y <= m.w) || (uv.y <= 1.0 - (m.y - texelSize.y * border_size) && uv.y >= 1.0 - m.y)) && - (uv.x > texelSize.x * (corner_radius - border_size) + m.x && uv.x < 1.0 - texelSize.x * (corner_radius - border_size) - m.z))) - { - c = border_color; - } else - // Corners - if (uv.x <= texelSize.x * (corner_radius - border_size) + m.x && uv.y <= texelSize.y * (corner_radius - border_size) + m.w) - { - // Bottom Left - d = distance(vec2(corner_radius - border_size) + vec2(margins.x, margins.w), uv * vec2(size)); - if (d - corner_radius <= 0.0) - { - if (d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else - c = vec4(0.0); - } else if (uv.x >= 1.0 - m.z - texelSize.x * (corner_radius - border_size) && uv.y <= texelSize.y * (corner_radius - border_size) + m.w) - { - // Bottom Right - d = distance(vec2(float(size.x) - (corner_radius - border_size) - margins.z, (corner_radius - border_size) + margins.w), uv * vec2(size)); - if (d - corner_radius <= 0.0) - { - if (d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else - c = vec4(0.0); - } else if (uv.x <= texelSize.x * (corner_radius - border_size) + m.x && uv.y >= 1.0 - texelSize.y * (corner_radius - border_size) - m.y) - { - // Top Left - d = distance(vec2((corner_radius - border_size) + margins.x, float(size.y) - (corner_radius - border_size) - margins.y), uv * vec2(size)); - if (d - corner_radius <= 0.0) - { - if (d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else - c = vec4(0.0); - } else if (uv.x >= 1.0 - texelSize.x * (corner_radius - border_size) - m.x && uv.y >= 1.0 - texelSize.y * (corner_radius - border_size) - m.y) - { - // Top Right - d = distance(vec2(vec2(size) - (corner_radius - border_size) - vec2(margins.z, margins.y)), uv * vec2(size)); - if (d - corner_radius <= 0.0) - { - if (d - (corner_radius - border_size) >= 0.0) - { - c = border_color; - } - } else - c = vec4(0.0); - } else if (uv.x < m.x || uv.x > 1.0 - m.z || uv.y < m.w || uv.y > 1.0 - m.y) - { - c = vec4(0.0); - } - out_color = mix(oc, c, progress); -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/src/filters.cpp wayfire-plugins-extra/subprojects/filters/src/filters.cpp --- wayfire-plugins-extra-0.10.0/subprojects/filters/src/filters.cpp 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/src/filters.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,670 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 Scott Moreau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static const char *vertex_shader = - R"( -#version 300 es - -in mediump vec2 position; -in mediump vec2 texcoord; - -out mediump vec2 uvpos; - -uniform mat4 mvp; - -void main() { - - gl_Position = mvp * vec4(position.xy, 0.0, 1.0); - uvpos = texcoord; -} -)"; - -// Supplied via ipc -// static const char *fragment_shader = -// R"( -// #version 100 -// @builtin_ext@ -// @builtin@ -// -// precision mediump float; -// -// varying mediump vec2 uvpos; -// -// void main() -// { -// vec4 c = get_pixel(uvpos); -// gl_FragColor = c; -// } -// )"; - -static std::string pixdecor_custom_data_name = "wf-decoration-shadow-margin"; - -class wf_shadow_margin_t : public wf::custom_data_t -{ - public: - wf::decoration_margins_t get_margins() - { - return margins; - } - - void set_margins(wf::decoration_margins_t margins) - { - this->margins = margins; - } - - private: - wf::decoration_margins_t margins = {0, 0, 0, 0}; -}; - -namespace wf -{ -namespace scene -{ -namespace filters -{ -const std::string transformer_name = "filters"; - -class wf_filters : public wf::scene::view_2d_transformer_t -{ - wayfire_view view; - wf::output_t *output; - OpenGL::program_t *shader; - std::unique_ptr fade; - - public: - OpenGL::program_t program; - class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t - { - wf::signal::connection_t on_node_damaged = - [=] (node_damage_signal *ev) - { - push_to_parent(ev->region); - }; - - wf_filters *self; - wayfire_view view; - damage_callback push_to_parent; - - public: - simple_node_render_instance_t(wf_filters *self, damage_callback push_damage, - wayfire_view view) : wf::scene::transformer_render_instance_t(self, - push_damage, - view->get_output()) - { - this->self = self; - this->view = view; - this->push_to_parent = push_damage; - self->connect(&on_node_damaged); - } - - ~simple_node_render_instance_t() - {} - - void schedule_instructions( - std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) - { - // We want to render ourselves only, the node does not have children - instructions.push_back(render_instruction_t{ - .instance = this, - .target = target, - .damage = damage & self->get_bounding_box(), - }); - } - - void render(const wf::scene::render_instruction_t& data) - { - wlr_box fb_geom = - data.target.framebuffer_box_from_geometry_box(data.target.geometry); - auto view_box = data.target.framebuffer_box_from_geometry_box( - self->get_children_bounding_box()); - view_box.x -= fb_geom.x; - view_box.y -= fb_geom.y; - - float x = view_box.x, y = view_box.y, w = view_box.width, - h = view_box.height; - - static const float vertexData[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - 1.0f, 1.0f, - -1.0f, 1.0f - }; - static const float texCoords[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f - }; - - auto src_tex = wf::gles_texture_t{get_texture(1.0)}; - data.pass->custom_gles_subpass(data.target,[&] - { - this->self->shader->use(src_tex.type); - this->self->shader->attrib_pointer("position", 2, 0, vertexData); - this->self->shader->attrib_pointer("texcoord", 2, 0, texCoords); - this->self->shader->uniformMatrix4f("mvp", wf::gles::output_transform(data.target)); - this->self->shader->uniform1f("progress", *self->fade); - this->self->shader->uniform1i("in_tex", 0); - - if (auto toplevel = wf::toplevel_cast(this->view)) - { - auto bg = view->get_surface_root_node()->get_bounding_box(); - auto vg = toplevel->get_geometry(); - auto margins = - glm::vec4{vg.x - bg.x, vg.y - bg.y, bg.width - ((vg.x - bg.x) + vg.width), - bg.height - ((vg.y - bg.y) + vg.height)}; - if (view->has_data(pixdecor_custom_data_name)) - { - auto decoration_margins = - view->get_data(pixdecor_custom_data_name)->get_margins(); - margins.x += decoration_margins.left; - margins.y += decoration_margins.bottom; - margins.z += decoration_margins.right; - margins.w += decoration_margins.top; - } - - // XXX: Pad the margins if there are none, so that the shader renders on the surface - if (bg == vg) - { - margins.x += 2.0; - margins.y += 2.0; - margins.z += 2.0; - margins.w += 2.0; - } - - this->self->shader->uniform4f("margins", margins); - } - - GL_CALL(glActiveTexture(GL_TEXTURE0)); - this->self->shader->set_active_texture(src_tex); - - /* Render it to target */ - wf::gles::bind_render_buffer(data.target); - GL_CALL(glViewport(x, y, w, h)); - - GL_CALL(glEnable(GL_BLEND)); - GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - - for (const auto& box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); - } - - /* Disable stuff */ - GL_CALL(glDisable(GL_BLEND)); - GL_CALL(glActiveTexture(GL_TEXTURE0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); - - this->self->shader->deactivate(); - }); - } - }; - - wf_filters(wayfire_view view, std::string shader_path) : wf::scene::view_2d_transformer_t(view) - { - this->view = view; - this->shader = &program; - if (view->get_output()) - { - output = view->get_output(); - output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - - std::ifstream t(shader_path); - std::string fragment_shader((std::istreambuf_iterator(t)), std::istreambuf_iterator()); - wf::gles::run_in_context([&] - { - program.compile(vertex_shader, fragment_shader); - }); - fade = std::make_unique(wf::create_option(700)); - fade->set(0.0, 0.0); - fade->animate(1.0); - } - - void unapply() - { - fade->animate(0.0); - } - - void pop_transformer(wayfire_view view) - { - if (view->get_transformed_node()->get_transformer(transformer_name)) - { - LOGI("Removing shader and transformer."); - view->get_transformed_node()->rem_transformer(transformer_name); - } - } - - wf::effect_hook_t pre_hook = [=] () - { - if (fade->running()) - { - for (auto & v : wf::get_core().get_all_views()) - { - v->damage(); - } - } else if (fade->end == 0.0) - { - pop_transformer(view); - } - }; - - void gen_render_instances(std::vector& instances, - damage_callback push_damage, wf::output_t *shown_on) override - { - instances.push_back(std::make_unique( - this, push_damage, view)); - } - - virtual ~wf_filters() - { - wf::gles::run_in_context([&] - { - program.free_resources(); - }); - fade.reset(); - if (output) - { - output->render->rem_effect(&pre_hook); - } - } -}; - -class wayfire_per_output_filters : public wf::per_output_plugin_instance_t -{ - std::unique_ptr fade; - std::shared_ptr program = nullptr; - wf::post_hook_t hook; - bool active = false; - - public: - void init() override - { - hook = [=] (wf::auxilliary_buffer_t& aux_buf, const wf::render_buffer_t& render_buf) - { - render(aux_buf, render_buf); - }; - fade = std::make_unique(wf::create_option(700)); - fade->set(0.0, 0.0); - } - - wf::effect_hook_t pre_hook = [=] () - { - if (fade->running()) - { - output->render->damage_whole(); - for (auto & v : wf::get_core().get_all_views()) - { - v->damage(); - } - } else if (fade->end == 0.0) - { - output->render->rem_effect(&pre_hook); - output->render->rem_post(&hook); - output->render->damage_whole(); - if (program) - { - wf::gles::run_in_context([&] - { - program->free_resources(); - }); - } - - program = nullptr; - active = false; - } - }; - - wf::json_t set_fs_shader(std::string shader) - { - if (program) - { - wf::gles::run_in_context([&] - { - program->free_resources(); - }); - } else - { - program = std::make_shared(); - } - - std::ifstream t(shader); - std::string fragment_shader((std::istreambuf_iterator(t)), std::istreambuf_iterator()); - wf::gles::run_in_context([&] - { - program->compile(vertex_shader, fragment_shader); - }); - if (program->get_program_id(wf::TEXTURE_TYPE_RGBA) == 0) - { - LOGE("Failed to compile fullscreen shader."); - output->render->rem_post(&hook); - program = nullptr; - return wf::ipc::json_error("Failed to compile fullscreen shader."); - } - - output->render->damage_whole(); - - if (active) - { - LOGI("Successfully compiled and applied fullscreen shader to output: ", output->to_string()); - return wf::ipc::json_ok(); - } - - output->render->add_post(&hook); - output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - fade->animate(1.0); - active = true; - - LOGI("Successfully compiled and applied fullscreen shader to output: ", output->to_string()); - return wf::ipc::json_ok(); - } - - wf::json_t unset_fs_shader() - { - fade->animate(0.0); - return wf::ipc::json_ok(); - } - - wf::json_t fs_has_shader() - { - auto response = wf::ipc::json_ok(); - response["has-shader"] = active; - return response; - } - - void render(wf::auxilliary_buffer_t& aux_buf, const wf::render_buffer_t& render_buf) - { - static const float vertexData[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - 1.0f, 1.0f, - -1.0f, 1.0f - }; - static const float texCoords[] = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - 0.0f, 0.0f - }; - - wf::gles::run_in_context([&] - { - /* Upload data to shader */ - program->use(wf::TEXTURE_TYPE_RGBA); - program->attrib_pointer("position", 2, 0, vertexData); - program->attrib_pointer("texcoord", 2, 0, texCoords); - program->uniformMatrix4f("mvp", glm::mat4(1.0)); - program->uniform1f("progress", *fade); - program->uniform1i("in_tex", 0); - GL_CALL(glActiveTexture(GL_TEXTURE0)); - program->set_active_texture(wf::gles_texture_t::from_aux(aux_buf)); - - /* Render it to aux_buf */ - wf::gles::bind_render_buffer(render_buf); - GL_CALL(glViewport(0, 0, aux_buf.get_size().width, aux_buf.get_size().height)); - - GL_CALL(glEnable(GL_BLEND)); - GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - - GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); - - /* Disable stuff */ - GL_CALL(glDisable(GL_BLEND)); - GL_CALL(glActiveTexture(GL_TEXTURE0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); - - program->deactivate(); - }); - } - - void fini() override - { - output->render->rem_effect(&pre_hook); - output->render->rem_post(&hook); - output->render->damage_whole(); - if (program) - { - wf::gles::run_in_context([&] - { - program->free_resources(); - }); - } - - fade.reset(); - } -}; - -class wayfire_filters : public wf::plugin_interface_t, - public wf::per_output_tracker_mixin_t -{ - wf::shared_data::ref_ptr_t ipc_repo; - - void pop_transformer(wayfire_view view) - { - if (view->get_transformed_node()->get_transformer(transformer_name)) - { - LOGI("Removing shader and transformer."); - view->get_transformed_node()->rem_transformer(transformer_name); - } - } - - void remove_transformers() - { - for (auto& view : wf::get_core().get_all_views()) - { - pop_transformer(view); - } - } - - public: - void init() override - { - ipc_repo->register_method("wf/filters/set-view-shader", ipc_set_view_shader); - ipc_repo->register_method("wf/filters/unset-view-shader", ipc_unset_view_shader); - ipc_repo->register_method("wf/filters/view-has-shader", ipc_view_has_shader); - ipc_repo->register_method("wf/filters/set-fs-shader", ipc_set_fs_shader); - ipc_repo->register_method("wf/filters/unset-fs-shader", ipc_unset_fs_shader); - ipc_repo->register_method("wf/filters/fs-has-shader", ipc_fs_has_shader); - - per_output_tracker_mixin_t::init_output_tracking(); - } - - void handle_new_output(wf::output_t *output) override - { - per_output_tracker_mixin_t::handle_new_output(output); - } - - void handle_output_removed(wf::output_t *output) override - { - per_output_tracker_mixin_t::handle_output_removed(output); - } - - std::shared_ptr ensure_transformer(wayfire_view view, std::string shader_path) - { - auto tmgr = view->get_transformed_node(); - if (tmgr->get_transformer(transformer_name)) - { - view->get_transformed_node()->rem_transformer(transformer_name); - } - - auto node = std::make_shared(view, shader_path); - tmgr->add_transformer(node, wf::TRANSFORMER_2D, transformer_name); - - return tmgr->get_transformer(transformer_name); - } - - wf::ipc::method_callback ipc_set_view_shader = [=] (wf::json_t data) -> wf::json_t - { - auto view_id = wf::ipc::json_get_uint64(data, "view-id"); - auto shader_path = wf::ipc::json_get_string(data, "shader-path"); - - auto view = wf::ipc::find_view_by_id(view_id); - if (view) - { - auto tr = ensure_transformer(view, shader_path); - if (tr->program.get_program_id(wf::TEXTURE_TYPE_RGBA) == 0) - { - pop_transformer(view); - LOGE("Failed to compile shader."); - return wf::ipc::json_error("Failed to compile shader."); - } - } else - { - LOGE("Failed to find view with given id. Maybe it isn't mapped?"); - return wf::ipc::json_error("Failed to find view with given id. Maybe it isn't mapped?"); - } - - LOGI("Successfully compiled and applied shader."); - view->damage(); - return wf::ipc::json_ok(); - }; - - wf::ipc::method_callback ipc_unset_view_shader = [=] (wf::json_t data) -> wf::json_t - { - auto view_id = wf::ipc::json_get_uint64(data, "view-id"); - - auto view = wf::ipc::find_view_by_id(view_id); - if (view) - { - auto tmgr = view->get_transformed_node(); - if (auto tr = tmgr->get_transformer(transformer_name)) - { - tr->unapply(); - view->damage(); - } - } - - return wf::ipc::json_ok(); - }; - - wf::ipc::method_callback ipc_view_has_shader = [=] (wf::json_t data) -> wf::json_t - { - auto view_id = wf::ipc::json_get_uint64(data, "view-id"); - - auto view = wf::ipc::find_view_by_id(view_id); - if (!view) - { - return wf::ipc::json_error("Failed to find view with given id."); - } - - auto tmgr = view->get_transformed_node(); - auto response = wf::ipc::json_ok(); - response["has-shader"] = tmgr->get_transformer(transformer_name) ? true : false; - return response; - }; - - wf::output_t *find_output_by_name(std::string name) - { - for (auto & output : wf::get_core().output_layout->get_outputs()) - { - if (output->to_string() == name) - { - return output; - } - } - - return nullptr; - } - - wf::ipc::method_callback ipc_set_fs_shader = [=] (wf::json_t data) -> wf::json_t - { - auto output_name = wf::ipc::json_get_string(data, "output-name"); - auto shader_path = wf::ipc::json_get_string(data, "shader-path"); - - auto output = find_output_by_name(output_name); - if (!output) - { - return wf::ipc::json_error("No such output"); - } - - return this->output_instance[output]->set_fs_shader(shader_path); - }; - - wf::ipc::method_callback ipc_unset_fs_shader = [=] (wf::json_t data) -> wf::json_t - { - auto output_name = wf::ipc::json_get_string(data, "output-name"); - - auto output = find_output_by_name(output_name); - if (!output) - { - return wf::ipc::json_error("No such output"); - } - - return this->output_instance[output]->unset_fs_shader(); - }; - - wf::ipc::method_callback ipc_fs_has_shader = [=] (wf::json_t data) -> wf::json_t - { - auto output_name = wf::ipc::json_get_string(data, "output-name"); - - auto output = find_output_by_name(output_name); - if (!output) - { - return wf::ipc::json_error("No such output"); - } - - return this->output_instance[output]->fs_has_shader(); - }; - - void fini() override - { - per_output_tracker_mixin_t::fini_output_tracking(); - - ipc_repo->unregister_method("wf/filters/set-view-shader"); - ipc_repo->unregister_method("wf/filters/unset-view-shader"); - ipc_repo->unregister_method("wf/filters/view-has-shader"); - ipc_repo->unregister_method("wf/filters/set-fs-shader"); - ipc_repo->unregister_method("wf/filters/unset-fs-shader"); - ipc_repo->unregister_method("wf/filters/fs-has-shader"); - - remove_transformers(); - } -}; -} -} -} - -DECLARE_WAYFIRE_PLUGIN(wf::scene::filters::wayfire_filters); diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/filters/src/meson.build wayfire-plugins-extra/subprojects/filters/src/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/filters/src/meson.build 2025-07-15 06:13:43.000000000 -0600 +++ wayfire-plugins-extra/subprojects/filters/src/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,4 +0,0 @@ -filters = shared_module('filters', ['filters.cpp'], - dependencies: [wayfire], - install: true, - install_dir: join_paths(get_option('libdir'), 'wayfire')) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/focus-request/focus-request.xml wayfire-plugins-extra/subprojects/focus-request/focus-request.xml --- wayfire-plugins-extra-0.10.0/subprojects/focus-request/focus-request.xml 2024-03-11 00:12:33.000000000 -0600 +++ wayfire-plugins-extra/subprojects/focus-request/focus-request.xml 1969-12-31 17:00:00.000000000 -0700 @@ -1,38 +0,0 @@ - - - - <_short>Focus Request - <_long>A simple plugin to handle various focus request events of wayfire. - Desktop - - - - - - - - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/focus-request/LICENSE wayfire-plugins-extra/subprojects/focus-request/LICENSE --- wayfire-plugins-extra-0.10.0/subprojects/focus-request/LICENSE 2024-03-11 00:12:33.000000000 -0600 +++ wayfire-plugins-extra/subprojects/focus-request/LICENSE 1969-12-31 17:00:00.000000000 -0700 @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 WayfirePlugins - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/focus-request/meson.build wayfire-plugins-extra/subprojects/focus-request/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/focus-request/meson.build 2024-03-11 00:12:33.000000000 -0600 +++ wayfire-plugins-extra/subprojects/focus-request/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,26 +0,0 @@ -project( - 'focus-request', - 'c', - 'cpp', - version: '0.1.0', - license: 'MIT', - meson_version: '>=0.51.0', - default_options: [ - 'cpp_std=c++17', - 'c_std=c11', - ], -) - -add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c']) -add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c']) -add_project_link_arguments(['-rdynamic','-fPIC'], language:'cpp') - -wayfire = dependency('wayfire') - -shared_module( 'focus-request', [ 'wf-focus-request.cpp' ], - dependencies: wayfire, - install: true, - install_dir: join_paths(get_option('libdir'), 'wayfire') -) - -install_data( 'focus-request.xml', install_dir: wayfire.get_variable( pkgconfig: 'metadatadir' ) ) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/focus-request/wf-focus-request.cpp wayfire-plugins-extra/subprojects/focus-request/wf-focus-request.cpp --- wayfire-plugins-extra-0.10.0/subprojects/focus-request/wf-focus-request.cpp 2024-03-11 00:12:33.000000000 -0600 +++ wayfire-plugins-extra/subprojects/focus-request/wf-focus-request.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,279 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2021 Marcus Britanicus - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - **/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -std::string ltrim( const std::string& s ) { - size_t start = s.find_first_not_of( ' ' ); - - return (start == std::string::npos) ? "" : s.substr( start ); -} - - -std::string rtrim( const std::string& s ) { - size_t end = s.find_last_not_of( ' ' ); - - return (end == std::string::npos) ? "" : s.substr( 0, end + 1 ); -} - - -std::string trim( const std::string& s ) { - return rtrim( ltrim( s ) ); -} - - -std::vector split( const std::string& s ) { - std::stringstream ss( s ); - std::vector list; - - for ( std::string line; std::getline( ss, line, ',' ); ) { - list.push_back( trim( line ) ); - } - - return list; -} - - -class wayfire_focus_request : public wf::plugin_interface_t { - wayfire_view last_focus_view = nullptr; - std::vector attention_list; - - wf::option_wrapper_t focus_key{ "focus-request/focus_last_demand" }; - - wf::activator_callback cb = - [ = ] ( auto ) { - if ( attention_list.size() == 0 ) { - LOGE( "Nothing to focus" ); - return true; - } - - /** Take the last element */ - wayfire_view view = attention_list.back(); - - if ( view == nullptr ) { - LOGE( "[FocusRequest] Nothing to activate." ); - return true; - } - - LOGE( "[FocusRequest] Activating view ", view->get_app_id(), " (", view->get_id(), ") ", view->get_title() ); - - /** Bring it to the front */ - wf::get_core().default_wm->focus_raise_view( view ); - - LOGE( "[FocusRequest] Attention list size (before) ", attention_list.size() ); - - /** Remove it from the list */ - attention_list.pop_back(); - - LOGE( "[FocusRequest] Attention list size (after) ", attention_list.size() ); - - return true; - }; - - wf::signal::connection_t onFocusRequested { - [ = ] (wf::view_focus_request_signal *ev) { - LOGD( "[FocusRequest] view_focus_request_signal intercepted: ", ev->view->get_app_id(), " (", ev->view->get_id(), ")" ); - /** Cast it into a toplevel object */ - auto toplevel = wf::toplevel_cast( ev->view ); - - /** Worry about this only if it's a toplevel */ - if ( toplevel == nullptr ) { - return; - } - - LOGD( "[FocusRequest] Self-request: ", ev->self_request, "; carried out: ", ev->carried_out ); - - /** Get the focus stealing timeout */ - wf::option_wrapper_t focus_timeout{ "focus-request/focus_stealing_timeout" }; - - LOGD( "[FocusRequest] FSP Timeout ", focus_timeout.value() ); - - /** Grant focus to these views unconditionally */ - wf::view_matcher_t always_auto_focus{ "focus-request/auto_focus_views" }; - - /** If this is one of the views which always get focus */ - if ( always_auto_focus.matches( ev->view ) ) { - LOGD( "[FocusRequest] Granting focus to always-view ", toplevel->get_app_id(), " (", ev->view->get_id(), ")" ); - wf::get_core().default_wm->focus_raise_view( ev->view, true ); - - /** Mark this as carried out */ - ev->carried_out = true; - } - - /** Focus children of the current view unconditionally */ - wf::option_wrapper_t auto_focus_children{ "focus-request/auto_focus_children" }; - - /** Parent of the current */ - auto parent_view = toplevel->parent; - - /** Check if this the child of the currently focused view. Grant focus if needed */ - if ( (parent_view != nullptr) && (auto_focus_children.value() == true) ) { - auto current_focus = wf::get_core().get_cursor_focus_view(); - - if ( (current_focus != nullptr) && (parent_view == current_focus) ) { - LOGD( "[FocusRequest] Granting focus to child ", toplevel->get_app_id(), " (", ev->view->get_id(), ")" ); - wf::get_core().default_wm->focus_raise_view( toplevel ); - - /** Mark this as carried out */ - ev->carried_out = true; - - /** We're done here */ - return; - } - } - - /** We're now interested only in self-requests */ - if ( ev->self_request and not ev->carried_out ) { - /** We'll either deny or acquiesce this request. So mark as carried out. */ - ev->carried_out = true; - - LOGD( "[FocusRequest] Recieved focus request. ", toplevel->get_app_id(), " (", ev->view->get_id(), ")" ); - - /** Grant it focus automatically, or just highlight it? */ - wf::option_wrapper_t auto_grant_focus{ "focus-request/auto_grant_focus" }; - - /** If the request is to be granted without ado, let's do that */ - if ( auto_grant_focus.value() == true ) { - LOGD( "[FocusRequest] Granting focus ", toplevel->get_app_id(), " (", ev->view->get_id(), ")" ); - wf::get_core().default_wm->focus_raise_view( toplevel ); - - /** We're done here */ - return; - } - - /** - * None of the above applied. So set demands attention flag and emit - * view_hints_changed_signal - */ - LOGD( "[FocusRequest] Setting demands-attention hint ", toplevel->get_app_id(), " (", ev->view->get_id(), ")" ); - wf::view_hints_changed_signal hints_signal; - hints_signal.view = ev->view; - hints_signal.demands_attention = true; - ev->view->emit( &hints_signal ); - wf::get_core().emit( &hints_signal ); - } - } - }; - - wf::signal::connection_t onViewHintsChanged { - [ = ] (wf::view_hints_changed_signal *ev) { - /** Check if the view is in the list */ - auto it = std::find( attention_list.begin(), attention_list.end(), ev->view ); - - LOGE( "[FocusRequest] View hints changed ", ev->view->get_app_id(), " (", ev->view->get_id(), ") ", ev->demands_attention ); - - std::string appid = ev->view->get_app_id(); - if ( ( appid.size() == 0 ) || ( appid == "nil" ) || ( appid == " " ) ) { - LOGE( "[FocusRequest] weird app (", ev->view->get_id(), ") ignoring." ); - return; - } - - /** demands_attention was set on this view */ - if ( ev->demands_attention ) { - /** Current view in the list: move it to the end */ - if ( it != attention_list.end() ) { - int idx = it - attention_list.begin(); - std::swap( attention_list[ idx ], attention_list.back() ); - LOGE( "[FocusRequest] attention list size ", attention_list.size() ); - } - - /** Current view not in the list: add it to the end */ - else { - attention_list.push_back( ev->view ); - LOGE( "[FocusRequest] attention list size ", attention_list.size() ); - } - - ev->view->get_output()->connect( &onViewDisappeared ); - } - - /** demands_attention was removed from this view */ - else { - /** Current view in the list: remove it */ - if ( it != attention_list.end() ) { - attention_list.erase( it ); - LOGE( "[FocusRequest] attention list size ", attention_list.size() ); - } - } - } - }; - - wf::signal::connection_t onViewDisappeared { - [ = ] (wf::view_disappeared_signal *ev) { - if ( ev->view == nullptr ) { - return; - } - - /** Check if the view is in the list */ - auto it = std::find( attention_list.begin(), attention_list.end(), ev->view ); - - if ( it != attention_list.end() ) { - int idx = it - attention_list.begin(); - LOGE( "[FocusRequest] removing view ", ev->view->get_id(), " ", ev->view->get_app_id() ); - std::swap( attention_list[ idx ], attention_list.back() ); - LOGE( "[FocusRequest] attention list size ", attention_list.size() ); - } - } - }; - - public: - void init() override { - wf::get_core().connect( &onFocusRequested ); - wf::get_core().connect( &onViewHintsChanged ); - - /** Get the currently focused view */ - last_focus_view = wf::get_core().get_cursor_focus_view(); - - /** Add the binding, this first time when the plugin is init */ - LOGE( "[FocusRequest] Adding activator" ); - - /** Add this to the list of bindings */ - wf::get_core().bindings->add_activator( focus_key, &cb ); - } - - bool is_unloadable() override { - return true; - } - - void fini() override { - wf::get_core().disconnect( &onFocusRequested ); - } -}; - -DECLARE_WAYFIRE_PLUGIN( wayfire_focus_request ); diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/ipc-scripts/ipc-shade-toggle.py wayfire-plugins-extra/subprojects/pixdecor/ipc-scripts/ipc-shade-toggle.py --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/ipc-scripts/ipc-shade-toggle.py 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/ipc-scripts/ipc-shade-toggle.py 1969-12-31 17:00:00.000000000 -0700 @@ -1,15 +0,0 @@ -#!/usr/bin/python3 - -import os -import sys -from wayfire import WayfireSocket -from wayfire.extra.wpe import WPE - -if len(sys.argv) < 2: - print(f"Usage: {sys.argv[0]} ") - exit(1) - -sock = WayfireSocket() -wpe = WPE(sock) - -wpe.shade_toggle(int(sys.argv[1])) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/LICENSE wayfire-plugins-extra/subprojects/pixdecor/LICENSE --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/LICENSE 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/LICENSE 1969-12-31 17:00:00.000000000 -0700 @@ -1,23 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2024 Scott Moreau -Copyright (c) 2024 Ilia Bozhinov -Copyright (c) 2024 Andrew Pliatsikas - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/meson.build wayfire-plugins-extra/subprojects/pixdecor/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/meson.build 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,23 +0,0 @@ -project( - 'pixdecor', - 'c', - 'cpp', - version: '0.1.0', - license: 'MIT', - meson_version: '>=0.51.0', - default_options: [ - 'cpp_std=c++17', - 'c_std=c11', - ], -) - -add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c']) -add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c']) -add_project_link_arguments(['-rdynamic','-fPIC'], language:'cpp') - -wayfire = dependency('wayfire', version: '>=0.9.0') - - -subdir('src') -subdir('metadata') - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/metadata/meson.build wayfire-plugins-extra/subprojects/pixdecor/metadata/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/metadata/meson.build 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/metadata/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1 +0,0 @@ -install_data( 'pixdecor.xml', install_dir: wayfire.get_variable( pkgconfig: 'metadatadir' ) ) \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/metadata/pixdecor.xml wayfire-plugins-extra/subprojects/pixdecor/metadata/pixdecor.xml --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/metadata/pixdecor.xml 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/metadata/pixdecor.xml 1969-12-31 17:00:00.000000000 -0700 @@ -1,268 +0,0 @@ - - - - <_short>Pix Decoration - <_long>A highly configurable and optionally fancy decorator plugin for wayfire. - Effects - - <_short>General - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_short>Shade - - - - - - - - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/README.md wayfire-plugins-extra/subprojects/pixdecor/README.md --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/README.md 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/README.md 1969-12-31 17:00:00.000000000 -0700 @@ -1,20 +0,0 @@ -# pixdecor -![pixdecor](https://github.com/soreau/pixdecor/assets/1450125/af891554-8eeb-4769-b571-fa587afd8350) - -A highly configurable decorator plugin for wayfire, pixdecor features antialiased rounded corners with shadows and optional animated effects. - -## Installing - -Set `--prefix` to the same as the wayfire installation. - -``` -$ meson setup build --prefix=/usr -$ ninja -C build -# ninja -C build install -``` - -Restart wayfire. - -## Running - -Disable other decorator plugins and enable pixdecor plugin in core section of `wayfire.ini`. diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-button.cpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-button.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-button.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-button.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,120 +0,0 @@ -#include "deco-button.hpp" -#include "deco-theme.hpp" -#include -#include -#include - -#define NORMAL 1.0 -#define PRESSED 0.5 -#define HOVERED 0.25 - -namespace wf -{ -namespace pixdecor -{ -button_t::button_t(pixdecor_theme_t& t, std::function damage) : - theme(t), damage_callback(damage) -{} - -wf::dimensions_t button_t::set_button_type(button_type_t type) -{ - this->type = type; - this->hover.animate(NORMAL, NORMAL); - auto size = update_texture(); - add_idle_damage(); - - return size; -} - -button_type_t button_t::get_button_type() const -{ - return this->type; -} - -void button_t::set_hover(bool is_hovered) -{ - this->is_hovered = is_hovered; - if (!this->is_pressed) - { - if (is_hovered) - { - this->hover.animate(HOVERED); - } else - { - this->hover.animate(NORMAL); - } - } - - add_idle_damage(); -} - -/** - * Set whether the button is pressed or not. - * Affects appearance. - */ -void button_t::set_pressed(bool is_pressed) -{ - this->is_pressed = is_pressed; - if (is_pressed) - { - this->hover.animate(PRESSED); - } else - { - this->hover.animate(is_hovered ? HOVERED : NORMAL); - } - - add_idle_damage(); -} - -void button_t::render(const wf::scene::render_instruction_t& data, wf::geometry_t geometry) -{ - OpenGL::render_texture(wf::gles_texture_t{button_texture.get_texture()}, data.target, geometry, {1, 1, 1, this->hover}, - OpenGL::RENDER_FLAG_CACHED); - data.pass->custom_gles_subpass(data.target,[&] - { - for (auto& box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::draw_cached(); - } - }); - - OpenGL::clear_cached(); - - if (this->hover.running()) - { - add_idle_damage(); - } -} - -wf::dimensions_t button_t::update_texture() -{ - pixdecor_theme_t::button_state_t state = { - .width = 1.0 * (theme.get_font_height_px() >= LARGE_ICON_THRESHOLD ? 26 : 18), - .height = 1.0 * (theme.get_font_height_px() >= LARGE_ICON_THRESHOLD ? 26 : 18), - .border = 1.0, - .hover = this->is_hovered, - }; - - auto surface = theme.get_button_surface(type, state, this->active); - wf::dimensions_t size{cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface)}; - - wf::gles::run_in_context([&] - { - this->button_texture = owned_texture_t{surface}; - }); - - cairo_surface_destroy(surface); - - return size; -} - -void button_t::add_idle_damage() -{ - this->idle_damage.run_once([=] () - { - this->damage_callback(); - }); -} -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-button.hpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-button.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-button.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-button.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,98 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace wf -{ -namespace pixdecor -{ -class pixdecor_theme_t; - -enum button_type_t -{ - BUTTON_CLOSE, - BUTTON_TOGGLE_MAXIMIZE, - BUTTON_MINIMIZE, -}; - -class button_t -{ - public: - /** - * Create a new button with the given theme. - * @param theme The theme to use. - * @param damage_callback A callback to execute when the button needs a - * repaint. Damage won't be reported while render() is being called. - */ - button_t(pixdecor_theme_t& theme, - std::function damage_callback); - - /** - * Set the type of the button. This will affect the displayed icon and - * potentially other appearance like colors. - */ - wf::dimensions_t set_button_type(button_type_t type); - - /** @return The type of the button */ - button_type_t get_button_type() const; - - /** - * Set the button hover state. - * Affects appearance. - */ - void set_hover(bool is_hovered); - - /** - * Set whether the button is pressed or not. - * Affects appearance. - */ - void set_pressed(bool is_pressed); - - /** - * Render the button on the given framebuffer at the given coordinates. - * Precondition: set_button_type() has been called, otherwise result is no-op - * - * @param buffer The target framebuffer - * @param geometry The geometry of the button, in logical coordinates - * @param scissor The scissor rectangle to render. - */ - void render(const wf::scene::render_instruction_t& data, wf::geometry_t geometry); - - pixdecor_theme_t& theme; - std::function damage_callback; - - private: - - button_type_t type; - wf::owned_texture_t button_texture; - bool active = false; - wf::geometry_t geometry; - - /* Whether the button is currently being hovered */ - bool is_hovered = false; - /* Whether the button is currently being held */ - bool is_pressed = false; - /* The shade of button background to use. */ - wf::animation::simple_animation_t hover{wf::create_option(500)}; - - wf::wl_idle_call idle_damage; - /** Damage button the next time the main loop goes idle */ - void add_idle_damage(); - - /** - * Redraw the button surface and store it as a texture - */ - wf::dimensions_t update_texture(); -}; -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-effects.cpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-effects.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-effects.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-effects.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,2624 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 Scott Moreau - * - Ported weston-smoke to compute shader set - * Copyright (c) 2024 Ilia Bozhinov - * - Awesome optimizations - * Copyright (c) 2024 Andrew Pliatsikas - * - Ported effect shaders to compute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - - -#include -#include - -#include "deco-effects.hpp" -#include "smoke-shaders.hpp" - - -namespace wf -{ -namespace pixdecor -{ -static std::string stitch_smoke_shader(const std::string& source) -{ - return smoke_header + source + effect_run_for_region_main; -} - -// ported from https://www.shadertoy.com/view/WdXBW4 -static const char *render_source_clouds = - R"( -#version 320 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float current_time; -float cloudscale=2.1; // Added cloudscale parameter - -const mat2 m = mat2(1.6, 1.2, -1.2, 1.6); - -vec2 hash(vec2 p) { - p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); - return -1.0 + 2.0 * fract(sin(p) * 43758.5453123); -} - -float noise(vec2 p) { - const float K1 = 0.366025404; // (sqrt(3)-1)/2; - const float K2 = 0.211324865; // (3-sqrt(3))/6; - vec2 i = floor(p + (p.x + p.y) * K1); - vec2 a = p - i + (i.x + i.y) * K2; - vec2 o = (a.x > a.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); - vec2 b = a - o + K2; - vec2 c = a - 1.0 + 2.0 * K2; - vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0); - vec3 n = h * h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0))); - return dot(n, vec3(70.0)); -} - -float fbm(vec2 n) { - float total = 0.0, amplitude = 0.1; - for (int i = 0; i < 7; i++) { - total += noise(n) * amplitude; - n = m * n; - amplitude *= 0.4; - } - return total; -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - int x = pos.x; - int y = pos.y; - - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - vec2 uv = vec2(pos) / vec2(gl_NumWorkGroups.x * gl_WorkGroupSize.x, gl_NumWorkGroups.y * gl_WorkGroupSize.y); - - float time = 0.003 * current_time; // Time variable for animation - - float cloudPattern1 = fbm(uv * 10.0 * cloudscale + time); - float cloudPattern2 = fbm(uv * 5.0 * cloudscale + time); - float cloudPattern3 = fbm(uv * 3.0 * cloudscale + time); - - // Combine different cloud patterns with different weights - float cloudPattern = 0.5 * cloudPattern1 + 0.3 * cloudPattern2 + 0.2 * cloudPattern3; - - // Ridge noise shape - float ridgeNoiseShape = 0.0; - uv *= cloudscale * 1.1; // Adjust scale - float weight = 0.8; - for (int i = 0; i < 8; i++) { - ridgeNoiseShape += abs(weight * noise(uv)); - uv = m * uv + time; - weight *= 0.7; - } - - // Noise shape - float noiseShape = 0.0; - uv = vec2(pos) / vec2(gl_NumWorkGroups.x * gl_WorkGroupSize.x, gl_NumWorkGroups.y * gl_WorkGroupSize.y); - uv *= cloudscale * 1.1; // Adjust scale - weight = 0.7; - for (int i = 0; i < 8; i++) { - noiseShape += weight * noise(uv); - uv = m * uv + time; - weight *= 0.6; - } - - noiseShape *= ridgeNoiseShape + noiseShape; - - // Noise color - float noiseColor = 0.0; - uv = vec2(pos) / vec2(gl_NumWorkGroups.x * gl_WorkGroupSize.x, gl_NumWorkGroups.y * gl_WorkGroupSize.y); - uv *= 2.0 * cloudscale; // Adjust scale - weight = 0.4; - for (int i = 0; i < 7; i++) { - noiseColor += weight * noise(uv); - uv = m * uv + time; - weight *= 0.6; - } - - // Noise ridge color - float noiseRidgeColor = 0.0; - uv = vec2(pos) / vec2(gl_NumWorkGroups.x * gl_WorkGroupSize.x, gl_NumWorkGroups.y * gl_WorkGroupSize.y); - uv *= 3.0 * cloudscale; // Adjust scale - weight = 0.4; - for (int i = 0; i < 7; i++) { - noiseRidgeColor += abs(weight * noise(uv)); - uv = m * uv + time; - weight *= 0.6; - } - - noiseColor += noiseRidgeColor; - - // Sky tint - float skytint = 0.5; - vec3 skyColour1 = vec3(0.1, 0.2, 0.3); - vec3 skyColour2 = vec3(0.4, 0.7, 1.0); - vec3 skycolour = mix(skyColour1, skyColour2, smoothstep(0.4, 0.6, uv.y)); - - // Cloud darkness - float clouddark = 0.5; - - // Cloud Cover, Cloud Alpha - float cloudCover = 0.01; - float cloudAlpha = 2.0; - - // Movement effect - uv = uv + time; - - // Use a bright color for clouds - vec3 cloudColor = vec3(1.0, 1.0, 1.0); ; // Bright white color for clouds - - // Mix the cloud color with the background, considering darkness, cover, and alpha - vec3 finalColor = mix(skycolour, cloudColor * clouddark, cloudPattern + noiseShape + noiseColor) * (1.0 - cloudCover) + cloudColor * cloudCover; - finalColor = mix(skycolour, finalColor, cloudAlpha); - - imageStore(out_tex, pos, vec4(finalColor, 1.0)); -} - - - -)"; - -// ported from https://github.com/keijiro/ShaderSketches/blob/master/Fragment/Dots3.glsl -static const char *render_source_halftone = - R"( -#version 310 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float time; - -const vec2 resolution = vec2(1280.0, 720.0); -const float timeFactor = 0.025; - -float rand(vec2 uv) { - return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); -} - -vec2 rotate(vec2 p, float theta) { - vec2 sncs = vec2(sin(theta), cos(theta)); - return vec2(p.x * sncs.y - p.y * sncs.x, p.x * sncs.x + p.y * sncs.y); -} - -float swirl(vec2 coord, float t) { - float l = length(coord) / resolution.x; - float phi = atan(coord.y, coord.x + 1e-6); - return sin(l * 10.0 + phi - t * 4.0) * 0.5 + 0.5; -} - -float halftone(vec2 coord, float angle, float t, float amp) { - coord -= resolution * 0.5; - float size = resolution.x / (60.0 + sin(time * timeFactor * 0.5) * 50.0); - vec2 uv = rotate(coord / size, angle / 180.0 * 3.14); - vec2 ip = floor(uv); // column, row - vec2 odd = vec2(0.5 * mod(ip.y, 2.0), 0.0); // odd line offset - vec2 cp = floor(uv - odd) + odd; // dot center - float d = length(uv - cp - 0.5) * size; // distance - float r = swirl(cp * size, t) * size * 0.5 * amp; // dot radius - return 1.0 - clamp(d - r, 0.0, 1.0); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - // Extract x and y coordinates - int x = pos.x; - int y = pos.y; - - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - vec3 c1 = 1.0 - vec3(1.0, 0.0, 0.0) * halftone(vec2(pos), 0.0, time * timeFactor * 1.00, 0.7); - vec3 c2 = 1.0 - vec3(0.0, 1.0, 0.0) * halftone(vec2(pos), 30.0, time * timeFactor * 1.33, 0.7); - vec3 c3 = 1.0 - vec3(0.0, 0.0, 1.0) * halftone(vec2(pos), -30.0, time * timeFactor * 1.66, 0.7); - vec3 c4 = 1.0 - vec3(1.0, 1.0, 1.0) * halftone(vec2(pos), 60.0, time * timeFactor * 2.13, 0.4); - - // Output the final color - imageStore(out_tex, pos, vec4(c1 * c2 * c3 * c4, 1.0)); -} -)"; - -// ported from https://www.shadertoy.com/view/WdjGRc -static const char *render_source_lava = - R"( -#version 320 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) uniform readonly image2D in_tex; -layout(binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float current_time; - -vec3 effect(float speed, vec2 uv, float time, float scale) { - float t = mod(time * 0.005, 6.0); - float rt = 0.00000000000001 * sin(t * 0.45); - - mat2 m1 = mat2(cos(rt), -sin(rt), -sin(rt), cos(rt)); - vec2 uva = uv * m1 * scale; - float irt = 0.005 * cos(t * 0.05); - mat2 m2 = mat2(sin(irt), cos(irt), -cos(irt), sin(irt)); - - for (int i = 1; i < 40; i += 1) { - float it = float(i); - uva *= m2; - uva.y += -1.0 + (0.6 / it) * cos(t + it * uva.x + 0.5 * it) * float(mod(it, 0.5) == 0.0); - uva.x += 1.0 + (0.5 / it) * cos(t + it * uva.y * 0.1 / 5.0 + 0.5 * (it + 15.0)); // Adjust the scaling factor for y-coordinate - } - - float n = 0.5; - float r = n + n * sin(4.0 * uva.x + t); - float gb = n + n * sin(3.0 * uva.y); - return vec3(r, gb * 0.8 * r, gb * r); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - -vec2 uv = vec2(pos) / vec2(1000, 2000); - uv = 2.0 * uv - 1.0; - uv *= (10.3 + 0.1 * sin(current_time * 0.01)); - - // Extract x and y coordinates - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - - // uv.y -= current_time * 0.013; -//uv.x -= current_time * 0.026; - vec3 col = effect(0.001, uv, current_time, 0.5); - // col += effect(0.5, uv * 3.0, 2.0 * current_time + 10.0, 0.5) * 0.3; - // col += effect(0.5, sin(current_time * 0.01) * uv * 2.0, 2.0 * current_time + 10.0, 0.5) * 0.1; - - // Output the final color to the output texture - imageStore(out_tex, pos, vec4(col, 1.0)); -} -)"; - -// ported from https://github.com/keijiro/ShaderSketches/blob/master/Fragment/Eyes2.glsl -static const char *render_source_pattern = - R"( -#version 310 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float time; - -float rand(vec2 uv) -{ - return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); -} - -vec3 hue2rgb(float h) -{ - h = fract(h) * 6.0 - 2.0; - return clamp(vec3(abs(h - 1.0) - 1.0, 2.0 - abs(h), 2.0 - abs(h - 2.0)), 0.0, 1.0); -} - -vec3 eyes(vec2 coord, vec2 resolution) -{ - const float pi = 3.141592; - float t = 0.4 * time * 0.05; - float aspectRatio = resolution.x / resolution.y; - float div = 20.0; - float sc = 30.0; - - vec2 p = (coord - resolution / 2.0) / sc - 0.5; - - // center offset - float dir = floor(rand(floor(p) + floor(t) * 0.11) * 4.0) * pi / 2.0; - vec2 offs = vec2(sin(dir), cos(dir)) * 0.6; - offs *= smoothstep(0.0, 0.1, fract(t)); - offs *= smoothstep(0.4, 0.5, 1.0 - fract(t)); - - // circles - float l = length(fract(p) + offs - 0.5); - float rep = sin((rand(floor(p)) * 2.0 + 2.0) * t) * 4.0 + 5.0; - float c = (abs(0.5 - fract(l * rep + 0.5)) - 0.25) * sc / rep; - - // grid lines - vec2 gr = (abs(0.5 - fract(p + 0.5)) - 0.05) * sc; - c = clamp(min(min(c, gr.x), gr.y), 0.0, 1.0); - - return hue2rgb(rand(floor(p) * 0.3231)) * c; -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - vec2 resolution = vec2(float(width), float(height)); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - vec3 color = eyes(vec2(pos), resolution); - - // Output the final color - imageStore(out_tex, pos, vec4(color, 1.0)); -} - - -)"; - -// original (by phodius) -static const char *render_source_hex = - R"( -#version 310 es -precision highp float; -precision highp int; - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; -layout(binding = 0, rgba32f) writeonly uniform highp image2D OutputImage; - - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float iTime; -vec2 iResolution; - -float rand(vec2 co) { - return fract(sin(dot(co.xy, vec2(12.9898, 4.1414))) * 43758.5453); -} - -// Hexagon function -vec4 hexagon(vec2 p) -{ - vec2 q = vec2(p.x * 2.0 * 0.5773503, p.y + p.x * 0.5773503); - - vec2 pi = floor(q); - vec2 pf = fract(q); - - float v = mod(pi.x * 9.0, 0.0); - - float ca = step(1.0, v); - float cb = step(2.0, v); - vec2 ma = step(pf.xy, pf.yx); - - float e = 0.0; - float f = length((fract(p) - 10.5) * vec2(1.0, 0.85)); - - return vec4(pi + ca - cb * ma, e, f); -} -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - vec2 uv = (vec2(pos) + 0.5) / float(width); - - // Generate a random value - float randVal = rand(uv); - - // Apply hexagon logic - vec2 p = (-float(width) + 2.0 * vec2(pos)) / float(height); - vec4 h = hexagon(40.0 * p + vec2(0.5 * iTime * 0.125)); - - float col = 0.01 + 0.15 * rand(vec2(h.xy)) * 1.0; - col *= 4.3 + 0.15 * sin(10.0 * h.z); - - // Use hardcoded colors for shades with gradient - vec3 shadeColor1 = vec3(0.1, 0.1, 0.1) + 1.1 * col * h.z; // Dark gray with gradient - vec3 shadeColor2 = vec3(0.4, 0.4, 0.4) + 1.1 * col; // Gray with gradient - vec3 shadeColor3 = vec3(0.9, 0.9, 0.9) + 0.1 * col; // Light gray with gradient - - // Use different hardcoded colors based on the random value - vec3 finalColor = mix(shadeColor1, mix(shadeColor2, shadeColor3, randVal), col); - - // Use imageStore instead of writing to buffer - imageStore(OutputImage, pos, vec4(finalColor, 1.0)); -} -)"; - -// ported from https://github.com/keijiro/ShaderSketches/blob/master/Fragment/Zebra.glsl -static const char *render_source_zebra = - R"( -#version 310 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float time; -const float resolutionY = 720.0; // Set to constant resolution of 720p -const float pi = 3.14159265359; -const float timeFactor = 0.05; // Adjust this factor to control the speed of the animation - -float rand(vec2 uv) -{ - return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - float size = resolutionY / 10.0; // cell size in pixel - - vec2 p1 = vec2(pos) / size; // normalized pos - vec2 p2 = fract(p1) - 0.5; // relative pos from cell center - - // random number - float rnd = dot(floor(p1), vec2(12.9898, 78.233)); - rnd = fract(sin(rnd) * 43758.5453); - - // rotation matrix - float phi = rnd * pi * 2.0 + time * 0.4 * timeFactor; - mat2 rot = mat2(cos(phi), -sin(phi), sin(phi), cos(phi)); - - vec2 p3 = rot * p2; // apply rotation - p3.y += sin(p3.x * 5.0 + time * 2.0 * timeFactor) * 0.12; // wave - - float rep = fract(rnd * 13.285) * 8.0 + 2.0; // line repetition - float gr = fract(p3.y * rep + time * 0.8 * timeFactor); // repeating gradient - - // make antialiased line by saturating the gradient - float c = clamp((0.25 - abs(0.5 - gr)) * size * 0.75 / rep, 0.0, 1.0); - c *= max(0.0, 1.0 - length(p2) * 0.6); // darken corners - - vec2 bd = (0.5 - abs(p2)) * size - 2.0; // border lines - c *= clamp(min(bd.x, bd.y), 0.0, 1.0); - - // Output the final color - imageStore(out_tex, pos, vec4(c, c, c, 1.0)); -} - - -)"; - -// ported from https://www.shadertoy.com/view/dlGfWV -static const char *render_source_neural_network = - R"( - -#version 310 es -precision highp float; -precision highp image2D; - -//layout(binding = 0, rgba32f) readonly uniform highp image2D neural_network_tex; // Use binding point 0 -layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; // Use binding point 1 - -//layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float time; - -uniform vec2 iResolution; -uniform float iTime; - -mat2 rotate2D(float r) { - float c = cos(r); - float s = sin(r); - return mat2(c, -s, s, c); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - // Normalized pixel coordinates (from 0 to 1) - vec2 uv = (vec2(pos) - 0.5 * float(gl_NumWorkGroups.x)) / float(gl_WorkGroupSize.x); - - // Scale the uv coordinates by a factor of 8 - uv *= 0.05; - - vec3 col = vec3(0); - float t = 0.05 * time; - - vec2 n = vec2(0), q; - vec2 N = vec2(0); - vec2 p = uv + sin(t * 0.1) / 10.0; - float S = 10.0; - mat2 m = rotate2D(1.0); - - for (float j = 0.0; j < 30.0; j++) { - p *= m; - n *= m; - q = p * S + j + n + t; - n += sin(q); - N += cos(q) / S; - S *= 1.2; - } - - col = vec3(1, 2, 4) * pow((N.x + N.y + 0.2) + 0.005 / length(N), 2.1); - - imageStore(out_tex, pos, vec4(col, 1.0)); -} -)"; - -// Ported from https://www.shadertoy.com/view/llSyDh -static const char *render_source_hexagon_maze = - R"( -#version 320 es - -precision highp float; -precision highp int; -precision highp image2D; - -//layout (location = 0) out vec4 fragColor; -layout (binding = 0, rgba32f) writeonly uniform image2D fragColor; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float iTime; -uniform vec2 iResolution; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - - -// Interlaced variation - Interesting, but patched together in a hurry. -//#define INTERLACING - -// A quick hack to get rid of the winding overlay - in order to show the maze only. -//#define MAZE_ONLY - - - -// Helper vector. If you're doing anything that involves regular triangles or hexagons, the -// 30-60-90 triangle will be involved in some way, which has sides of 1, sqrt(3) and 2. -const vec2 s = vec2(1, 1.7320508); - -// Standard vec2 to float hash - Based on IQ's original. -float hash21(vec2 p){ return fract(sin(dot(p, vec2(141.173, 289.927)))*43758.5453); } - - -// Standard 2D rotation formula. -mat2 r2(in float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); } - - -// The 2D hexagonal isosuface function: If you were to render a horizontal line and one that -// slopes at 60 degrees, mirror, then combine them, you'd arrive at the following. -float hex(in vec2 p){ - - p = abs(p); - - // Below is equivalent to: - //return max(p.x*.5 + p.y*.866025, p.x); - - return max(dot(p, s*.5), p.x); // Hexagon. - -} - -// This function returns the hexagonal grid coordinate for the grid cell, and the corresponding -// hexagon cell ID - in the form of the central hexagonal point. That's basically all you need to -// produce a hexagonal grid. -// -// When working with 2D, I guess it's not that important to streamline this particular function. -// However, if you need to raymarch a hexagonal grid, the number of operations tend to matter. -// This one has minimal setup, one "floor" call, a couple of "dot" calls, a ternary operator, etc. -// To use it to raymarch, you'd have to double up on everything - in order to deal with -// overlapping fields from neighboring cells, so the fewer operations the better. -vec4 getHex(vec2 p){ - - // The hexagon centers: Two sets of repeat hexagons are required to fill in the space, and - // the two sets are stored in a "vec4" in order to group some calculations together. The hexagon - // center we'll eventually use will depend upon which is closest to the current point. Since - // the central hexagon point is unique, it doubles as the unique hexagon ID. - vec4 hC = floor(vec4(p, p - vec2(.5, 1))/s.xyxy) + .5; - - // Centering the coordinates with the hexagon centers above. - vec4 h = vec4(p - hC.xy*s, p - (hC.zw + .5)*s); - - // Nearest hexagon center (with respect to p) to the current point. In other words, when - // "h.xy" is zero, we're at the center. We're also returning the corresponding hexagon ID - - // in the form of the hexagonal central point. Note that a random constant has been added to - // "hC.zw" to further distinguish it from "hC.xy." - // - // On a side note, I sometimes compare hex distances, but I noticed that Iomateron compared - // the Euclidian version, which seems neater, so I've adopted that. - return dot(h.xy, h.xy)= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - vec2 fragCoord = vec2(id); - float res = clamp(iResolution.y, 300.0, 600.0); - vec2 u = (fragCoord - iResolution.xy*.5)/res; - vec2 sc = u*4. + s.yx*(iTime*0.05)/12.; - vec4 h = getHex(sc); - vec4 h2 = getHex(sc - 1.0 / s); - vec4 h3 = getHex(sc + 1.0 / s); - vec2 p = h.xy; - float eDist = hex(p); - float cDist = dot(p, p); - float rnd = hash21(h.zw); - //float aRnd = sin(rnd*6.283 + (iTime*0.05)*1.5)*.5 + .5; // Animating the random number. - - #ifdef INTERLACING - // Random vec3 - used for some overlapping. - //vec3 lRnd = vec3(rnd*14.4 + .81, fract(rnd*21.3 + .97), fract(rnd*7.2 + .63)); - vec3 lRnd = vec3(hash21(h.zw + .23), hash21(h.zw + .96), hash21(h.zw + .47)); - #endif - - // It's possible to control the randomness to form some kind of repeat pattern. - //rnd = mod(h.z + h.w, 2.); - - - // Redundant here, but I might need it later. - float dir = 1.; - - - - // Storage vector. - vec2 q; - - - // If the grid cell's random ID is above a threshold, flip the Y-coordinates. - if(rnd>.5) p.y = -p.y; - - - - // Determining the closest of the three arcs to the current point, the keeping a copy - // of the vector used to produce it. That way, you'll know just to render that particular - // decorated arc, lines, etc - instead of all three. - const float r = 1.; - const float th = .2; // Arc thickness. - - // Arc one. - q = p - vec2(0, r)/s; - vec3 da = vec3(q, dfPol(q)); - - // Arc two. "r2" could be hardcoded, but this is a relatively cheap 2D example. - q = r2(3.14159*2./3.)*p - vec2(0, r)/s; - vec3 db = vec3(q, dfPol(q)); - - // Arc three. - q = r2(3.14159*4./3.)*p - vec2(0, r)/s; - vec3 dc = vec3(q, dfPol(q)); - - // Compare distance fields, and return the vector used to produce the closest one. - vec3 q3 = da.z.5 && lRnd.x<.5) hLines2 *= smoothstep(0., .02, ln); - if(lRnd.x>.5) hLines2 *= dMask; - #else - if(rnd>.5) hLines2 *= smoothstep(0., .02, ln); - hLines2 *= dMask; - #endif - bg = mix(bg, vec3(0), hLines2*tr); - - float eDist3 = hex(h3.xy); - float hLines3 = smoothstep(0., .02, eDist3 - .5 + .02); - #ifdef INTERLACING - if(rnd<=.5 && lRnd.x>.5) hLines3 *= smoothstep(0., .02, ln); - if(lRnd.x>.5) hLines3 *= dMask; - #else - if(rnd<=.5) hLines3 *= smoothstep(0., .02, ln); - hLines3 *= dMask; - #endif - bg = mix(bg, vec3(0), hLines3*tr); - - - // Using the two off-centered hex coordinates to give the background a bit of highlighting. - float shade = max(1.25 - dot(h2.xy, h2.xy)*2., 0.); - shade = min(shade, max(dot(h3.xy, h3.xy)*3. + .25, 0.)); - bg = mix(bg, vec3(0), (1.-shade)*.5); - - // I wanted to change the colors of everything at the last minute. It's pretty hacky, so - // when I'm feeling less lazy, I'll tidy it up. :) - vec3 dotCol = bg.zyx*vec3(1.5, .4, .4); - vec3 bCol = mix(bg.zyx, bg.yyy, .25); - bg = mix(bg.yyy, bg.zyx, .25); - - - - // Under the random threshold, and we draw the lines under the Truchet pattern. - #ifdef INTERLACING - if(lRnd.x>.5){ - bg = mix(bg, vec3(0), (1. - smoothstep(0., .015, lnBord))); - bg = mix(bg, bCol, (1. - smoothstep(0., .015, ln))); - // Center lines. - bg = mix(bg, vec3(0), smoothstep(0., .02, eDist3 - .5 + .02)*tr); - } - #else - bg = mix(bg, vec3(0), (1. - smoothstep(0., .015, lnBord))); - bg = mix(bg, bCol, (1. - smoothstep(0., .015, ln))); - #endif - - - - // Apply the Truchet shadow to the background. - bg = mix(bg, vec3(0), (1. - smoothstep(0., .07, d))*.5); - - - // Place the Truchet field to the background, with some additional shading to give it a - // slightly rounded, raised feel. - //vec3 col = mix(bg, vec3(1)*max(-d*3. + .7, 0.), (1. - dMask)*.65); - // Huttarl suggest slightly more shading on the snake-like pattern edges, so I added just a touch. - vec3 col = mix(bg, vec3(1)*max(-d*9. + .4, 0.), (1. - dMask)*.65); - - - - - // Apply the moving dot pattern to the Truchet. - //dotCol = mix(dotCol, dotCol.xzy, dot(sin(u*3.14159*2. - cos(u.yx*3.14159*2.)*3.14159), vec2(.25)) + .5); - col = mix(col, vec3(0), (1. - dMask)*(1. - smoothstep(0., .02, d2))); - col = mix(col, dotCol, (1. - dMask)*(1. - smoothstep(0., .02, d2 + .125))); - - // Truchet border. - col = mix(col, vec3(0), 1. - smoothstep(0., .015, dBord)); - - #ifdef INTERLACING - // Over the random threshold, and we draw the lines over the Truchet. - if(lRnd.x<=.5){ - col = mix(col, vec3(0), (1. - smoothstep(0., .015, lnBord))); - col = mix(col, bCol, (1. - smoothstep(0., .015, ln))); - // Center lines. - col = mix(col, vec3(0), smoothstep(0., .02, eDist2 - .5 + .02)*tr); - } - #endif - - - - - // Subtle vignette. - u = fragCoord/iResolution.xy; - col *= pow(16.*u.x*u.y*(1. - u.x)*(1. - u.y) , .125) + .25; - // Colored variation. - //col = mix(pow(min(vec3(1.5, 1, 1)*col, 1.), vec3(1, 3, 16)), col, - //pow(16.*u.x*u.y*(1. - u.x)*(1. - u.y) , .25)*.75 + .25); - - - - - - - - // Using the edge distance to produce some repeat contour lines. Standard stuff. - //if (rnd>.5) h.xy = -h.yx; - //float cont = clamp(cos(hex(h.xy)*6.283*12.)*1.5 + 1.25, 0., 1.); - //col = mix(col, vec3(0), (1. - smoothstep(0., .015, ln))*(smoothstep(0., .015, d))*(1.-cont)*.5); - - - - // Very basic hatch line effect. - float gr = dot(col, vec3(.299, .587, .114)); - float hatch = (gr<.45)? clamp(sin((sc.x - sc.y)*3.14159*40.)*2. + 1.5, 0., 1.) : 1.; - float hatch2 = (gr<.25)? clamp(sin((sc.x + sc.y)*3.14159*40.)*2. + 1.5, 0., 1.) : 1.; - - col *= min(hatch, hatch2)*.5 + .5; - col *= clamp(sin((sc.x - sc.y)*3.14159*80.)*1.5 + .75, 0., 1.)*.25 + 1.; - - - - vec2 u2 = fragCoord / iResolution.xy; - col *= pow(16.0 * u2.x * u2.y * (1.0 - u2.x) * (1.0 - u2.y), 0.125) + 0.25; - - imageStore(fragColor, id, vec4(sqrt(max(col, 0.0)), 1.0)); -} - - - -)"; - -// ported from https://www.shadertoy.com/view/4td3zj -static const char *render_source_raymarched_truchet = - R"( -#version 310 es - -precision highp float; -precision highp int; -precision highp image2D; - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; -layout(binding = 0, rgba8) writeonly uniform image2D imageOut; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float iTime; -uniform vec2 iResolution; - -float heightMap(in vec2 p) { - - p *= 5.; - - // Hexagonal coordinates. - vec2 h = vec2(p.x + p.y*.57735, p.y*1.1547); - - // Closest hexagon center. - vec2 f = fract(h); h -= f; - float c = fract((h.x + h.y)/3.); - h = c<.666 ? c<.333 ? h : h + 1. : h + step(f.yx, f); - - p -= vec2(h.x - h.y*.5, h.y*.8660254); - - // Rotate (flip, in this case) random hexagons. Otherwise, you'd have a bunch of circles only. - // Note that "h" is unique to each hexagon, so we can use it as the random ID. - c = fract(cos(dot(h, vec2(41, 289)))*43758.5453); // Reusing "c." - p -= p*step(c, .5)*2.; // Equivalent to: if (c<.5) p *= -1.; - - // Minimum squared distance to neighbors. Taking the square root after comparing, for speed. - // Three partitions need to be checked due to the flipping process. - p -= vec2(-1, 0); - c = dot(p, p); // Reusing "c" again. - p -= vec2(1.5, .8660254); - c = min(c, dot(p, p)); - p -= vec2(0, -1.73205); - c = min(c, dot(p, p)); - - return sqrt(c); - - // Wrapping the values - or folding the values over (abs(c-.5)*2., cos(c*6.283*1.), etc) - to produce - // the nicely lined-up, wavy patterns. I"m perfoming this step in the "map" function. It has to do - // with coloring and so forth. - //c = sqrt(c); - //c = cos(c*6.283*1.) + cos(c*6.283*2.); - //return (clamp(c*.6+.5, 0., 1.)); - -} - -// Raymarching an XY-plane - raised a little by the hexagonal Truchet heightmap. Pretty standard. -float map(vec3 p){ - - - float c = heightMap(p.xy); // Height map. - // Wrapping, or folding the height map values over, to produce the nicely lined-up, wavy patterns. - c = cos(c*6.283*1.) + cos(c*6.283*2.); - c = (clamp(c*.6+.5, 0., 1.)); - - - // Back plane, placed at vec3(0., 0., 1.), with plane normal vec3(0., 0., -1). - // Adding some height to the plane from the heightmap. Not much else to it. - return 1. - p.z - c*.025; - - -} - -// The normal function with some edge detection and curvature rolled into it. Sometimes, it's possible to -// get away with six taps, but we need a bit of epsilon value variance here, so there's an extra six. -vec3 getNormal(vec3 p, inout float edge, inout float crv) { - - vec2 e = vec2(.01, 0); // Larger epsilon for greater sample spread, thus thicker edges. - - // Take some distance function measurements from either side of the hit point on all three axes. - float d1 = map(p + e.xyy), d2 = map(p - e.xyy); - float d3 = map(p + e.yxy), d4 = map(p - e.yxy); - float d5 = map(p + e.yyx), d6 = map(p - e.yyx); - float d = map(p)*2.; // The hit point itself - Doubled to cut down on calculations. See below. - - // Edges - Take a geometry measurement from either side of the hit point. Average them, then see how - // much the value differs from the hit point itself. Do this for X, Y and Z directions. Here, the sum - // is used for the overall difference, but there are other ways. Note that it's mainly sharp surface - // curves that register a discernible difference. - edge = abs(d1 + d2 - d) + abs(d3 + d4 - d) + abs(d5 + d6 - d); - //edge = max(max(abs(d1 + d2 - d), abs(d3 + d4 - d)), abs(d5 + d6 - d)); // Etc. - - // Once you have an edge value, it needs to normalized, and smoothed if possible. How you - // do that is up to you. This is what I came up with for now, but I might tweak it later. - edge = smoothstep(0., 1., sqrt(edge/e.x*2.)); - - // We may as well use the six measurements to obtain a rough curvature value while we're at it. - crv = clamp((d1 + d2 + d3 + d4 + d5 + d6 - d*3.)*32. + .6, 0., 1.); - - // Redoing the calculations for the normal with a more precise epsilon value. - e = vec2(.0025, 0); - d1 = map(p + e.xyy), d2 = map(p - e.xyy); - d3 = map(p + e.yxy), d4 = map(p - e.yxy); - d5 = map(p + e.yyx), d6 = map(p - e.yyx); - - - // Return the normal. - // Standard, normalized gradient mearsurement. - return normalize(vec3(d1 - d2, d3 - d4, d5 - d6)); -} - - - -// I keep a collection of occlusion routines... OK, that sounded really nerdy. :) -// Anyway, I like this one. I'm assuming it's based on IQ's original. -float calculateAO(in vec3 p, in vec3 n) -{ - float sca = 2., occ = 0.; - for(float i=0.; i<5.; i++){ - - float hr = .01 + i*.5/4.; - float dd = map(n * hr + p); - occ += (hr - dd)*sca; - sca *= 0.7; - } - return clamp(1.0 - occ, 0., 1.); -} - - -/* -// Surface bump function. Cheap, but with decent visual impact. -float bumpSurf3D( in vec3 p){ - - float c = heightMap((p.xy + p.z*.025)*6.); - c = cos(c*6.283*3.); - //c = sqrt(clamp(c+.5, 0., 1.)); - c = (c*.5 + .5); - - return c; - -} - -// Standard function-based bump mapping function. -vec3 dbF(in vec3 p, in vec3 nor, float bumpfactor){ - - const vec2 e = vec2(0.001, 0); - float ref = bumpSurf3D(p); - vec3 grad = (vec3(bumpSurf3D(p - e.xyy), - bumpSurf3D(p - e.yxy), - bumpSurf3D(p - e.yyx) )-ref)/e.x; - - grad -= nor*dot(nor, grad); - - return normalize( nor + grad*bumpfactor ); - -} -*/ - -// Compact, self-contained version of IQ's 3D value noise function. -float n3D(vec3 p){ - - const vec3 s = vec3(7, 157, 113); - vec3 ip = floor(p); p -= ip; - vec4 h = vec4(0., s.yz, s.y + s.z) + dot(ip, s); - p = p*p*(3. - 2.*p); //p *= p*p*(p*(p * 6. - 15.) + 10.); - h = mix(fract(sin(h)*43758.5453), fract(sin(h + s.x)*43758.5453), p.x); - h.xy = mix(h.xz, h.yw, p.y); - return mix(h.x, h.y, p.z); // Range: [0, 1]. -} - -// Simple environment mapping. Pass the reflected vector in and create some -// colored noise with it. The normal is redundant here, but it can be used -// to pass into a 3D texture mapping function to produce some interesting -// environmental reflections. -vec3 envMap(vec3 rd, vec3 sn){ - - vec3 sRd = rd; // Save rd, just for some mixing at the end. - - // Add a time component, scale, then pass into the noise function. - rd.xy -= iTime*.25 *0.0125; - rd *= 3.; - - float c = n3D(rd)*.57 + n3D(rd*2.)*.28 + n3D(rd*4.)*.15; // Noise value. - c = smoothstep(0.4, 1., c); // Darken and add contast for more of a spotlight look. - - vec3 col = vec3(c, c*c, c*c*c*c); // Simple, warm coloring. - //vec3 col = vec3(min(c*1.5, 1.), pow(c, 2.5), pow(c, 12.)); // More color. - - // Mix in some more red to tone it down and return. - return mix(col, col.yzx, sRd*.25+.25); - -} - - - -// vec2 to vec2 hash. -vec2 hash22(vec2 p) { - - // Faster, but doesn't disperse things quite as nicely as other combinations. :) - float n = sin(dot(p, vec2(41, 289))); - return fract(vec2(262144, 32768)*n)*.75 + .25; - - // Animated. - //p = fract(vec2(262144, 32768)*n); - //return sin( p*6.2831853 + iTime *0.0125)*.35 + .65; - -} - -// 2D 2nd-order Voronoi: Obviously, this is just a rehash of IQ's original. I've tidied -// up those if-statements. Since there's less writing, it should go faster. That's how -// it works, right? :) -// -float Voronoi(in vec2 p){ - - vec2 g = floor(p), o; p -= g; - - vec3 d = vec3(1); // 1.4, etc. "d.z" holds the distance comparison value. - - for(int y = -1; y <= 1; y++){ - for(int x = -1; x <= 1; x++){ - - o = vec2(x, y); - o += hash22(g + o) - p; - - d.z = dot(o, o); - // More distance metrics. - //o = abs(o); - //d.z = max(o.x*.8666 + o.y*.5, o.y);// - //d.z = max(o.x, o.y); - //d.z = (o.x*.7 + o.y*.7); - - d.y = max(d.x, min(d.y, d.z)); - d.x = min(d.x, d.z); - - } - } - - return max(d.y/1.2 - d.x*1., 0.)/1.2; - //return d.y - d.x; // return 1.-d.x; // etc. - -} - - - -void main() { - - vec2 iResolution = vec2(width, height); - ivec2 id = ivec2(gl_GlobalInvocationID.xy); - float tm = (iTime / 2.) * 0.0125; - - - - // Unit directional ray - Coyote's observation. - vec3 rd = normalize(vec3(2. * vec2(id) - iResolution.xy, iResolution.y)); - - - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - // Rotate the XY-plane back and forth. Note that sine and cosine are kind of rolled into one. - vec2 a = sin(vec2(1.570796, 0) + sin(tm / 4.) * .3); - - // Fabrice's observation. - rd.xy = mat2(a, -a.y, a.x) * rd.xy; - - // Ray origin. Moving in the X-direction to the right. - // vec3 ro = vec3(tm, cos(tm / 4.), 0.); -vec3 ro = vec3(0.0,0.0, 0.); - // Light position, hovering around behind the camera. - vec3 lp = ro + vec3(cos(tm / 2.) * .5, sin(tm / 2.) * .5, -.5); - - // Standard raymarching segment. Because of the straightforward setup, not many iterations are necessary. - float d, t = 0.; - for (int j = 0; j < 32; j++) { - d = map(ro + rd * t); // distance to the function. - t += d * .7; // Total distance from the camera to the surface. - - // The plane "is" the far plane, so no far=plane break is needed. - if (d < 0.001) - break; - } - - // Edge and curve value. Passed into, and set, during the normal calculation. - float edge, crv; - - // Surface position, surface normal and light direction. - vec3 sp = ro + rd * t; - vec3 sn = getNormal(sp, edge, crv); - vec3 ld = lp - sp; - - - // Coloring and texturing the surface. - // - // Height map. - float c = heightMap(sp.xy); - - // Folding, or wrapping, the values above to produce the snake-like pattern that lines up with the randomly - // flipped hex cells produced by the height map. - vec3 fold = cos(vec3(1, 2, 4)*c*6.283); - - // Using the height map value, then wrapping it, to produce a finer grain Truchet pattern for the overlay. - float c2 = heightMap((sp.xy + sp.z*.025)*6.); - c2 = cos(c2*6.283*3.); - c2 = (clamp(c2+.5, 0., 1.)); - - - // Function based bump mapping. I prefer none in this example, but it's there if you want it. - //if(temp.x>0. || temp.y>0.) sn = dbF(sp, sn, .001); - - // Surface color value. - vec3 oC = vec3(1); - - if(fold.x>0.) oC = vec3(1, .05, .1)*c2; // Reddish pink with finer grained Truchet overlay. - - if(fold.x<0.05 && (fold.y)<0.) oC = vec3(1, .7, .45)*(c2*.25 + .75); // Lighter lined borders. - else if(fold.x<0.) oC = vec3(1, .8, .4)*c2; // Gold, with overlay. - - //oC *= n3D(sp*128.)*.35 + .65; // Extra fine grained noisy texturing. - - - // Sending some greenish particle pulses through the snake-like patterns. With all the shininess going - // on, this effect is a little on the subtle side. - float p1 = 1.0 - smoothstep(0., .1, fold.x*.5+.5); // Restrict to the snake-like path. - // Other path. - //float p2 = 1.0 - smoothstep(0., .1, cos(heightMap(sp.xy + 1. + (iTime*0.0125)/4.)*6.283)*.5+.5); - float p2 = 1.0 - smoothstep(0., .1, Voronoi(sp.xy*4. + vec2(tm, cos(tm/4.)))); - p1 = (p2 + .25)*p1; // Overlap the paths. - oC += oC.yxz*p1*p1; // Gives a kind of electron effect. Works better with just Voronoi, but it'll do. - - - - - float lDist = max(length(ld), 0.001); // Light distance. - float atten = 1./(1. + lDist*.125); // Light attenuation. - - ld /= lDist; // Normalizing the light direction vector. - - - float diff = max(dot(ld, sn), 0.); // Diffuse. - float spec = pow(max( dot( reflect(-ld, sn), -rd ), 0.0 ), 16.); // Specular. - float fre = pow(clamp(dot(sn, rd) + 1., .0, 1.), 3.); // Fresnel, for some mild glow. - - // Shading. Note, there are no actual shadows. The camera is front on, so the following - // two functions are enough to give a shadowy appearance. - crv = crv*.9 + .1; // Curvature value, to darken the crevices. - float ao = calculateAO(sp, sn); // Ambient occlusion, for self shadowing. - - - - // Combining the terms above to light the texel. - vec3 col = oC*(diff + .5) + vec3(1., .7, .4)*spec*2. + vec3(.4, .7, 1)*fre; - - - col += (oC*.5+.5)*envMap(reflect(rd, sn), sn)*6.; // Fake environment mapping. - - - // Edges. - col *= 1. - edge*.85; // Darker edges. - - // Applying the shades. - col *= (atten*crv*ao); - -col *= 1.3; - // Rough gamma correction, then write to the output buffer. - vec3 finalColor = sqrt(clamp(col, 0., 1.)); - ivec2 fragCoord = ivec2(id); // Convert to ivec2 - imageStore(imageOut, fragCoord, vec4(finalColor, 1.0)); // Use vec4 instead of uvec4 - -} -)"; - -// ported from https://www.shadertoy.com/view/mtyGWy -static const char *render_source_neon_pattern = - R"( - - #version 310 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) uniform readonly image2D in_tex; -layout(binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -//uniform float current_time; // Assuming this is the global time variable -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float current_time; - -vec3 palette(float t) { - vec3 a = vec3(0.5, 0.5, 0.5); - vec3 b = vec3(0.5, 0.5, 0.5); - vec3 c = vec3(1.0, 1.0, 1.0); - vec3 d = vec3(0.263, 0.416, 0.557); - return a + b * cos(6.28318 * (c * t + d)); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - // Extract x and y coordinates - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - vec2 uv = vec2(pos) / vec2(width, height); - vec2 uv0 = uv; - vec3 finalColor = vec3(0.0); - - for (float i = 0.0; i < 4.0; i++) { - uv = fract(uv * 1.5) - 0.5; - - float d = length(uv) * exp(-length(uv0)); - - vec3 col = palette(length(uv0) + i * 0.4 + current_time * 0.000001); - - d = sin(d * 8.0 + current_time * 0.02) / 8.0; - d = abs(d); - - d = pow(0.01 / d, 1.2); - - finalColor += col * d; - } - - // Output the final color to the output texture - imageStore(out_tex, pos, vec4(finalColor, 1.0)); -} -)"; - -// original (by phodius) -static const char *render_source_neon_rings = - R"( -#version 310 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) uniform readonly image2D in_tex; -layout(binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float current_time; // Animated time - -#define PI 3.14159265358979323846 -#define TWO_PI 6.28318530717958647692 - -void main() { - - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - // Number of circles - int numCircles = 5; - - // Initialize final color - vec3 finalColor = vec3(0.0); - - for (int i = 0; i < numCircles; ++i) { - // Calculate UV coordinates for each circle - vec2 uv = vec2(pos) / vec2(width / 3, height / 3); - - // Calculate polar coordinates - float a = atan(uv.y, uv.x); - float r = length(uv) * (0.2 + 0.1 * float(i)); - - // Map polar coordinates to UV - uv = vec2(a / TWO_PI, r); - - // Apply horizontal movement based on time for each circle - float xOffset = sin(current_time * 0.02 + float(i)) * 0.2; - uv.x += xOffset; - - // Time-dependent color - float xCol = (uv.x - (current_time / 300000.0)) * 3.0; - xCol = mod(xCol, 3.0); - vec3 horColour = vec3(0.25, 0.25, 0.25); - - if (xCol < 1.0) { - horColour.r += 1.0 - xCol; - horColour.g += xCol; - } else if (xCol < 2.0) { - xCol -= 1.0; - horColour.g += 1.0 - xCol; - horColour.b += xCol; - } else { - xCol -= 2.0; - horColour.b += 1.0 - xCol; - horColour.r += xCol; - } - - // Draw color beam - uv = (2.0 * uv) - 1.0; - float beamWidth = (0.7 + 0.5 * cos(uv.x * 1.0 * TWO_PI * 0.15 * clamp(floor(5.0 + 1.0 * cos(current_time)), 0.0, 1.0))) * abs(1.0 / (30.0 * uv.y)); - vec3 horBeam = vec3(beamWidth); - - // Add the color for the current circle to the final color - finalColor += ((horBeam) * horColour); - } - - // Output the final color to the output texture - imageStore(out_tex, pos, vec4(finalColor, 1.0)); -} - - -)"; - -// ported from https://www.shadertoy.com/view/WdjGRc -static const char *render_source_deco = - R"( -#version 320 es -precision highp float; -precision highp image2D; - -layout(binding = 0, rgba32f) uniform readonly image2D in_tex; -layout(binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; -layout(location = 9) uniform float current_time; - -vec3 effect(float speed, vec2 uv, float time, float scale) { - float t = mod(time * 0.005, 6.0); - float rt = 0.00000000000001 * sin(t * 0.45); - - mat2 m1 = mat2(cos(rt), -sin(rt), -sin(rt), cos(rt)); - vec2 uva = uv * m1 * scale; - float irt = 0.005 * cos(t * 0.05); - mat2 m2 = mat2(sin(irt), cos(irt), -cos(irt), sin(irt)); - - for (int i = 1; i < 400; i += 1) { - float it = float(i); - uva *= m2; - uva.y += -1.0 + (0.6 / it) * cos(t + it * uva.x + 0.5 * it) * float(mod(it, 0.5) == 0.0); - uva.x += 1.0 + (0.5 / it) * cos(t + it * uva.y * 0.1 / 5.0 + 0.5 * (it + 15.0)); // Adjust the scaling factor for y-coordinate - } - - float n = 0.5; - float r = n + n * sin(4.0 * uva.x + t); - float gb = n + n * sin(3.0 * uva.y); - return vec3(r, gb * 0.8 * r, gb * r); -} - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - vec2 uv = vec2(pos) / vec2(width, height); - uv = 2.0 * uv - 1.0; - uv *= (10.3 + 0.1 * sin(current_time * 0.01)); - - int x = pos.x; - int y = pos.y; - - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - - - // uv.y -= current_time * 0.013; -//uv.x -= current_time * 0.026; - vec3 col = effect(0.001, uv, current_time, 0.5); - // col += effect(0.5, uv * 3.0, 2.0 * current_time + 10.0, 0.5) * 0.3; - // col += effect(0.5, sin(current_time * 0.01) * uv * 2.0, 2.0 * current_time + 10.0, 0.5) * 0.1; - - // Output the final color to the output texture - imageStore(out_tex, pos, vec4(col, 1.0)); -} -)"; - -static const char *rounded_corner_overlay = - R"( -#version 320 es - -layout(binding = 0, rgba32f) readonly uniform highp image2D in_tex; // Use binding point 0 -layout(binding = 0, rgba32f) writeonly uniform highp image2D out_tex; // Use binding point 0 - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int corner_radius; -layout(location = 8) uniform int shadow_radius; -layout(location = 9) uniform vec4 shadow_color; - -void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - - // Check if the pixel should be drawn - if (pos.x >= border_size && pos.x <= (width - 1) - border_size && pos.y >= title_height && pos.y <= (height - 1) - border_size) - { - return; - } - float d; - vec4 c = shadow_color; - vec4 m = vec4(0.0); - vec4 s; - float diffuse = 1.0 / float(shadow_radius == 0 ? 1 : shadow_radius); - // left - if (pos.x < shadow_radius * 2 && pos.y >= shadow_radius * 2 && pos.y <= height - shadow_radius * 2) - { - d = distance(vec2(float(shadow_radius * 2), float(pos.y)), vec2(pos)); - imageStore(out_tex, pos, mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0)))); - } - // top left corner - if (pos.x < shadow_radius * 2 + corner_radius && pos.y < shadow_radius * 2 + corner_radius) - { - d = distance(vec2(float(shadow_radius * 2 + corner_radius)), vec2(pos)) - float(corner_radius); - s = mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0))); - c = imageLoad(in_tex, pos); - d = distance(vec2(float(shadow_radius * 2 + corner_radius)), vec2(pos)); - imageStore(out_tex, pos, mix(c, s, clamp(d - float(corner_radius), 0.0, 1.0))); - } - // bottom left corner - if (pos.x < (shadow_radius * 2 + corner_radius) && pos.y > height - (shadow_radius * 2 + corner_radius)) - { - d = distance(vec2(float((shadow_radius * 2 + corner_radius)), float((height - 1) - (shadow_radius * 2 + corner_radius))), vec2(pos)) - float(corner_radius); - s = mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0))); - c = imageLoad(in_tex, pos); - d = distance(vec2(float((shadow_radius * 2 + corner_radius)), float((height - 1) - (shadow_radius * 2 + corner_radius))), vec2(pos)); - imageStore(out_tex, pos, mix(c, s, clamp(d - float(corner_radius), 0.0, 1.0))); - } - // top - if (pos.x >= shadow_radius * 2 + corner_radius && pos.x <= width - shadow_radius * 2 + corner_radius && pos.y < shadow_radius * 2) - { - d = distance(vec2(float(pos.x), float(shadow_radius * 2)), vec2(pos)); - imageStore(out_tex, pos, mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0)))); - } - // right - if (pos.x > (width - 1) - shadow_radius * 2 && pos.y >= shadow_radius * 2 && pos.y <= (height - 1) - shadow_radius * 2) - { - d = distance(vec2(float((width - 1) - shadow_radius * 2), float(pos.y)), vec2(pos)); - imageStore(out_tex, pos, mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0)))); - } - // top right corner - if (pos.x > width - (shadow_radius * 2 + corner_radius) && pos.y < (shadow_radius * 2 + corner_radius)) - { - d = distance(vec2(float((width - 1) - (shadow_radius * 2 + corner_radius)), float((shadow_radius * 2 + corner_radius))), vec2(pos)) - float(corner_radius); - s = mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0))); - c = imageLoad(in_tex, pos); - d = distance(vec2(float((width - 1) - (shadow_radius * 2 + corner_radius)), float((shadow_radius * 2 + corner_radius))), vec2(pos)); - imageStore(out_tex, pos, mix(c, s, clamp(d - float(corner_radius), 0.0, 1.0))); - } - // bottom right corner - if (pos.x > (width - 1) - (shadow_radius * 2 + corner_radius) && pos.y > (height - 1) - (shadow_radius * 2 + corner_radius)) - { - d = distance(vec2(float((width - 1) - (shadow_radius * 2 + corner_radius)), float((height - 1) - (shadow_radius * 2 + corner_radius))), vec2(pos)) - float(corner_radius); - s = mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0))); - c = imageLoad(in_tex, pos); - d = distance(vec2(float((width - 1) - (shadow_radius * 2 + corner_radius)), float((height - 1) - (shadow_radius * 2 + corner_radius))), vec2(pos)); - imageStore(out_tex, pos, mix(c, s, clamp(d - float(corner_radius), 0.0, 1.0))); - } - // bottom - if (pos.x >= (shadow_radius * 2 + corner_radius) && pos.x <= (width - 1) - (shadow_radius * 2 + corner_radius) && pos.y > (height - 1) - shadow_radius * 2) - { - d = distance(vec2(float(pos.x), float((height - 1) - shadow_radius * 2)), vec2(pos)); - imageStore(out_tex, pos, mix(c, m, 1.0 - exp(-pow(d * diffuse, 2.0)))); - } -} - -)"; - -static const char *beveled_glass_overlay = - R"( -#version 320 es - -layout(binding = 0, rgba32f) readonly uniform highp image2D neural_network_tex; // Use binding point 0 -layout(binding = 0, rgba32f) writeonly uniform highp image2D image; // Use binding point 0 - -layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -#define MARKER_RADIUS 12.5 -#define THICCNESS 2.0 - - -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int radius; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; - -bool isInsideTriangle(vec2 p, vec2 a, vec2 b, vec2 c) { - vec2 v0 = b - a; - vec2 v1 = c - a; - vec2 v2 = p - a; - - float dot00 = dot(v0, v0); - float dot01 = dot(v0, v1); - float dot02 = dot(v0, v2); - float dot11 = dot(v1, v1); - float dot12 = dot(v1, v2); - - float invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); - float u = (dot11 * dot02 - dot01 * dot12) * invDenom; - float v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - return (u >= 0.0) && (v >= 0.0) && (u + v <= 1.0); -} - - -vec4 toBezier(float delta, int i, vec4 P0, vec4 P1, vec4 P2, vec4 P3) -{ - float t = delta * float(i); - float t2 = t * t; - float one_minus_t = 1.0 - t; - float one_minus_t2 = one_minus_t * one_minus_t; - return (P0 * one_minus_t2 * one_minus_t + P1 * 3.0 * t * one_minus_t2 + P2 * 3.0 * t2 * one_minus_t + P3 * t2 * t); -} - -float sin01(float x) { - return (sin(x) + 1.0) / 2.0; -} - - - -vec4 drawCurveBenzier(vec2 p1, vec2 p2, int setCount) { - vec4 col = vec4(0.0); - ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); - float curveRadius = float(radius); -// Draw the lines connecting the points - - vec2 fragCoord = vec2(storePos); - for (int i = 0; i <= setCount; ++i) { - vec4 bezierPoint = toBezier(1.0 / float(setCount), i, vec4(p1, 0.0, 1.0), vec4(p1 + (p2 - p1) * 0.5, 0.0, 1.0), vec4(p1 + (p2 - p1) * 0.5, 0.0, 1.0), vec4(p2, 0.0, 1.0)); - vec2 curvePoint = bezierPoint.xy / bezierPoint.w; - float distance = length(fragCoord - curvePoint); - float curveIntensity = smoothstep(0.0, THICCNESS, curveRadius - distance); - col.rgb += vec3(0.1, 0.1, 0.1) * curveIntensity; - col.a = max(col.a, curveIntensity); - } - - return col; -} - - - - -vec4 drawCurve(vec2 p1, vec2 p2, int setCount) { - vec4 col = vec4(0.0); - ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); - float curveRadius = float(radius + 1); - vec2 fragCoord = vec2(storePos); - - float t = clamp(dot(fragCoord - p1, p2 - p1) / dot(p2 - p1, p2 - p1), 0.0, 1.0); - vec2 curvePoint = mix(p1, p2, t); - - float distance = length(fragCoord - curvePoint); - float curveIntensity = smoothstep(0.0, curveRadius, curveRadius - distance); - - // Calculate gradient along the line with grey to white to grey - vec3 gradientColor; - - if (t < 0.5) { - gradientColor = mix(vec3(0.7), vec3(1.0), t * 2.0); - } else { - gradientColor = mix(vec3(1.0), vec3(0.7), (t - 0.5) * 2.0); - } - - // Use the curveIntensity to interpolate between gradient colors - col.rgb = gradientColor * curveIntensity; - col.a = max(col.a, curveIntensity); - - return col; -} - -void main() { - ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); - - int x = storePos.x; - int y = storePos.y; - // Check if the pixel should be drawn - if (x >= border_size && x <= (width - 1) - border_size && y >= title_height && y <= (height - 1) - border_size) - { - return; - } - vec2 fragCoord = vec2(storePos); - - vec4 col = vec4(0.0); - float space = 15.0; - - vec2 p1 = vec2(0.0 + THICCNESS, float(height) - THICCNESS - space); - vec2 p2 = vec2(0.0 + THICCNESS, 0.0 + THICCNESS + space); - - vec2 x1 = vec2(float(width) - THICCNESS, float(height) - THICCNESS - space); - vec2 x2 = vec2(float(width) - THICCNESS, 0.0 + THICCNESS + space); - - vec2 y1 = vec2(0.0 + THICCNESS + space, float(height) - THICCNESS); - vec2 y2 = vec2(float(width) - THICCNESS - space, float(height) - THICCNESS); - - vec2 z1 = vec2(0.0 + THICCNESS + space, 0.0 + THICCNESS); - vec2 z2 = vec2(float(width) - THICCNESS - space, 0.0 + THICCNESS); - - float curveRadius = float(radius); -// Draw the lines connecting the points - -int setwidth = int(width); -int setheight = int(height); - - -if (setwidth<=400 && setheight<=300 ){ - col += drawCurveBenzier(p1, p2, setheight); - col += drawCurveBenzier(x1, x2, setheight); - col += drawCurveBenzier(y1, y2, setwidth); - col += drawCurveBenzier(z1, z2, setwidth); -} -else { - col += drawCurve(p1, p2, setheight); - col += drawCurve(x1, x2, setheight); - col += drawCurve(y1, y2, setwidth); - col += drawCurve(z1, z2, setwidth); - } - - -float INNERspace = 0.0; - - -//left - vec2 INNERp1 = vec2(0.0 - THICCNESS+ float(border_size), float(height) - THICCNESS - INNERspace-float(border_size) ); - vec2 INNERp2 = vec2(0.0 - THICCNESS+ float(border_size),0.0 - THICCNESS + INNERspace+float(border_size) +float(title_height-border_size)); -//right - vec2 INNERx1 = vec2(float(width) + THICCNESS-float(border_size), float(height)- THICCNESS - INNERspace-float(border_size)); - vec2 INNERx2 = vec2(float(width) + THICCNESS-float(border_size),0.0 - THICCNESS + INNERspace+float(border_size) +float(title_height-border_size)); -//bottom - vec2 INNERy1 = vec2(0.0 + THICCNESS + INNERspace+float(border_size), float(height) + THICCNESS -float(border_size)); - vec2 INNERy2 = vec2(float(width) - THICCNESS - INNERspace-float(border_size), float(height) + THICCNESS-float(border_size)); -//top - vec2 INNERz1 = vec2(0.0 +INNERspace+float(border_size), 0.0 - THICCNESS + INNERspace+float(border_size) +float(title_height-border_size)); - vec2 INNERz2 = vec2(float(width) - THICCNESS - INNERspace-float(border_size) ,0.0 - THICCNESS + INNERspace+float(border_size) +float(title_height-border_size)); - - - -if (setwidth<=400 && setheight<=300 ){ - col += drawCurveBenzier(INNERp1, INNERp2, setheight); - col += drawCurveBenzier(INNERx1, INNERx2, setheight); - col += drawCurveBenzier(INNERy1, INNERy2, setwidth); - col += drawCurveBenzier(INNERz1, INNERz2, setwidth); -} -else{ - col += drawCurve(INNERp1, INNERp2, setheight); - col += drawCurve(INNERx1, INNERx2, setheight); - col += drawCurve(INNERy1, INNERy2, setwidth); - col += drawCurve(INNERz1, INNERz2, setwidth); - } - - - vec2 p3 = fragCoord; - vec2 p12 = p2 - p1; - vec2 p13 = p3 - p1; - - vec2 x3 = fragCoord; - vec2 x12 = x2 - x1; - vec2 x13 = x3 - x1; - - vec2 y3 = fragCoord; - vec2 y12 = y2 - y1; - vec2 y13 = y3 - y1; - - vec2 z3 = fragCoord; - vec2 z12 = z2 - z1; - vec2 z13 = z3 - z1; - - float d = dot(p12, p13) / length(p12); // = length(p13) * cos(angle) - float dx = dot(x12, x13) / length(x12); - float dy = dot(y12, y13) / length(y12); - float dz = dot(z12, z13) / length(z12); - - vec2 p4 = p1 + normalize(p12) * d; - vec2 x4 = x1 + normalize(x12) * dx; - vec2 y4 = y1 + normalize(y12) * dy; - vec2 z4 = z1 + normalize(z12) * dz; - - if (((length(p4 - p3) < THICCNESS && length(p4 - p1) <= length(p12) && length(p4 - p2) <= length(p12)) || - (length(x4 - x3) < THICCNESS && length(x4 - x1) <= length(x12) && length(x4 - x2) <= length(x12))) || - (length(y4 - y3) < THICCNESS && length(y4 - y1) <= length(y12) && length(y4 - y2) <= length(y12)) || - (length(z4 - z3) < THICCNESS && length(z4 - z1) <= length(z12) && length(z4 - z2) <= length(z12))) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - - - vec2 INNERp3 = fragCoord; - vec2 INNERp12 = INNERp2 - INNERp1; - vec2 INNERp13 = INNERp3 - INNERp1; - - vec2 INNERx3 = fragCoord; - vec2 INNERx12 = INNERx2 - INNERx1; - vec2 INNERx13 = INNERx3 - INNERx1; - - vec2 INNERy3 = fragCoord; - vec2 INNERy12 = INNERy2 - INNERy1; - vec2 INNERy13 = INNERy3 - INNERy1; - - vec2 INNERz3 = fragCoord; - vec2 INNERz12 = INNERz2 - INNERz1; - vec2 INNERz13 = INNERz3 - INNERz1; - - float INNERd = dot(INNERp12, INNERp13) / length(INNERp12); // = length(p13) * cos(angle) - float INNERdx = dot(INNERx12, INNERx13) / length(INNERx12); - float INNERdy = dot(INNERy12, INNERy13) / length(INNERy12); - float INNERdz = dot(INNERz12, INNERz13) / length(INNERz12); - - vec2 INNERp4 = INNERp1 + normalize(INNERp12) * INNERd; - vec2 INNERx4 = INNERx1 + normalize(INNERx12) * INNERdx; - vec2 INNERy4 = INNERy1 + normalize(INNERy12) * INNERdy; - vec2 INNERz4 = INNERz1 + normalize(INNERz12) * INNERdz; - - if (((length(INNERp4 - INNERp3) < THICCNESS && length(INNERp4 - INNERp1) <= length(INNERp12) && length(INNERp4 - INNERp2) <= length(INNERp12)) || - (length(INNERx4 - INNERx3) < THICCNESS && length(INNERx4 - INNERx1) <= length(INNERx12) && length(INNERx4 - INNERx2) <= length(INNERx12))) || - (length(INNERy4 - INNERy3) < THICCNESS && length(INNERy4 - INNERy1) <= length(INNERy12) && length(INNERy4 - INNERy2) <= length(INNERy12)) || - (length(INNERz4 - INNERz3) < THICCNESS && length(INNERz4 - INNERz1) <= length(INNERz12) && length(INNERz4 - INNERz2) <= length(INNERz12))) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - - - - - - // Draw the lines connecting the points - // Calculate the line segment connecting p1 and y1 - vec2 dir = normalize(y1 - p1); - vec2 relPoint = fragCoord - p1; - float alongLine = dot(relPoint, dir); - float distance = length(relPoint - alongLine * dir); - - // Draw the line connecting p1 and y1 - if (distance < THICCNESS && alongLine > 0.0 && alongLine < length(y1 - p1)) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - - - - dir = normalize(y2 - x1); - relPoint = fragCoord - x1; - alongLine = dot(relPoint, dir); - distance = length(relPoint - alongLine * dir); - - if (distance < THICCNESS && alongLine > 0.0 && alongLine < length(x1 - y2)) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - - - dir = normalize(p2 - z1); - relPoint = fragCoord - z1; - alongLine = dot(relPoint, dir); - distance = length(relPoint - alongLine * dir); - - if (distance < THICCNESS && alongLine > 0.0 && alongLine < length(z1 - p2)) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - - - - dir = normalize(x2 - z2); - relPoint = fragCoord - z2; - alongLine = dot(relPoint, dir); - distance = length(relPoint - alongLine * dir); - - if (distance < THICCNESS && alongLine > 0.0 && alongLine < length(x2 - z2)) { - col = vec4(0.1, 0.1, 0.1, 1.0); - } - // Draw other lines... - - vec2 t1 = vec2(0.0, float(height)); - vec2 t2 = vec2(float(width), float(height)); - vec2 t3 = vec2(-0.5, -0.5); - vec2 t4 = vec2(float(width), -0.5); - - - if (isInsideTriangle(fragCoord, vec2(p1.x-10.1,p1.y), t1, vec2(y1.x,y1.y+10.1)) || - isInsideTriangle(fragCoord, vec2(x1.x+10.1,x1.y), t2, vec2(y2.x,y2.y+10.1)) || - isInsideTriangle(fragCoord, vec2(z1.x,z1.y-2.4), t3, vec2(p2.x-3.1,p2.y-2.1)) || - isInsideTriangle(fragCoord, vec2(z2.x,z2.y-5.5), t4, vec2(x2.x+3.1,x2.y)) ) { - col = vec4(0.0, 0.0, 0.0, 0.0); // Set the color to fully transparent - } else { - // Apply your original logic for other regions - - // Sample neural network texture - vec4 neuralColor = imageLoad(neural_network_tex, ivec2(fragCoord)); - col += neuralColor; - } -//z2 - x2 - - // vec4 neuralColor = imageLoad(neural_network_tex, ivec2(fragCoord)); - // col += neuralColor; - // Store the final color - imageStore(image, storePos, col); -} - -)"; - -void setup_shader(GLuint *program, std::string source) -{ - auto compute_shader = OpenGL::compile_shader(source.c_str(), GL_COMPUTE_SHADER); - auto compute_program = GL_CALL(glCreateProgram()); - GL_CALL(glAttachShader(compute_program, compute_shader)); - GL_CALL(glLinkProgram(compute_program)); - - int s = GL_FALSE; -#define LENGTH 1024 * 128 - char log[LENGTH]; - GL_CALL(glGetProgramiv(compute_program, GL_LINK_STATUS, &s)); - GL_CALL(glGetProgramInfoLog(compute_program, LENGTH, NULL, log)); - - if (s == GL_FALSE) - { - LOGE("Failed to link shader:\n", source, - "\nLinker output:\n", log); - } - - GL_CALL(glDeleteShader(compute_shader)); - *program = compute_program; -} - -static void seed_random() -{ - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - srandom(ts.tv_nsec); -} - -void smoke_t::destroy_programs() -{ - if (motion_program != GLuint(-1)) - { - GL_CALL(glDeleteProgram(motion_program)); - GL_CALL(glDeleteProgram(diffuse1_program)); - GL_CALL(glDeleteProgram(diffuse2_program)); - GL_CALL(glDeleteProgram(project1_program)); - GL_CALL(glDeleteProgram(project2_program)); - GL_CALL(glDeleteProgram(project3_program)); - GL_CALL(glDeleteProgram(project4_program)); - GL_CALL(glDeleteProgram(project5_program)); - GL_CALL(glDeleteProgram(project6_program)); - GL_CALL(glDeleteProgram(advect1_program)); - GL_CALL(glDeleteProgram(advect2_program)); - } - - if (render_program != GLuint(-1)) - { - GL_CALL(glDeleteProgram(render_program)); - } - - if (render_overlay_program != GLuint(-1)) - { - GL_CALL(glDeleteProgram(render_overlay_program)); - } - - motion_program = diffuse1_program = diffuse2_program = project1_program = - project2_program = project3_program = project4_program = project5_program = - project6_program = advect1_program = advect2_program = render_program = - render_overlay_program = GLuint(-1); -} - -void smoke_t::create_programs() -{ - destroy_programs(); - wf::gles::run_in_context([&] - { - if ((std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink")) - { - setup_shader(&motion_program, motion_source); - setup_shader(&diffuse1_program, stitch_smoke_shader(diffuse1_source)); - setup_shader(&diffuse2_program, stitch_smoke_shader(diffuse2_source)); - setup_shader(&project1_program, stitch_smoke_shader(project1_source)); - setup_shader(&project2_program, stitch_smoke_shader(project2_source)); - setup_shader(&project3_program, stitch_smoke_shader(project3_source)); - setup_shader(&project4_program, stitch_smoke_shader(project4_source)); - setup_shader(&project5_program, stitch_smoke_shader(project5_source)); - setup_shader(&project6_program, stitch_smoke_shader(project6_source)); - setup_shader(&advect1_program, stitch_smoke_shader(advect1_source)); - setup_shader(&advect2_program, stitch_smoke_shader(advect2_source)); - setup_shader(&render_program, std::string(render_source) + effect_run_for_region_main); - } else if (std::string(effect_type) == "clouds") - { - setup_shader(&render_program, render_source_clouds); - } else if (std::string(effect_type) == "halftone") - { - setup_shader(&render_program, render_source_halftone); - } else if (std::string(effect_type) == "pattern") - { - setup_shader(&render_program, render_source_pattern); - } else if (std::string(effect_type) == "lava") - { - setup_shader(&render_program, render_source_lava); - } else if (std::string(effect_type) == "hex") - { - setup_shader(&render_program, render_source_hex); - } else if (std::string(effect_type) == "zebra") - { - setup_shader(&render_program, render_source_zebra); - } else if (std::string(effect_type) == "neural_network") - { - setup_shader(&render_program, render_source_neural_network); - } else if (std::string(effect_type) == "hexagon_maze") - { - setup_shader(&render_program, render_source_hexagon_maze); - } else if (std::string(effect_type) == "raymarched_truchet") - { - setup_shader(&render_program, render_source_raymarched_truchet); - } else if (std::string(effect_type) == "neon_pattern") - { - setup_shader(&render_program, render_source_neon_pattern); - } else if (std::string(effect_type) == "neon_rings") - { - setup_shader(&render_program, render_source_neon_rings); - } else if (std::string(effect_type) == "deco") - { - setup_shader(&render_program, render_source_deco); - } - - if (std::string(overlay_engine) == "rounded_corners") - { - setup_shader(&render_overlay_program, rounded_corner_overlay); - } else if (std::string(overlay_engine) == "beveled_glass") - { - setup_shader(&render_overlay_program, beveled_glass_overlay); - } - }); -} - -smoke_t::smoke_t() -{ - motion_program = diffuse1_program = diffuse2_program = project1_program = - project2_program = project3_program = project4_program = project5_program = - project6_program = advect1_program = advect2_program = render_program = - render_overlay_program = GLuint(-1); - - texture = b0u = b0v = b0d = b1u = b1v = b1d = GLuint(-1); - - create_programs(); - seed_random(); -} - -smoke_t::~smoke_t() -{ - destroy_programs(); - destroy_textures(); -} - -void smoke_t::create_textures() -{ - GL_CALL(glGenTextures(1, &texture)); - GL_CALL(glGenTextures(1, &b0u)); - GL_CALL(glGenTextures(1, &b0v)); - GL_CALL(glGenTextures(1, &b0d)); - GL_CALL(glGenTextures(1, &b1u)); - GL_CALL(glGenTextures(1, &b1v)); - GL_CALL(glGenTextures(1, &b1d)); -} - -void smoke_t::destroy_textures() -{ - if (texture != GLuint(-1)) - { - GL_CALL(glDeleteTextures(1, &texture)); - texture = GLuint(-1); - } - - if (b0u == GLuint(-1)) - { - return; - } - - GL_CALL(glDeleteTextures(1, &b0u)); - GL_CALL(glDeleteTextures(1, &b0v)); - GL_CALL(glDeleteTextures(1, &b0d)); - GL_CALL(glDeleteTextures(1, &b1u)); - GL_CALL(glDeleteTextures(1, &b1v)); - GL_CALL(glDeleteTextures(1, &b1d)); - - b0u = b0v = b0d = b1u = b1v = b1d = GLuint(-1); -} - -int round_up_div(int a, int b) -{ - return (a + b - 1) / b; -} - -void smoke_t::dispatch_region(const wf::region_t& region) -{ - std::vector values; - - int max_x = 0; - int max_y = 0; - - for (auto& box : region) - { - auto rect = wlr_box_from_pixman_box(box); - values.push_back(rect.x); - values.push_back(rect.y); - values.push_back(rect.width); - values.push_back(rect.height); - - if (rect.width > rect.height) - { - values.push_back(0); // xy will not be flipped in compute shader - max_x = std::max(max_x, rect.width); - max_y = std::max(max_y, rect.height); - } else - { - values.push_back(1); // xy will be flipped in compute shader - max_x = std::max(max_x, rect.height); - max_y = std::max(max_y, rect.width); - } - } - - if (values.size() / 5 > 4) - { - LOGE("Error: too many regions"); - return; - } - - GL_CALL(glUniform1iv(10, values.size(), values.data())); - GL_CALL(glDispatchCompute(round_up_div(max_x, 16), round_up_div(max_y, 16), values.size() / 5)); - GL_CALL(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)); -} - -void smoke_t::run_shader_region(GLuint program, const wf::region_t & region, const wf::dimensions_t & size) -{ - GL_CALL(glUseProgram(program)); - GL_CALL(glUniform1i(5, size.width)); - GL_CALL(glUniform1i(6, size.height)); - dispatch_region(region); -} - -void smoke_t::run_shader(GLuint program, int width, int height, int title_height, int border_size, int radius) -{ - GL_CALL(glUseProgram(program)); - GL_CALL(glUniform1i(1, title_height + border_size + radius * 2)); - GL_CALL(glUniform1i(2, border_size + radius * 2)); - GL_CALL(glUniform1i(5, width)); - GL_CALL(glUniform1i(6, height)); - GL_CALL(glUniform1i(9, radius * 2)); - GL_CALL(glDispatchCompute(width / 15, height / 15, 1)); - GL_CALL(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)); -} - -void smoke_t::recreate_textures(wf::geometry_t rectangle) -{ - if ((rectangle.width <= 0) || (rectangle.height <= 0)) - { - return; - } - - destroy_textures(); - create_textures(); - - GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, rectangle.width, rectangle.height)); - if ((std::string(effect_type) != "smoke") && (std::string(effect_type) != "ink")) - { - return; - } - - GLuint fb; - GL_CALL(glGenFramebuffers(1, &fb)); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, fb)); - - wf::color_t clear_color{0, 0, 0, 0}; - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - - GL_CALL(glActiveTexture(GL_TEXTURE0 + 1)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0u)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b0u, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 2)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0v)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b0v, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 3)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0d)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b0d, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 4)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1u)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b1u, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 5)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1v)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b1v, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 6)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1d)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, rectangle.width, rectangle.height)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, b1d, 0)); - OpenGL::clear(clear_color, GL_COLOR_BUFFER_BIT); - - GL_CALL(glDeleteFramebuffers(1, &fb)); -} - -void smoke_t::step_effect(const wf::scene::render_instruction_t& data, wf::geometry_t rectangle, - bool ink, wf::pointf_t p, wf::color_t decor_color, wf::color_t effect_color, - int title_height, int border_size, int shadow_radius) -{ - bool smoke = (std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink"); - if ((rectangle.width <= 0) || (rectangle.height <= 0)) - { - return; - } - - int radius = shadow_radius; - int diffuse_iterations = 2; - - wf::gles::run_in_context([&] - { - wf::gles::bind_render_buffer(data.target); - if ((rectangle.width != saved_width) || (rectangle.height != saved_height)) - { - saved_width = rectangle.width; - saved_height = rectangle.height; - - recreate_textures(rectangle); - } - - GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); - GL_CALL(glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F)); - - const wf::geometry_t nonshadow_rect = wf::geometry_t{ - radius* 2, - radius* 2, - rectangle.width - 4 * radius, - rectangle.height - 4 * radius - }; - - wf::geometry_t inner_part = { - border_size + radius * 2, - title_height + border_size + radius * 2, - rectangle.width - border_size * 2 - radius * 4, - rectangle.height - border_size * 2 - title_height - radius * 4, - }; - - wf::region_t border_region = nonshadow_rect; - border_region ^= inner_part; - border_region.expand_edges(1); - border_region &= nonshadow_rect; - - if (smoke) - { - wf::point_t point{int(p.x), int(p.y)}; - if ((p.x == FLT_MIN) || (p.y == FLT_MIN)) - { - point.x = point.y = INT_MIN; - } - - GL_CALL(glActiveTexture(GL_TEXTURE0 + 1)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0u)); - GL_CALL(glBindImageTexture(1, b0u, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 2)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0v)); - GL_CALL(glBindImageTexture(2, b0v, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 3)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b0d)); - GL_CALL(glBindImageTexture(3, b0d, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 4)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1u)); - GL_CALL(glBindImageTexture(4, b1u, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 5)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1v)); - GL_CALL(glBindImageTexture(5, b1v, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 6)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, b1d)); - GL_CALL(glBindImageTexture(6, b1d, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F)); - - if ((point.x >= radius) && (point.y >= radius)) - { - GL_CALL(glUseProgram(motion_program)); - // upload stuff - GL_CALL(glUniform1i(1, title_height + border_size + radius * 2)); - GL_CALL(glUniform1i(2, border_size + radius * 2)); - GL_CALL(glUniform1i(3, point.x)); - GL_CALL(glUniform1i(4, point.y)); - GL_CALL(glUniform1i(5, rectangle.width)); - GL_CALL(glUniform1i(6, rectangle.height)); - GL_CALL(glUniform1i(7, random())); - GL_CALL(glUniform1i(8, random())); - GL_CALL(glUniform1i(9, radius * 2)); - GL_CALL(glDispatchCompute(1, 1, 1)); - GL_CALL(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)); - } - - for (int k = 0; k < diffuse_iterations; k++) - { - run_shader_region(diffuse1_program, border_region, wf::dimensions(rectangle)); - } - - run_shader_region(project1_program, border_region, wf::dimensions(rectangle)); - for (int k = 0; k < diffuse_iterations; k++) - { - run_shader_region(project2_program, border_region, wf::dimensions(rectangle)); - } - - run_shader_region(project3_program, border_region, wf::dimensions(rectangle)); - run_shader_region(advect1_program, border_region, wf::dimensions(rectangle)); - run_shader_region(project4_program, border_region, wf::dimensions(rectangle)); - for (int k = 0; k < diffuse_iterations; k++) - { - run_shader_region(project5_program, border_region, wf::dimensions(rectangle)); - } - - run_shader_region(project6_program, border_region, wf::dimensions(rectangle)); - for (int k = 0; k < diffuse_iterations; k++) - { - run_shader_region(diffuse2_program, border_region, wf::dimensions(rectangle)); - } - - run_shader_region(advect2_program, border_region, wf::dimensions(rectangle)); - } - - if (std::string(effect_type) != "none") - { - GL_CALL(glUseProgram(render_program)); - - GLfloat effect_color_f[4] = - {GLfloat(effect_color.r), GLfloat(effect_color.g), GLfloat(effect_color.b), - GLfloat(effect_color.a)}; - GLfloat decor_color_f[4] = - {GLfloat(decor_color.r), GLfloat(decor_color.g), GLfloat(decor_color.b), GLfloat(decor_color.a)}; - if (smoke) - { - GL_CALL(glUniform1i(4, ink)); - GL_CALL(glUniform4fv(8, 1, effect_color_f)); - GL_CALL(glUniform4fv(9, 1, decor_color_f)); - dispatch_region(border_region); - } else - { - GL_CALL(glUniform1i(1, title_height + border_size + radius * 2)); - GL_CALL(glUniform1i(2, border_size + radius * 2)); - GL_CALL(glUniform1i(5, rectangle.width)); - GL_CALL(glUniform1i(6, rectangle.height)); - GL_CALL(glUniform1i(7, radius * 2)); - GL_CALL(glUniform1f(9, effect_animate ? ((wf::get_current_time() & 0x5FFFFFFF) / 30.0) : 0.0)); - GL_CALL(glDispatchCompute(rectangle.width / 15, rectangle.height / 15, 1)); - GL_CALL(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)); - } - } else if (!smoke && (std::string(overlay_engine) != "none")) - { - GLuint fb; - GL_CALL(glGenFramebuffers(1, &fb)); - GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, fb)); - GL_CALL(glActiveTexture(GL_TEXTURE0 + 0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); - GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture, 0)); - OpenGL::clear(decor_color, GL_COLOR_BUFFER_BIT); - GL_CALL(glDeleteFramebuffers(1, &fb)); - } - if ((std::string(overlay_engine) == "rounded_corners") || - (std::string(overlay_engine) == "beveled_glass")) - { - GL_CALL(glUseProgram(render_overlay_program)); - GL_CALL(glUniform1i(1, title_height + border_size + radius * 2)); - GL_CALL(glUniform1i(2, border_size + radius * 2)); - GL_CALL(glUniform1i(5, rectangle.width)); - GL_CALL(glUniform1i(6, rectangle.height)); - GL_CALL(glUniform1i(7, rounded_corner_radius)); - if (std::string(overlay_engine) == "rounded_corners") - { - GLfloat shadow_color_f[4] = - {GLfloat(wf::color_t(shadow_color).r), GLfloat(wf::color_t(shadow_color).g), - GLfloat(wf::color_t(shadow_color).b), GLfloat(wf::color_t(shadow_color).a)}; - GL_CALL(glUniform1i(8, radius)); - GL_CALL(glUniform4fv(9, 1, shadow_color_f)); - } - - GL_CALL(glDispatchCompute(round_up_div(rectangle.width, 16), round_up_div(rectangle.height, 16), 1)); - GL_CALL(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)); - } - - GL_CALL(glUseProgram(0)); - }); -} - -void smoke_t::render_effect(const wf::scene::render_instruction_t& data, wf::geometry_t rectangle) -{ - OpenGL::render_transformed_texture(wf::gles_texture_t{texture}, rectangle, - wf::gles::render_target_orthographic_projection(data.target), glm::vec4{1}, - OpenGL::TEXTURE_TRANSFORM_INVERT_Y | OpenGL::RENDER_FLAG_CACHED); - - data.pass->custom_gles_subpass(data.target,[&] - { - for (auto& box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::draw_cached(); - } - }); - - OpenGL::clear_cached(); -} - -void smoke_t::effect_updated() -{ - create_programs(); - wf::gles::run_in_context([&] - { - recreate_textures(wf::geometry_t{0, 0, saved_width, saved_height}); - }); -} -} // namespace pixdecor -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-effects.hpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-effects.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-effects.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-effects.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,51 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include - -namespace wf -{ -namespace pixdecor -{ -class smoke_t -{ - /** background effects */ - GLuint motion_program, - diffuse1_program, diffuse2_program, - project1_program, project2_program, project3_program, - project4_program, project5_program, project6_program, - advect1_program, advect2_program, render_program, render_overlay_program, - texture, b0u, b0v, b0d, b1u, b1v, b1d, neural_network_tex; - - int saved_width = -1, saved_height = -1; - - wf::option_wrapper_t effect_type{"pixdecor/effect_type"}; - wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; - wf::option_wrapper_t effect_animate{"pixdecor/animate"}; - wf::option_wrapper_t rounded_corner_radius{"pixdecor/rounded_corner_radius"}; - wf::option_wrapper_t shadow_color{"pixdecor/shadow_color"}; - - public: - smoke_t(); - ~smoke_t(); - - void run_shader(GLuint program, int width, int height, int title_height, int border_size, int radius); - void run_shader_region(GLuint program, const wf::region_t & region, const wf::dimensions_t & size); - void dispatch_region(const wf::region_t& region); - - void step_effect(const wf::scene::render_instruction_t& data, wf::geometry_t rectangle, - bool ink, wf::pointf_t p, wf::color_t decor_color, wf::color_t effect_color, - int title_height, int border_size, int shadow_radius); - void render_effect(const wf::scene::render_instruction_t& data, wf::geometry_t rectangle); - void recreate_textures(wf::geometry_t rectangle); - void create_programs(); - void destroy_programs(); - void create_textures(); - void destroy_textures(); - void effect_updated(); -}; -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-layout.cpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-layout.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-layout.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-layout.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,591 +0,0 @@ -#include "deco-layout.hpp" -#include "deco-theme.hpp" -#include -#include -#include -#include -#include - -namespace wf -{ -namespace pixdecor -{ -/** - * Represents an area of the decoration which reacts to input events. - */ -decoration_area_t::decoration_area_t(decoration_area_type_t type, wf::geometry_t g) -{ - this->type = type; - this->geometry = g; - - assert(type != DECORATION_AREA_BUTTON); -} - -/** - * Initialize a new decoration area holding a button - */ -decoration_area_t::decoration_area_t(wf::geometry_t g, - std::function damage_callback, - pixdecor_theme_t& theme) -{ - this->type = DECORATION_AREA_BUTTON; - this->geometry = g; - this->damage_callback = damage_callback; - - this->button = std::make_unique(theme, - std::bind(damage_callback, g)); -} - -wf::geometry_t decoration_area_t::get_geometry() const -{ - return geometry; -} - -void decoration_area_t::set_geometry(wf::geometry_t g) -{ - geometry = g; - - if (this->type == DECORATION_AREA_BUTTON) - { - this->button = std::make_unique(this->button->theme, - std::bind(this->damage_callback, g)); - } -} - -button_t& decoration_area_t::as_button() -{ - assert(button); - - return *button; -} - -decoration_area_type_t decoration_area_t::get_type() const -{ - return type; -} - -pixdecor_layout_t::pixdecor_layout_t(pixdecor_theme_t& th, - std::function callback) : - - titlebar_size(th.get_title_height()), - border_size(th.get_input_size()), - theme(th), - damage_callback(callback) -{} - -pixdecor_layout_t::~pixdecor_layout_t() -{ - this->layout_areas.clear(); -} - -wf::geometry_t pixdecor_layout_t::create_buttons(int width, int radius) -{ - // read the string from settings; start at the colon and replace commas with spaces - wf::option_wrapper_t button_spacing{"pixdecor/button_spacing"}; - wf::option_wrapper_t button_x_offset{"pixdecor/button_x_offset"}; - wf::option_wrapper_t button_y_offset{"pixdecor/button_y_offset"}; - GSettings *settings = g_settings_new("org.gnome.desktop.wm.preferences"); - gchar *b_layout = g_settings_get_string(settings, "button-layout"); - gchar *ptr = b_layout + strlen(b_layout) - 1; - while (ptr >= b_layout) - { - if (*ptr == ',') - { - *ptr = ' '; - } - - if (*ptr == ':') - { - break; - } - - ptr--; - } - - std::string layout = (*ptr == ':') ? ptr + 1 : std::string(b_layout); - g_free(b_layout); - g_object_unref(settings); - - std::stringstream stream((std::string)layout); - std::vector buttons; - std::string button_name; - while (stream >> button_name) - { - if (button_name == "minimize") - { - buttons.push_back(BUTTON_MINIMIZE); - } - - if (button_name == "maximize") - { - buttons.push_back(BUTTON_TOGGLE_MAXIMIZE); - } - - if (button_name == "close") - { - buttons.push_back(BUTTON_CLOSE); - } - } - - int total_width = 0; - int per_button = 0; - int border = theme.get_border_size(); - wf::geometry_t button_geometry; - button_geometry.x = (width - (maximized ? 4 : border)) + button_x_offset; - - for (auto type : wf::reverse(buttons)) - { - auto button_area = std::make_unique(button_geometry, damage_callback, theme); - auto surface_size = button_area->as_button().set_button_type(type); - button_geometry.width = surface_size.width; - button_geometry.height = surface_size.height; - int button_padding = (theme.get_title_height() - button_geometry.height) / 2 + button_y_offset; - button_geometry.y = button_padding + border / 2 + (radius * 2); - per_button = button_geometry.width + (buttons.back() == type ? 0 : button_spacing); - button_geometry.x -= per_button; - button_area->set_geometry(button_geometry); - button_area->as_button().set_button_type(type); - this->layout_areas.push_back(std::move(button_area)); - total_width += per_button; - } - - total_width -= button_x_offset; - - return { - button_geometry.x, maximized ? 4 : border + (radius * 2), - total_width, theme.get_title_height() - }; -} - -/** Regenerate layout using the new size */ -void pixdecor_layout_t::resize(int width, int height) -{ - wf::option_wrapper_t shadow_radius{"pixdecor/shadow_radius"}; - wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; - wf::option_wrapper_t maximized_borders{"pixdecor/maximized_borders"}; - bool rounded_corners = std::string(overlay_engine) == "rounded_corners"; - - int border = theme.get_border_size(); - int radius = (rounded_corners && !maximized) ? int(shadow_radius) : 0; - - this->layout_areas.clear(); - - if (this->theme.get_title_height() > 0) - { - auto button_geometry_expanded = create_buttons(width - (radius * 2), radius); - - /* Padding around the button, allows move */ - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_MOVE, button_geometry_expanded)); - - /* Titlebar dragging area (for move) */ - wf::geometry_t title_geometry = { - border, - maximized ? 0 : border / 2 + (radius * 2), - /* Up to the button, but subtract the padding to the left of the - * title and the padding between title and button */ - std::max(1, button_geometry_expanded.x - border), - theme.get_title_height() + (maximized ? 0 : border / 2 + 1), - }; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_TITLE, title_geometry)); - - this->cached_titlebar = { - border, border, - width - 2 * border, height - 2 * border - }; - } - - border = MIN_RESIZE_HANDLE_SIZE - theme.get_input_size(); - auto inverse_border = MIN_RESIZE_HANDLE_SIZE - theme.get_border_size(); - - if (!maximized || maximized_borders) - { - /* Resizing edges - top */ - wf::geometry_t border_geometry = - {0 + (radius * 2), -inverse_border + (radius * 2), - width - (radius * 4) + MIN_RESIZE_HANDLE_SIZE, border}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_RESIZE_TOP, border_geometry)); - - /* Resizing edges - bottom */ - border_geometry = - {0 + (radius * 2), (height - border + inverse_border) - (radius * 2), - width - (radius * 4) + MIN_RESIZE_HANDLE_SIZE, border}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_RESIZE_BOTTOM, border_geometry)); - - /* Resizing edges - left */ - border_geometry = - {-inverse_border + (radius * 2), 0 + (radius * 2), border, - height - (radius * 4) + MIN_RESIZE_HANDLE_SIZE}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_RESIZE_LEFT, border_geometry)); - - /* Resizing edges - right */ - border_geometry = - {(width - border + inverse_border) - (radius * 2), 0 + (radius * 2), border, - height - (radius * 4) + MIN_RESIZE_HANDLE_SIZE}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_RESIZE_RIGHT, border_geometry)); - - if (rounded_corners) - { - /* Shadow - top */ - border_geometry = {0, 0, width, radius* 2}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_SHADOW, border_geometry)); - - /* Shadow - bottom */ - border_geometry = {0, height - radius * 2, width, radius* 2}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_SHADOW, border_geometry)); - - /* Shadow - left */ - border_geometry = {0, radius* 2, radius* 2, height - radius * 4}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_SHADOW, border_geometry)); - - /* Shadow - right */ - border_geometry = {width - radius * 2, radius* 2, radius* 2, height - radius * 4}; - this->layout_areas.push_back(std::make_unique( - DECORATION_AREA_SHADOW, border_geometry)); - } - } -} - -/** - * @return The decoration areas which need to be rendered, in top to bottom - * order. - */ -std::vector> pixdecor_layout_t::get_renderable_areas() -{ - std::vector> renderable; - for (auto& area : layout_areas) - { - if (area->get_type() & DECORATION_AREA_RENDERABLE_BIT) - { - renderable.push_back({area}); - } - } - - return renderable; -} - -wf::region_t pixdecor_layout_t::calculate_region() const -{ - wf::region_t r{}; - for (auto& area : layout_areas) - { - auto g = area->get_geometry(); - auto b = theme.get_input_size(); - if (maximized && (area->get_type() & DECORATION_AREA_MOVE_BIT)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, b, b}); - } - - if (area->get_type() & DECORATION_AREA_RESIZE_BIT) - { - if (b <= MIN_RESIZE_HANDLE_SIZE) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_TOP) || - (area->get_type() == DECORATION_AREA_RESIZE_BOTTOM)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{0, 0, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_LEFT) || - (area->get_type() == DECORATION_AREA_RESIZE_RIGHT)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, 0, 0}); - } - } - - if ((g.width > 0) && (g.height > 0)) - { - r |= g; - } - } - - return r; -} - -wf::region_t pixdecor_layout_t::limit_region(wf::region_t & region) const -{ - wf::region_t out = region & this->cached_titlebar; - return out; -} - -void pixdecor_layout_t::unset_hover(wf::point_t position) -{ - auto area = find_area_at(position); - if (area && (area->get_type() == DECORATION_AREA_BUTTON)) - { - area->as_button().set_hover(false); - } -} - -/** Handle motion event to (x, y) relative to the decoration */ -pixdecor_layout_t::action_response_t pixdecor_layout_t::handle_motion( - int x, int y) -{ - auto previous_area = find_area_at(current_input); - auto current_area = find_area_at({x, y}); - - if (previous_area == current_area) - { - if (is_grabbed && current_area && - (current_area->get_type() & DECORATION_AREA_MOVE_BIT)) - { - is_grabbed = false; - return {DECORATION_ACTION_MOVE, 0}; - } - } else - { - unset_hover(current_input); - if (current_area && (current_area->get_type() == DECORATION_AREA_BUTTON)) - { - current_area->as_button().set_hover(true); - } - } - - this->current_input = {x, y}; - update_cursor(); - - return {DECORATION_ACTION_NONE, 0}; -} - -/** - * Handle press or release event. - * @param pressed Whether the event is a press(true) or release(false) - * event. - * @return The action which needs to be carried out in response to this - * event. - * */ -pixdecor_layout_t::action_response_t pixdecor_layout_t::handle_press_event( - bool pressed) -{ - if (pressed) - { - auto area = find_area_at(current_input); - if (area && (area->get_type() & DECORATION_AREA_MOVE_BIT)) - { - if (timer.is_connected()) - { - double_click_at_release = true; - } else - { - timer.set_timeout(300, [] () { return false; }); - } - } - - if (area && (area->get_type() & DECORATION_AREA_RESIZE_BIT)) - { - return {DECORATION_ACTION_RESIZE, calculate_resize_edges()}; - } - - if (area && (area->get_type() == DECORATION_AREA_BUTTON)) - { - area->as_button().set_pressed(true); - } - - is_grabbed = true; - grab_origin = current_input; - } - - if (!pressed && double_click_at_release) - { - double_click_at_release = false; - return {DECORATION_ACTION_TOGGLE_MAXIMIZE, 0}; - } else if (!pressed && is_grabbed) - { - is_grabbed = false; - auto begin_area = find_area_at(grab_origin); - auto end_area = find_area_at(current_input); - - if (begin_area && (begin_area->get_type() == DECORATION_AREA_BUTTON)) - { - begin_area->as_button().set_pressed(false); - if (end_area && (begin_area == end_area)) - { - switch (begin_area->as_button().get_button_type()) - { - case BUTTON_CLOSE: - return {DECORATION_ACTION_CLOSE, 0}; - - case BUTTON_TOGGLE_MAXIMIZE: - return {DECORATION_ACTION_TOGGLE_MAXIMIZE, 0}; - - case BUTTON_MINIMIZE: - return {DECORATION_ACTION_MINIMIZE, 0}; - - default: - break; - } - } - } - } - - return {DECORATION_ACTION_NONE, 0}; -} - -pixdecor_layout_t::action_response_t pixdecor_layout_t::handle_axis_event( - int delta) -{ - if (delta < 0) - { - return {DECORATION_ACTION_SHADE, 0}; - } else - { - return {DECORATION_ACTION_UNSHADE, 0}; - } -} - -/** - * Find the layout area at the given coordinates, if any - * @return The layout area or null on failure - */ -nonstd::observer_ptr pixdecor_layout_t::find_area_at( - wf::point_t point) -{ - for (auto& area : this->layout_areas) - { - auto g = area->get_geometry(); - auto b = theme.get_input_size(); - if (area->get_type() & DECORATION_AREA_MOVE_BIT) - { - continue; - } - - if (area->get_type() & DECORATION_AREA_RESIZE_BIT) - { - if (b <= MIN_RESIZE_HANDLE_SIZE) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_TOP) || - (area->get_type() == DECORATION_AREA_RESIZE_BOTTOM)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{0, 0, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_LEFT) || - (area->get_type() == DECORATION_AREA_RESIZE_RIGHT)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, 0, 0}); - } - } - - if (maximized && (area->get_type() & DECORATION_AREA_MOVE_BIT)) - { - g.height += b; - } - - if (g & point) - { - return {area}; - } - } - - for (auto& area : this->layout_areas) - { - auto g = area->get_geometry(); - auto b = theme.get_input_size(); - if (area->get_type() & DECORATION_AREA_RESIZE_BIT) - { - continue; - } - - if (maximized && (area->get_type() & DECORATION_AREA_MOVE_BIT)) - { - g.height += b; - } - - if (g & point) - { - return {area}; - } - } - - return nullptr; -} - -/** Calculate resize edges based on @current_input */ -uint32_t pixdecor_layout_t::calculate_resize_edges() const -{ - wf::option_wrapper_t shadow_radius{"pixdecor/shadow_radius"}; - wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; - int radius = (std::string(overlay_engine) == "rounded_corners") ? int(shadow_radius) : 0; - uint32_t edges = 0; - for (auto& area : layout_areas) - { - auto g = area->get_geometry(); - auto b = theme.get_input_size(); - g.width = g.width ?: 1; - g.height = g.height ?: 1; - if (area->get_type() & DECORATION_AREA_RESIZE_BIT) - { - if (b <= MIN_RESIZE_HANDLE_SIZE) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_TOP) || - (area->get_type() == DECORATION_AREA_RESIZE_BOTTOM)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{0, 0, b, b}); - } else if ((area->get_type() == DECORATION_AREA_RESIZE_LEFT) || - (area->get_type() == DECORATION_AREA_RESIZE_RIGHT)) - { - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{b, b, 0, 0}); - } - } - - if (((b - radius * 2) > MIN_RESIZE_HANDLE_SIZE) && (area->get_type() == DECORATION_AREA_RESIZE_TOP)) - { - g.height /= 2; - } - - if (g & this->current_input) - { - if (area->get_type() & DECORATION_AREA_RESIZE_BIT) - { - edges |= (area->get_type() & ~DECORATION_AREA_RESIZE_BIT); - } - } - } - - return edges; -} - -/** Update the cursor based on @current_input */ -void pixdecor_layout_t::update_cursor() -{ - uint32_t edges = calculate_resize_edges(); - auto area = find_area_at(this->current_input); - if (area && (area->get_type() == DECORATION_AREA_BUTTON)) - { - wf::get_core().set_cursor("default"); - return; - } - - auto cursor_name = edges > 0 ? - wlr_xcursor_get_resize_name((wlr_edges)edges) : "default"; - wf::get_core().set_cursor(cursor_name); -} - -void pixdecor_layout_t::set_maximize(bool state) -{ - maximized = state; -} - -void pixdecor_layout_t::handle_focus_lost() -{ - if (is_grabbed) - { - this->is_grabbed = false; - auto area = find_area_at(grab_origin); - if (area && (area->get_type() == DECORATION_AREA_BUTTON)) - { - area->as_button().set_pressed(false); - } - } - - this->unset_hover(current_input); -} -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-layout.hpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-layout.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-layout.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-layout.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,201 +0,0 @@ -#pragma once - -#include -#include -#include "deco-button.hpp" - -namespace wf -{ -namespace pixdecor -{ -static constexpr uint32_t DECORATION_AREA_RENDERABLE_BIT = (1 << 16); -static constexpr uint32_t DECORATION_AREA_RESIZE_BIT = (1 << 17); -static constexpr uint32_t DECORATION_AREA_MOVE_BIT = (1 << 18); -static constexpr uint32_t DECORATION_AREA_SHADOW_BIT = (1 << 19); - - -/** Different types of areas around the decoration */ -enum decoration_area_type_t -{ - DECORATION_AREA_MOVE = DECORATION_AREA_MOVE_BIT, - DECORATION_AREA_TITLE = - DECORATION_AREA_MOVE_BIT | DECORATION_AREA_RENDERABLE_BIT, - DECORATION_AREA_BUTTON = DECORATION_AREA_RENDERABLE_BIT, - DECORATION_AREA_SHADOW = DECORATION_AREA_SHADOW_BIT, - DECORATION_AREA_RESIZE_LEFT = WLR_EDGE_LEFT | DECORATION_AREA_RESIZE_BIT, - DECORATION_AREA_RESIZE_RIGHT = WLR_EDGE_RIGHT | DECORATION_AREA_RESIZE_BIT, - DECORATION_AREA_RESIZE_TOP = WLR_EDGE_TOP | DECORATION_AREA_RESIZE_BIT, - DECORATION_AREA_RESIZE_BOTTOM = WLR_EDGE_BOTTOM | DECORATION_AREA_RESIZE_BIT, -}; - -/** - * Represents an area of the decoration which reacts to input events. - */ -struct decoration_area_t -{ - public: - /** - * Initialize a new decoration area with the given type and geometry - */ - decoration_area_t(decoration_area_type_t type, wf::geometry_t g); - - /** - * Initialize a new decoration area holding a button. - * - * @param g The geometry of the button. - * @param damage_callback Callback to execute when button needs repaint. - * @param theme The theme to use for the button. - */ - decoration_area_t(wf::geometry_t g, - std::function damage_callback, - pixdecor_theme_t& theme); - - /** @return The geometry of the decoration area, relative to the layout */ - wf::geometry_t get_geometry() const; - void set_geometry(wf::geometry_t g); - - /** @return The area's button, if the area is a button. Otherwise UB */ - button_t& as_button(); - - /** @return The type of the decoration area */ - decoration_area_type_t get_type() const; - - private: - std::function damage_callback; - decoration_area_type_t type; - wf::geometry_t geometry; - - /* For buttons only */ - std::unique_ptr button; -}; - - -/** - * Action which needs to be taken in response to an input event - */ -enum decoration_layout_action_t -{ - DECORATION_ACTION_NONE = 0, - /* Drag actions */ - DECORATION_ACTION_MOVE = 1, - DECORATION_ACTION_RESIZE = 2, - /* Button actions */ - DECORATION_ACTION_CLOSE = 3, - DECORATION_ACTION_TOGGLE_MAXIMIZE = 4, - DECORATION_ACTION_MINIMIZE = 5, - /* Axis actions */ - DECORATION_ACTION_SHADE = 6, - DECORATION_ACTION_UNSHADE = 7, -}; - -class pixdecor_theme_t; -/** - * Manages the layout of the decorations, i.e positioning of the title, - * buttons, etc. - * - * Also dispatches the input events to the appropriate place. - */ -class pixdecor_layout_t -{ - public: - /** - * Create a new decoration layout for the given theme. - * When the theme changes, the decoration layout needs to be created again. - * - * @param damage_callback The function to be called when a part of the - * layout needs a repaint. - */ - pixdecor_layout_t(pixdecor_theme_t& theme, - std::function damage_callback); - ~pixdecor_layout_t(); - - /** Regenerate layout using the new size */ - void resize(int width, int height); - - /** - * @return The decoration areas which need to be rendered, in top to bottom - * order. - */ - std::vector> get_renderable_areas(); - - /** @return The combined region of all layout areas */ - wf::region_t calculate_region() const; - - /** Limit region to title bar area by region intersection - * @param region to limit by title area - * @return the intersection between region and the title bar area */ - wf::region_t limit_region(wf::region_t & region) const; - - struct action_response_t - { - decoration_layout_action_t action; - /* For resizing action, determine the edges for resize request */ - uint32_t edges; - }; - - /** Handle motion event to (x, y) relative to the decoration */ - action_response_t handle_motion(int x, int y); - - /** - * Handle press or release event. - * @param pressed Whether the event is a press(true) or release(false) - * event. - * @return The action which needs to be carried out in response to this - * event. - */ - action_response_t handle_press_event(bool pressed = true); - - /** - * Handle axis event. - * @param delta The delta of the axis event denoting direction - * @return The action which needs to be carried out in response to this - * event. - */ - action_response_t handle_axis_event(int delta); - - /** - * Handle focus lost event. - */ - void handle_focus_lost(); - - void set_maximize(bool state); - - private: - const int titlebar_size; - const int border_size; - pixdecor_theme_t& theme; - bool maximized; - - std::function damage_callback; - - std::vector> layout_areas; - wf::geometry_t cached_titlebar; - - bool is_grabbed = false; - /* Position where the grab has started */ - wf::point_t grab_origin; - /* Last position of the input */ - wf::point_t current_input; - /* double-click timer */ - wf::wl_timer timer; - bool double_click_at_release = false; - - /** Create buttons in the layout, and return their total geometry */ - wf::geometry_t create_buttons(int width, int height); - - /** Calculate resize edges based on @current_input */ - uint32_t calculate_resize_edges() const; - /** Update the cursor based on @current_input */ - void update_cursor(); - - /** - * Find the layout area at the given coordinates, if any - * @return The layout area or null on failure - */ - nonstd::observer_ptr find_area_at(wf::point_t point); - - /** Unset hover state of hovered button at @position, if any */ - void unset_hover(wf::point_t position); -}; -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/decoration.cpp wayfire-plugins-extra/subprojects/pixdecor/src/decoration.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/decoration.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/decoration.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,764 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "deco-subsurface.hpp" -#include "wayfire/core.hpp" -#include "wayfire/plugin.hpp" -#include "wayfire/signal-provider.hpp" -#include "wayfire/toplevel-view.hpp" -#include "wayfire/toplevel.hpp" -#include -#include -#include -#include -#include -#include -#include "shade.hpp" - -namespace wf -{ -namespace pixdecor -{ -int handle_theme_updated(int fd, uint32_t mask, void *data) -{ - int bufsz = sizeof(inotify_event) + NAME_MAX + 1; - char buf[bufsz]; - - if ((mask & WL_EVENT_READABLE) == 0) - { - return 0; - } - - if (read(fd, buf, bufsz) < 0) - { - return 0; - } - - (*((std::function*)data))(); - - return 0; -} - -class wayfire_pixdecor : public wf::plugin_interface_t -{ - wf::option_wrapper_t border_size{"pixdecor/border_size"}; - wf::option_wrapper_t title_font{"pixdecor/title_font"}; - wf::option_wrapper_t title_text_align{"pixdecor/title_text_align"}; - wf::option_wrapper_t titlebar{"pixdecor/titlebar"}; - wf::option_wrapper_t maximized_borders{"pixdecor/maximized_borders"}; - wf::option_wrapper_t maximized_shadows{"pixdecor/maximized_shadows"}; - wf::option_wrapper_t fg_color{"pixdecor/fg_color"}; - wf::option_wrapper_t bg_color{"pixdecor/bg_color"}; - wf::option_wrapper_t fg_text_color{"pixdecor/fg_text_color"}; - wf::option_wrapper_t bg_text_color{"pixdecor/bg_text_color"}; - wf::option_wrapper_t button_color{"pixdecor/button_color"}; - wf::option_wrapper_t button_line_thickness{"pixdecor/button_line_thickness"}; - wf::option_wrapper_t button_spacing{"pixdecor/button_spacing"}; - wf::option_wrapper_t button_x_offset{"pixdecor/button_x_offset"}; - wf::option_wrapper_t button_y_offset{"pixdecor/button_y_offset"}; - wf::option_wrapper_t button_minimize_image{"pixdecor/button_minimize_image"}; - wf::option_wrapper_t button_maximize_image{"pixdecor/button_maximize_image"}; - wf::option_wrapper_t button_close_image{"pixdecor/button_close_image"}; - wf::option_wrapper_t ignore_views_string{"pixdecor/ignore_views"}; - wf::option_wrapper_t always_decorate_string{"pixdecor/always_decorate"}; - wf::option_wrapper_t effect_type{"pixdecor/effect_type"}; - wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; - wf::option_wrapper_t effect_animate{"pixdecor/animate"}; - wf::option_wrapper_t rounded_corner_radius{"pixdecor/rounded_corner_radius"}; - wf::option_wrapper_t shadow_radius{"pixdecor/shadow_radius"}; - wf::option_wrapper_t shadow_color{"pixdecor/shadow_color"}; - wf::view_matcher_t ignore_views{"pixdecor/ignore_views"}; - wf::view_matcher_t always_decorate{"pixdecor/always_decorate"}; - wf::option_wrapper_t shade_modifier{"pixdecor/shade_modifier"}; - wf::option_wrapper_t csd_titlebar_height{"pixdecor/csd_titlebar_height"}; - wf::option_wrapper_t enable_shade{"pixdecor/enable_shade"}; - wf::ipc_activator_t pixdecor_toggle_shade{"pixdecor/shade_toggle"}; - wf::wl_idle_call idle_update_views; - int inotify_fd; - int wd_cfg_file; - int wd_cfg_dir; - wl_event_source *evsrc; - std::function update_event; - wf::effect_hook_t pre_hook; - bool hook_set = false; - - wf::axis_callback shade_axis_cb; - - wf::signal::connection_t on_new_tx = - [=] (wf::txn::new_transaction_signal *ev) - { - // For each transaction, we need to consider what happens with participating views - for (const auto& obj : ev->tx->get_objects()) - { - if (auto toplevel = std::dynamic_pointer_cast(obj)) - { - // First check whether the toplevel already has decoration - // In that case, we should just set the correct margins - if (auto deco = toplevel->get_data()) - { - deco->update_decoration_size(); - toplevel->pending().margins = deco->get_margins(toplevel->pending()); - continue; - } - - // Second case: the view is already mapped, or the transaction does not map it. - // The view is not being decorated, so nothing to do here. - if (toplevel->current().mapped || !toplevel->pending().mapped) - { - continue; - } - - // Third case: the transaction will map the toplevel. - auto view = wf::find_view_for_toplevel(toplevel); - wf::dassert(view != nullptr, "Mapping a toplevel means there must be a corresponding view!"); - if (should_decorate_view(view)) - { - if (auto deco = toplevel->get_data()) - { - deco->update_decoration_size(); - } - - adjust_new_decorations(view); - } - } - } - }; - - wf::signal::connection_t on_decoration_state_changed = - [=] (wf::view_decoration_state_updated_signal *ev) - { - auto toplevel = wf::toplevel_cast(ev->view); - if (toplevel) - { - remove_decoration(toplevel); - } - - update_view_decoration(ev->view); - }; - - // allows criteria containing maximized or floating check - wf::signal::connection_t on_view_tiled = - [=] (wf::view_tiled_signal *ev) - { - update_view_decoration(ev->view); - }; - - wf::signal::connection_t on_app_id_changed = - [=] (wf::view_app_id_changed_signal *ev) - { - update_view_decoration(ev->view); - }; - - wf::signal::connection_t on_title_changed = - [=] (wf::view_title_changed_signal *ev) - { - update_view_decoration(ev->view); - }; - - wf::signal::connection_t on_output_added = - [=] (wf::output_added_signal *ev) - { - if (effect_animate || (std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink")) - { - ev->output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - }; - - wf::signal::connection_t on_output_removed = - [=] (wf::output_removed_signal *ev) - { - ev->output->render->rem_effect(&pre_hook); - }; - - void pop_transformer(wayfire_view view) - { - if (view->get_transformed_node()->get_transformer(shade_transformer_name)) - { - view->get_transformed_node()->rem_transformer(shade_transformer_name); - } - } - - void remove_shade_transformers() - { - for (auto& view : wf::get_core().get_all_views()) - { - pop_transformer(view); - } - } - - std::shared_ptr ensure_transformer(wayfire_view view, int titlebar_height) - { - auto tmgr = view->get_transformed_node(); - if (auto tr = tmgr->get_transformer(shade_transformer_name)) - { - return tr; - } - - auto node = std::make_shared(view, titlebar_height); - tmgr->add_transformer(node, wf::TRANSFORMER_2D, shade_transformer_name); - auto tr = tmgr->get_transformer(shade_transformer_name); - - return tr; - } - - void init_shade(wayfire_view view, bool shade, int titlebar_height) - { - if (!bool(enable_shade)) - { - return; - } - - if (shade) - { - if (view && view->is_mapped()) - { - auto tr = ensure_transformer(view, titlebar_height); - tr->set_titlebar_height(titlebar_height); - tr->init_animation(shade); - } - } else - { - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - tr->set_titlebar_height(titlebar_height); - tr->init_animation(shade); - } - } - } - - public: - - void init() override - { - auto& ol = wf::get_core().output_layout; - ol->connect(&on_output_added); - ol->connect(&on_output_removed); - wf::get_core().connect(&on_decoration_state_changed); - wf::get_core().tx_manager->connect(&on_new_tx); - wf::get_core().connect(&on_app_id_changed); - wf::get_core().connect(&on_title_changed); - wf::get_core().connect(&on_view_tiled); - - if (bool(enable_shade)) - { - wf::get_core().bindings->add_axis(shade_modifier, &shade_axis_cb); - } - - pixdecor_toggle_shade.set_handler([=] (wf::output_t *output, wayfire_view view) - { - if (!bool(enable_shade)) - { - return false; - } - - if (auto toplevel = wf::toplevel_cast(view)) - { - bool direction = true; - auto deco = toplevel->toplevel()->get_data(); - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - direction = !tr->get_direction(); - } - - init_shade(view, direction, - deco ? deco->get_titlebar_height() : csd_titlebar_height); - return true; - } - - return false; - }); - - shade_axis_cb = [=] (wlr_pointer_axis_event *ev) - { - auto v = wf::get_core().get_cursor_focus_view(); - if (ev->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) - { - if (auto toplevel = wf::toplevel_cast(v)) - { - auto deco = toplevel->toplevel()->get_data(); - init_shade(v, ev->delta < 0 ? true : false, - deco ? deco->get_titlebar_height() : csd_titlebar_height); - return true; - } - - return true; - } - - return false; - }; - - enable_shade.set_callback([=] - { - if (bool(enable_shade)) - { - wf::get_core().bindings->add_axis(shade_modifier, &shade_axis_cb); - } - - { - wf::get_core().bindings->rem_binding(&shade_axis_cb); - remove_shade_transformers(); - } - }); - - csd_titlebar_height.set_callback([=] () - { - for (auto& view : wf::get_core().get_all_views()) - { - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - auto toplevel = toplevel_cast(view); - if (toplevel) - { - if (!toplevel->toplevel()->get_data()) - { - tr->set_titlebar_height(csd_titlebar_height); - } - } - } - } - }); - - for (auto& view : wf::get_core().get_all_views()) - { - update_view_decoration(view); - } - - border_size.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - remove_decoration(toplevel); - adjust_new_decorations(toplevel); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - }); - - fg_color.set_callback([=] { update_colors(); }); - bg_color.set_callback([=] { update_colors(); }); - fg_text_color.set_callback([=] { update_colors(); }); - bg_text_color.set_callback([=] { update_colors(); }); - ignore_views_string.set_callback([=] - { - idle_update_views.run_once([=] () - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel) - { - continue; - } - - update_view_decoration(view); - } - }); - }); - always_decorate_string.set_callback([=] - { - idle_update_views.run_once([=] () - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel) - { - continue; - } - - update_view_decoration(view); - } - }); - }); - - pre_hook = [=] () - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - auto deco = toplevel->toplevel()->get_data(); - deco->update_animation(); - } - }; - - if (std::string(effect_type) != "none") - { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - - hook_set = true; - } - - titlebar.set_callback([=] {option_changed_cb(false, true);}); - effect_type.set_callback([=] {option_changed_cb(false, false);}); - overlay_engine.set_callback([=] {option_changed_cb(true, false);recreate_frames();}); - effect_animate.set_callback([=] {option_changed_cb(false, false);}); - button_color.set_callback([=] {recreate_frames();}); - button_line_thickness.set_callback([=] {recreate_frames();}); - button_spacing.set_callback([=] {recreate_frames();}); - button_x_offset.set_callback([=] {recreate_frames();}); - button_y_offset.set_callback([=] {recreate_frames();}); - button_minimize_image.set_callback([=] {recreate_frames();}); - button_maximize_image.set_callback([=] {recreate_frames();}); - button_close_image.set_callback([=] {recreate_frames();}); - title_text_align.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - view->damage(); - } - }); - title_font.set_callback([=] {recreate_frames();}); - shadow_radius.set_callback([=] - { - option_changed_cb(false, (std::string(overlay_engine) == "rounded_corners")); - }); - shadow_color.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - view->damage(); - } - }); - rounded_corner_radius.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - view->damage(); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - }); - maximized_borders.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data() || - !toplevel->pending_tiled_edges()) - { - continue; - } - - view->damage(); - remove_decoration(toplevel); - adjust_new_decorations(toplevel); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - }); - maximized_shadows.set_callback([=] - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data() || - !toplevel->pending_tiled_edges()) - { - continue; - } - - view->damage(); - remove_decoration(toplevel); - adjust_new_decorations(toplevel); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - }); - - // set up the watch on the xsettings file - inotify_fd = inotify_init1(IN_CLOEXEC); - evsrc = wl_event_loop_add_fd(wf::get_core().ev_loop, inotify_fd, WL_EVENT_READABLE, - handle_theme_updated, &this->update_event); - - // enable watches on xsettings file - char *conf_dir = g_build_filename(g_get_user_config_dir(), "xsettingsd/", NULL); - char *conf_file = g_build_filename(conf_dir, "xsettingsd.conf", NULL); - wd_cfg_dir = inotify_add_watch(inotify_fd, conf_dir, IN_CREATE); - wd_cfg_file = inotify_add_watch(inotify_fd, conf_file, IN_CLOSE_WRITE); - g_free(conf_file); - g_free(conf_dir); - - update_event = [=] (void) - { - update_colors(); - }; - - dlopen("libpangocairo-1.0.so", RTLD_LAZY); - } - - void fini() override - { - for (auto view : wf::get_core().get_all_views()) - { - if (auto toplevel = wf::toplevel_cast(view)) - { - remove_decoration(toplevel); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - } - - if (hook_set) - { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->rem_effect(&pre_hook); - } - } - - on_output_added.disconnect(); - on_output_removed.disconnect(); - on_decoration_state_changed.disconnect(); - on_new_tx.disconnect(); - on_app_id_changed.disconnect(); - on_title_changed.disconnect(); - - wf::get_core().bindings->rem_binding(&shade_axis_cb); - remove_shade_transformers(); - - wl_event_source_remove(evsrc); - inotify_rm_watch(inotify_fd, wd_cfg_file); - inotify_rm_watch(inotify_fd, wd_cfg_dir); - close(inotify_fd); - } - - void recreate_frame(wayfire_toplevel_view toplevel) - { - auto deco = toplevel->toplevel()->get_data(); - if (!deco) - { - return; - } - - deco->recreate_frame(); - } - - void recreate_frames() - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel) - { - continue; - } - - recreate_frame(toplevel); - } - } - - void option_changed_cb(bool resize_decorations, bool recreate_decorations) - { - if (effect_animate || (std::string(effect_type) == "smoke") || (std::string(effect_type) == "ink")) - { - if (!hook_set) - { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - - hook_set = true; - } - } else - { - if (hook_set) - { - for (auto& o : wf::get_core().output_layout->get_outputs()) - { - o->render->rem_effect(&pre_hook); - } - - hook_set = false; - } - } - - if (recreate_decorations) - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - remove_decoration(toplevel); - adjust_new_decorations(toplevel); - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - - return; - } - - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - view->damage(); - toplevel->toplevel()->get_data()->effect_updated(); - - auto& pending = toplevel->toplevel()->pending(); - if (!resize_decorations || (pending.tiled_edges != 0)) - { - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - continue; - } - - if (std::string(overlay_engine) == "rounded_corners") - { - pending.margins = - {int(shadow_radius) * 2, int(shadow_radius) * 2, - int(shadow_radius) * 2, int(shadow_radius) * 2}; - pending.geometry = wf::expand_geometry_by_margins(pending.geometry, pending.margins); - } else - { - pending.geometry = wf::shrink_geometry_by_margins(pending.geometry, pending.margins); - pending.margins = toplevel->toplevel()->get_data()->get_margins( - toplevel->toplevel()->pending()); - pending.geometry = wf::expand_geometry_by_margins(pending.geometry, pending.margins); - } - - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - } - - void update_colors() - { - for (auto& view : wf::get_core().get_all_views()) - { - auto toplevel = wf::toplevel_cast(view); - if (!toplevel || !toplevel->toplevel()->get_data()) - { - continue; - } - - auto deco = toplevel->toplevel()->get_data(); - deco->update_colors(); - view->damage(); - } - } - - /** - * Uses view_matcher_t to match whether the given view needs to be - * ignored for decoration - * - * @param view The view to match - * @return Whether the given view should be decorated? - */ - bool ignore_decoration_of_view(wayfire_view view) - { - return ignore_views.matches(view); - } - - bool should_decorate_view(wayfire_toplevel_view view) - { - return (view->should_be_decorated() && !ignore_decoration_of_view(view)) || always_decorate.matches( - view); - } - - void adjust_new_decorations(wayfire_toplevel_view view) - { - auto toplevel = view->toplevel(); - - if (!toplevel->get_data()) - { - toplevel->store_data(std::make_unique(view)); - } - - auto deco = toplevel->get_data(); - auto& pending = toplevel->pending(); - pending.margins = deco->get_margins(pending); - - if (!pending.fullscreen && !pending.tiled_edges) - { - toplevel->pending().geometry = wf::expand_geometry_by_margins( - toplevel->pending().geometry, pending.margins); - } - } - - void remove_decoration(wayfire_toplevel_view view) - { - view->toplevel()->erase_data(); - auto& pending = view->toplevel()->pending(); - if (!pending.fullscreen && !pending.tiled_edges) - { - pending.geometry = wf::shrink_geometry_by_margins(pending.geometry, pending.margins); - } - - pending.margins = {0, 0, 0, 0}; - - std::string custom_data_name = "wf-decoration-shadow-margin"; - if (view->has_data(custom_data_name)) - { - view->erase_data(custom_data_name); - } - } - - void update_view_decoration(wayfire_view view) - { - if (auto toplevel = wf::toplevel_cast(view)) - { - if (!toplevel) - { - return; - } - - if (!toplevel->toplevel()->get_data() && (always_decorate.matches(view) || - (should_decorate_view(toplevel) - && - !ignore_views.matches(view)))) - { - adjust_new_decorations(toplevel); - } else if ((!always_decorate.matches(view) && - (!should_decorate_view(toplevel) || ignore_views.matches(view)))) - { - remove_decoration(toplevel); - } - - wf::get_core().tx_manager->schedule_object(toplevel->toplevel()); - } - } -}; -} -} - -DECLARE_WAYFIRE_PLUGIN(wf::pixdecor::wayfire_pixdecor); diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-subsurface.cpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-subsurface.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-subsurface.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-subsurface.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,699 +0,0 @@ -#include "wayfire/geometry.hpp" -#include "wayfire/scene-input.hpp" -#include "wayfire/scene-operations.hpp" -#include "wayfire/scene-render.hpp" -#include "wayfire/scene.hpp" -#include "wayfire/signal-provider.hpp" -#include "wayfire/toplevel.hpp" -#include -#define GLM_FORCE_RADIANS -#include - -#include - -#include -#include -#include -#include -#include -#include -#include "deco-subsurface.hpp" -#include "deco-layout.hpp" -#include "deco-theme.hpp" -#include -#include -#include -#include - -#include - -#include -#include "shade.hpp" - - -namespace wf -{ -namespace pixdecor -{ -wf::option_wrapper_t effect_color{"pixdecor/effect_color"}; -wf::option_wrapper_t shadow_radius{"pixdecor/shadow_radius"}; -wf::option_wrapper_t titlebar_opt{"pixdecor/titlebar"}; -wf::option_wrapper_t csd_titlebar_height{"pixdecor/csd_titlebar_height"}; -wf::option_wrapper_t enable_shade{"pixdecor/enable_shade"}; -wf::option_wrapper_t title_font{"pixdecor/title_font"}; -wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; -wf::option_wrapper_t effect_type{"pixdecor/effect_type"}; -wf::option_wrapper_t maximized_borders{"pixdecor/maximized_borders"}; -wf::option_wrapper_t maximized_shadows{"pixdecor/maximized_shadows"}; -wf::option_wrapper_t title_text_align{"pixdecor/title_text_align"}; - -class simple_decoration_node_t : public wf::scene::node_t, public wf::pointer_interaction_t, - public wf::touch_interaction_t -{ - std::weak_ptr _view; - wf::signal::connection_t title_set = - [=] (wf::view_title_changed_signal *ev) - { - if (auto view = _view.lock()) - { - view->damage(); - } - }; - - void update_title(int width, int height, int t_width, int border, int buttons_width, double scale) - { - if (auto view = _view.lock()) - { - int target_width = width * scale; - int target_height = height * scale; - - if ((int(title_text_align) != title_texture.title_text_align) || - (view->get_title() != title_texture.current_text) || - (target_width != title_texture.tex.get_size().width) || - (std::string(title_font) != title_texture.title_font_string) || - (target_height != title_texture.tex.get_size().height) || - (view->activated != title_texture.rendered_for_activated_state)) - { - auto surface = theme.render_text(view->get_title(), - target_width, target_height, t_width, border, buttons_width, view->activated); - title_texture.tex = owned_texture_t{surface}; - cairo_surface_destroy(surface); - title_texture.title_font_string = title_font; - title_texture.current_text = view->get_title(); - title_texture.title_text_align = int(title_text_align); - title_texture.rendered_for_activated_state = view->activated; - } - } - } - - struct - { - wf::owned_texture_t tex; - std::string current_text = ""; - bool rendered_for_activated_state = false; - int title_text_align = int(title_text_align); - std::string title_font_string = title_font; - } title_texture; - - public: - pixdecor_theme_t theme; - pixdecor_layout_t layout; - wf::region_t cached_region; - - wf::dimensions_t size; - - int current_thickness; - int current_titlebar; - wf::pointf_t current_cursor_position; - - simple_decoration_node_t(wayfire_toplevel_view view) : - node_t(false), - theme{}, - layout{theme, [=] (wlr_box box) { wf::scene::damage_node(shared_from_this(), box + get_offset()); }} - { - this->_view = view->weak_from_this(); - view->connect(&title_set); - - // make sure to hide frame if the view is fullscreen - update_decoration_size(); - - current_cursor_position.x = current_cursor_position.y = FLT_MIN; - } - - ~simple_decoration_node_t() - { - remove_shade_transformers(); - } - - wf::point_t get_offset() - { - auto view = _view.lock(); - if (view && view->pending_tiled_edges() && !maximized_borders && !maximized_shadows) - { - return {0, -current_titlebar}; - } - - return {-current_thickness, -current_titlebar}; - } - - void render_title(const wf::scene::render_instruction_t& data, - const wf::geometry_t& geometry, int t_width, int border, int buttons_width) - { - update_title(geometry.width, geometry.height, t_width, border, buttons_width, data.target.scale); - OpenGL::render_texture(wf::gles_texture_t{title_texture.tex.get_texture()}, data.target, geometry, - glm::vec4(1.0f), OpenGL::RENDER_FLAG_CACHED); - - data.pass->custom_gles_subpass(data.target,[&] - { - for (auto& box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::draw_cached(); - } - }); - - OpenGL::clear_cached(); - } - - void render_region(const wf::scene::render_instruction_t& data, wf::point_t origin) - { - int border = theme.get_border_size(); - wlr_box geometry{origin.x, origin.y, size.width, size.height}; - - bool activated = false; - bool maximized = false; - if (auto view = _view.lock()) - { - activated = view->activated; - maximized = view->pending_tiled_edges(); - } - - auto renderables = layout.get_renderable_areas(); - auto offset = - wf::point_t{origin.x, - origin.y - - ((maximized && (!maximized_shadows || !maximized_borders)) ? -border / 2 : border / 4)}; - - wf::gles::run_in_context([&] - { - wf::gles::bind_render_buffer(data.target); - - theme.render_background(data, geometry, activated, current_cursor_position); - - if (!titlebar_opt) - { - return; - } - - int buttons_width = 0; - for (auto item : renderables) - { - if (item->get_type() != DECORATION_AREA_TITLE) - { - buttons_width += item->get_geometry().width; - } - } - - /* Draw title & buttons */ - auto title_border = border + ((std::string(overlay_engine) == "rounded_corners" && - (!maximized || maximized_shadows)) ? int(shadow_radius) * 2 : 0); - for (auto item : renderables) - { - if (item->get_type() == DECORATION_AREA_TITLE) - { - render_title(data, - item->get_geometry() + offset, size.width - border * 2, title_border, buttons_width); - } else // button - { - item->as_button().render(data, - item->get_geometry() + origin); - } - } - }); - } - - std::optional find_node_at(const wf::pointf_t& at) override - { - bool maximized = false; - if (auto view = _view.lock()) - { - maximized = view->pending_tiled_edges(); - } - - int border = theme.get_border_size(); - int r = - (std::string(overlay_engine) == "rounded_corners" && - (!maximized || (maximized && maximized_shadows))) ? int(shadow_radius) * 2 : 0; - r -= MIN_RESIZE_HANDLE_SIZE - std::min(border, MIN_RESIZE_HANDLE_SIZE); - wf::pointf_t local = at - wf::pointf_t{get_offset()}; - if (auto view = _view.lock()) - { - wf::geometry_t g = view->get_geometry(); - g.x = g.y = 0; - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{-r, -r, -r, -r}); - wf::region_t deco_region{g}; - g = wf::expand_geometry_by_margins(g, wf::decoration_margins_t{-border, -border, -border, - -theme.get_title_height() - border}); - wf::region_t view_region{g}; - deco_region ^= view_region; - if (deco_region.contains_pointf(local)) - { - return wf::scene::input_node_t{ - .node = this, - .local_coords = local, - }; - } - } - - return {}; - } - - pointer_interaction_t& pointer_interaction() override - { - return *this; - } - - touch_interaction_t& touch_interaction() override - { - return *this; - } - - class decoration_render_instance_t : public wf::scene::render_instance_t - { - simple_decoration_node_t *self; - wf::scene::damage_callback push_damage; - - wf::signal::connection_t on_surface_damage = - [=] (wf::scene::node_damage_signal *data) - { - push_damage(data->region); - }; - - public: - decoration_render_instance_t(simple_decoration_node_t *self, wf::scene::damage_callback push_damage) - { - this->self = self; - this->push_damage = push_damage; - self->connect(&on_surface_damage); - } - - void schedule_instructions(std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) override - { - auto our_region = self->cached_region + self->get_offset(); - wf::region_t our_damage = damage & our_region; - if (!our_damage.empty()) - { - instructions.push_back(wf::scene::render_instruction_t{ - .instance = this, - .target = target, - .damage = std::move(our_damage), - }); - } - } - - void render(const wf::scene::render_instruction_t& data) override - { - auto offset = self->get_offset(); - wlr_box rectangle{offset.x, offset.y, self->size.width, self->size.height}; - bool activated = false; - bool maximized = false; - if (auto view = self->_view.lock()) - { - activated = view->activated; - maximized = maximized_shadows ? false : view->pending_tiled_edges(); - } - - if ((std::string(effect_type) != "none") || (std::string(overlay_engine) != "none")) - { - self->theme.smoke.step_effect(data, rectangle, std::string(effect_type) == "ink", - self->current_cursor_position, self->theme.get_decor_color(activated), effect_color, - self->theme.get_title_height(), self->theme.get_border_size(), - (std::string(overlay_engine) == "rounded_corners" && !maximized) ? shadow_radius : 0); - } - - self->render_region(data, offset); - } - }; - - void gen_render_instances(std::vector& instances, - wf::scene::damage_callback push_damage, wf::output_t *output = nullptr) override - { - instances.push_back(std::make_unique(this, push_damage)); - } - - wf::geometry_t get_bounding_box() override - { - return wf::construct_box(get_offset(), size); - } - - /* wf::compositor_surface_t implementation */ - void handle_pointer_enter(wf::pointf_t point) override - { - point -= wf::pointf_t{get_offset()}; - layout.handle_motion(point.x, point.y); - } - - void handle_pointer_leave() override - { - layout.handle_focus_lost(); - current_cursor_position.x = current_cursor_position.y = FLT_MIN; - } - - void handle_pointer_motion(wf::pointf_t to, uint32_t) override - { - to -= wf::pointf_t{get_offset()}; - handle_action(layout.handle_motion(to.x, to.y)); - current_cursor_position = to; - } - - void handle_pointer_button(const wlr_pointer_button_event& ev) override - { - if (ev.button != BTN_LEFT) - { - return; - } - - handle_action(layout.handle_press_event(ev.state == WL_POINTER_BUTTON_STATE_PRESSED)); - } - - void handle_pointer_axis(const wlr_pointer_axis_event& ev) override - { - if (ev.orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) - { - handle_action(layout.handle_axis_event(ev.delta)); - } - } - - void pop_transformer(wayfire_view view) - { - if (view->get_transformed_node()->get_transformer(shade_transformer_name)) - { - view->get_transformed_node()->rem_transformer(shade_transformer_name); - } - } - - void remove_shade_transformers() - { - for (auto& view : wf::get_core().get_all_views()) - { - pop_transformer(view); - } - } - - std::shared_ptr ensure_transformer(wayfire_view view, int titlebar_height) - { - auto tmgr = view->get_transformed_node(); - if (auto tr = tmgr->get_transformer(shade_transformer_name)) - { - return tr; - } - - auto node = std::make_shared(view, titlebar_height); - tmgr->add_transformer(node, wf::TRANSFORMER_2D, shade_transformer_name); - auto tr = tmgr->get_transformer(shade_transformer_name); - - return tr; - } - - void init_shade(wayfire_view view, bool shade, int titlebar_height) - { - if (!bool(enable_shade)) - { - return; - } - - if (shade) - { - if (view && view->is_mapped()) - { - auto tr = ensure_transformer(view, titlebar_height); - tr->set_titlebar_height(titlebar_height); - tr->init_animation(shade); - } - } else - { - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - tr->set_titlebar_height(titlebar_height); - tr->init_animation(shade); - } - } - } - - void handle_action(pixdecor_layout_t::action_response_t action) - { - if (auto view = _view.lock()) - { - switch (action.action) - { - case DECORATION_ACTION_MOVE: - return wf::get_core().default_wm->move_request(view); - - case DECORATION_ACTION_RESIZE: - return wf::get_core().default_wm->resize_request(view, action.edges); - - case DECORATION_ACTION_CLOSE: - return view->close(); - - case DECORATION_ACTION_TOGGLE_MAXIMIZE: - if (view->pending_tiled_edges()) - { - return wf::get_core().default_wm->tile_request(view, 0); - } else - { - return wf::get_core().default_wm->tile_request(view, wf::TILED_EDGES_ALL); - } - - break; - - case DECORATION_ACTION_SHADE: - init_shade(view, true, current_titlebar); - break; - - case DECORATION_ACTION_UNSHADE: - init_shade(view, false, current_titlebar); - break; - - case DECORATION_ACTION_MINIMIZE: - return wf::get_core().default_wm->minimize_request(view, true); - break; - - default: - break; - } - } - } - - void handle_touch_down(uint32_t time_ms, int finger_id, wf::pointf_t position) override - { - handle_touch_motion(time_ms, finger_id, position); - handle_action(layout.handle_press_event()); - } - - void handle_touch_up(uint32_t time_ms, int finger_id, wf::pointf_t lift_off_position) override - { - handle_action(layout.handle_press_event(false)); - layout.handle_focus_lost(); - } - - void handle_touch_motion(uint32_t time_ms, int finger_id, wf::pointf_t position) override - { - position -= wf::pointf_t{get_offset()}; - layout.handle_motion(position.x, position.y); - current_cursor_position = position; - } - - void recreate_frame() - { - update_decoration_size(); - if (auto view = _view.lock()) - { - auto size = wf::dimensions(view->get_pending_geometry()); - layout.resize(size.width, size.height); - wf::get_core().tx_manager->schedule_object(view->toplevel()); - } - } - - void resize(wf::dimensions_t dims) - { - if (auto view = _view.lock()) - { - theme.set_maximize(view->pending_tiled_edges()); - layout.set_maximize(maximized_shadows ? 0 : view->pending_tiled_edges()); - view->damage(); - size = dims; - layout.resize(size.width, size.height); - if (!view->toplevel()->current().fullscreen) - { - this->cached_region = layout.calculate_region(); - } - - view->damage(); - } - } - - void update_decoration_size() - { - if (auto view = _view.lock()) - { - view->damage(); - bool fullscreen = view->toplevel()->pending().fullscreen; - bool maximized = view->toplevel()->pending().tiled_edges; - if (fullscreen) - { - current_thickness = 0; - current_titlebar = 0; - this->cached_region.clear(); - } else - { - int shadow_thickness = std::string(overlay_engine) == "rounded_corners" && - (!maximized || (maximized && maximized_shadows)) ? int(shadow_radius) * 2 : 0; - - current_thickness = theme.get_border_size() + shadow_thickness; - current_titlebar = theme.get_title_height() + - ((maximized && !titlebar_opt && !maximized_borders && - !maximized_shadows) ? 0 : current_thickness); - this->cached_region = layout.calculate_region(); - } - - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - tr->set_titlebar_height(current_titlebar); - } - - view->damage(); - } - } -}; - -simple_decorator_t::simple_decorator_t(wayfire_toplevel_view view) -{ - this->view = view; - this->shadow_thickness = 0; - deco = std::make_shared(view); - deco->resize(wf::dimensions(view->get_pending_geometry())); - wf::scene::add_back(view->get_surface_root_node(), deco); - - view->connect(&on_view_activated); - view->connect(&on_view_geometry_changed); - view->connect(&on_view_fullscreen); - view->connect(&on_view_tiled); - - on_view_activated = [this] (auto) - { - wf::scene::damage_node(deco, deco->get_bounding_box()); - }; - - on_view_geometry_changed = [this] (auto) - { - deco->resize(wf::dimensions(this->view->get_geometry())); - wf::get_core().tx_manager->schedule_object(this->view->toplevel()); - }; - - on_view_tiled = [this] (auto) - { - deco->resize(wf::dimensions(this->view->get_geometry())); - wf::get_core().tx_manager->schedule_object(this->view->toplevel()); - }; - - on_view_fullscreen = [this] (auto) - { - if (!this->view->toplevel()->pending().fullscreen) - { - deco->resize(wf::dimensions(this->view->get_geometry())); - wf::get_core().tx_manager->schedule_object(this->view->toplevel()); - } - }; -} - -simple_decorator_t::~simple_decorator_t() -{ - wf::scene::remove_child(deco); - deco.reset(); -} - -int simple_decorator_t::get_titlebar_height() -{ - return deco->current_titlebar; -} - -void simple_decorator_t::recreate_frame() -{ - deco->recreate_frame(); -} - -void simple_decorator_t::update_decoration_size() -{ - deco->update_decoration_size(); -} - -void simple_decorator_t::update_colors() -{ - deco->theme.update_colors(); -} - -void simple_decorator_t::effect_updated() -{ - deco->theme.smoke.effect_updated(); -} - -wf::decoration_margins_t simple_decorator_t::get_margins(const wf::toplevel_state_t& state) -{ - if (state.fullscreen) - { - return {0, 0, 0, 0}; - } - - deco->theme.set_maximize(state.tiled_edges); - - this->shadow_thickness = std::string(overlay_engine) == "rounded_corners" && - (!state.tiled_edges || (state.tiled_edges && maximized_shadows)) ? int(shadow_radius) * 2 : 0; - - int thickness = deco->theme.get_border_size() + this->shadow_thickness; - int titlebar = deco->theme.get_title_height() + - ((state.tiled_edges && !titlebar_opt && !maximized_borders && !maximized_shadows) ? 0 : thickness); - if (state.tiled_edges && !maximized_borders) - { - if (maximized_shadows) - { - if (!titlebar_opt) - { - titlebar = thickness; - } - } else - { - thickness = 0; - } - } - - double shade_progress = 0.0; - if (auto tr = - view->get_transformed_node()->get_transformer( - shade_transformer_name)) - { - tr->set_titlebar_height(titlebar); - shade_progress = tr->progression.shade; - } - - if (view->has_data(custom_data_name)) - { - view->get_data(custom_data_name)->set_margins( - {shadow_thickness, shadow_thickness, shadow_thickness, - shadow_thickness + - int((view->get_geometry().height - shadow_thickness - titlebar) * shade_progress)}); - } else - { - view->store_data(std::make_unique(), custom_data_name); - view->get_data(custom_data_name)->set_margins( - {shadow_thickness, shadow_thickness, shadow_thickness, - shadow_thickness + - int((view->get_geometry().height - shadow_thickness - titlebar) * shade_progress)}); - } - - return wf::decoration_margins_t{ - .left = thickness, - .right = thickness, - .bottom = thickness, - .top = titlebar, - }; -} - -void simple_decorator_t::update_animation() -{ - auto margins = get_margins(view->toplevel()->current()); - auto bbox = deco->get_bounding_box(); - - wf::region_t region; - region |= wlr_box{bbox.x, bbox.y, bbox.width, margins.top}; - region |= wlr_box{bbox.x, bbox.y, margins.left, bbox.height}; - region |= wlr_box{bbox.x, bbox.y + bbox.height - margins.bottom, bbox.width, margins.bottom}; - region |= wlr_box{bbox.x + bbox.width - margins.right, bbox.y, margins.right, bbox.height}; - wf::scene::damage_node(deco, region); -} -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-subsurface.hpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-subsurface.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-subsurface.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-subsurface.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,62 +0,0 @@ -#ifndef DECO_SUBSURFACE_HPP -#define DECO_SUBSURFACE_HPP - -#include "wayfire/object.hpp" -#include "wayfire/toplevel.hpp" -#include -#include -#include - -static std::string custom_data_name = "wf-decoration-shadow-margin"; - -class wf_shadow_margin_t : public wf::custom_data_t -{ - public: - wf::decoration_margins_t get_margins() - { - return margins; - } - - void set_margins(wf::decoration_margins_t margins) - { - this->margins = margins; - } - - private: - wf::decoration_margins_t margins = {0, 0, 0, 0}; -}; - -namespace wf -{ -namespace pixdecor -{ -class simple_decoration_node_t; -/** - * A decorator object attached as custom data to a toplevel object. - */ -class simple_decorator_t : public wf::custom_data_t -{ - wayfire_toplevel_view view; - std::shared_ptr deco; - - wf::signal::connection_t on_view_activated; - wf::signal::connection_t on_view_geometry_changed; - wf::signal::connection_t on_view_fullscreen; - wf::signal::connection_t on_view_tiled; - - public: - void update_colors(); - void effect_updated(); - void recreate_frame(); - void update_decoration_size(); - simple_decorator_t(wayfire_toplevel_view view); - ~simple_decorator_t(); - wf::decoration_margins_t get_margins(const wf::toplevel_state_t& state); - int get_titlebar_height(); - void update_animation(); - int shadow_thickness; -}; -} -} - -#endif /* end of include guard: DECO_SUBSURFACE_HPP */ diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-theme.cpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-theme.cpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-theme.cpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-theme.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,367 +0,0 @@ -#include "deco-theme.hpp" -#include -#include -#include -#include -#include - -namespace wf -{ -namespace pixdecor -{ -wf::option_wrapper_t border_size{"pixdecor/border_size"}; -wf::option_wrapper_t titlebar{"pixdecor/titlebar"}; -wf::option_wrapper_t fg_color{"pixdecor/fg_color"}; -wf::option_wrapper_t bg_color{"pixdecor/bg_color"}; -wf::option_wrapper_t fg_text_color{"pixdecor/fg_text_color"}; -wf::option_wrapper_t bg_text_color{"pixdecor/bg_text_color"}; -wf::option_wrapper_t button_minimize_image{"pixdecor/button_minimize_image"}; -wf::option_wrapper_t button_maximize_image{"pixdecor/button_maximize_image"}; -wf::option_wrapper_t button_close_image{"pixdecor/button_close_image"}; -wf::option_wrapper_t button_color{"pixdecor/button_color"}; -wf::option_wrapper_t button_line_thickness{"pixdecor/button_line_thickness"}; -/** Create a new theme with the default parameters */ -pixdecor_theme_t::pixdecor_theme_t() -{ - gs = g_settings_new("org.gnome.desktop.interface"); - - // read initial colours - update_colors(); -} - -pixdecor_theme_t::~pixdecor_theme_t() -{ - g_object_unref(gs); -} - -void pixdecor_theme_t::update_colors(void) -{ - fg = wf::color_t(fg_color); - bg = wf::color_t(bg_color); - fg_text = wf::color_t(fg_text_color); - bg_text = wf::color_t(bg_text_color); -} - -/** - * @return A PangoFontDescription representing either a provided font from - * the Title Font option or the system font, scaled by the text-scaling-factor GSetting. - */ -PangoFontDescription*pixdecor_theme_t::create_font_description() -{ - GSettings *gs = g_settings_new("org.gnome.desktop.interface"); - - std::string title_font_val(title_font); - bool using_system_font{}; - - if (title_font_val.empty()) - { - char *font = g_settings_get_string(gs, "font-name"); - title_font_val = font; - using_system_font = true; - g_free(font); - } - - PangoFontDescription *font_desc = pango_font_description_from_string(title_font_val.c_str()); - int font_size = pango_font_description_get_size(font_desc); - bool font_size_absolute; - - // font size will be 0 if nothing is specified - grab from system font if this is the case - // if the font is the system font, then just pray it works - if (!font_size && !using_system_font) - { - char *font = g_settings_get_string(gs, "font-name"); - PangoFontDescription *sys_font_desc = pango_font_description_from_string(font); - - font_size = pango_font_description_get_size(sys_font_desc); - font_size_absolute = pango_font_description_get_size_is_absolute(sys_font_desc); - - pango_font_description_free(sys_font_desc); - g_free(font); - } else - { - font_size_absolute = pango_font_description_get_size_is_absolute(font_desc); - } - - // scale the font size if we got it by text-scaling-factor - if (font_size) - { - double scaling_factor = g_settings_get_double(gs, "text-scaling-factor"); - if (!scaling_factor) // should default to 1.0, but better safe than sorry - { - scaling_factor = 1.0; - } - - if (font_size_absolute) - { - pango_font_description_set_absolute_size(font_desc, font_size * scaling_factor); - } else - { - pango_font_description_set_size(font_desc, font_size * scaling_factor); - } - } - - g_object_unref(gs); - return font_desc; -} - -/** - * @return A PangoFontDescription from create_font_description(), - * originating from a global, internally managed instance, freeing the data upon exit. - * It will also be updated with changes to the Title Font option. - */ -PangoFontDescription*pixdecor_theme_t::get_font_description() -{ - static std::unique_ptr font_desc( - create_font_description(), &pango_font_description_free); - - static std::once_flag once_flag; - std::call_once(once_flag, [&] - { - title_font.set_callback([&] - { - font_desc.reset(create_font_description()); - }); - }); - - return font_desc.get(); -} - -/** @return The available height for displaying the title */ -int pixdecor_theme_t::get_font_height_px() -{ - PangoFontDescription *font_desc = get_font_description(); - int font_height = pango_font_description_get_size(font_desc); - - if (!pango_font_description_get_size_is_absolute(font_desc)) - { - font_height *= 4; - font_height /= 3; - } - - return font_height / PANGO_SCALE; -} - -int pixdecor_theme_t::get_title_height() -{ - int height = get_font_height_px(); - height *= 3; - height /= 2; - height += 8; - if (height < MIN_BAR_HEIGHT) - { - height = MIN_BAR_HEIGHT; - } - - return titlebar ? height + ((maximized && !maximized_borders) ? border_size : 0) : 0; -} - -/** @return The available border for resizing */ -int pixdecor_theme_t::get_border_size() const -{ - return (!maximized_borders && maximized) ? 0 : border_size; -} - -/** @return The input area for resizing */ -int pixdecor_theme_t::get_input_size() const -{ - return std::max(get_border_size(), MIN_RESIZE_HANDLE_SIZE); -} - -wf::color_t pixdecor_theme_t::get_decor_color(bool active) const -{ - return active ? fg : bg; -} - -void pixdecor_theme_t::set_maximize(bool state) -{ - maximized = state; -} - -/** - * Fill the given rectangle with the background color(s). - * - * @param fb The target framebuffer, must have been bound already - * @param rectangle The rectangle to redraw. - * @param scissor The GL scissor rectangle to use. - * @param active Whether to use active or inactive colors - */ -void pixdecor_theme_t::render_background(const wf::scene::render_instruction_t& data, - wf::geometry_t rectangle, bool active, wf::pointf_t p) -{ - if ((std::string(effect_type) == "none") && (std::string(overlay_engine) == "none")) - { - data.pass->custom_gles_subpass(data.target,[&] - { - for (auto& box : data.damage) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::render_rectangle(rectangle, get_decor_color(active), wf::gles::render_target_orthographic_projection(data.target)); - } - }); - } else - { - smoke.render_effect(data, rectangle); - } -} - -/** - * Render the given text on a cairo_surface_t with the given size. - * The caller is responsible for freeing the memory afterwards. - */ -cairo_surface_t*pixdecor_theme_t::render_text(std::string text, - int width, int height, int t_width, int border, int buttons_width, bool active) -{ - const auto format = CAIRO_FORMAT_ARGB32; - auto surface = cairo_image_surface_create(format, width, height); - - if (height == 0) - { - return surface; - } - - auto cr = cairo_create(surface); - - PangoFontDescription *font_desc; - PangoLayout *layout; - int x, w, h; - - // render text - font_desc = get_font_description(); - - layout = pango_cairo_create_layout(cr); - pango_layout_set_font_description(layout, font_desc); - pango_layout_set_text(layout, text.c_str(), text.size()); - cairo_set_source_rgba(cr, active ? fg_text.r : bg_text.r, active ? fg_text.g : bg_text.g, - active ? fg_text.b : bg_text.b, 1); - pango_layout_get_pixel_size(layout, &w, &h); - switch (int(title_text_align)) - { - // left - case 0: - x = border; - break; - - // right - case 2: - x = t_width - (w + buttons_width + border); - break; - - // center - case 1: - default: - x = (t_width - w) / 2; - break; - } - - cairo_translate(cr, x, (height - h) / 2); - pango_cairo_show_layout(cr, layout); - g_object_unref(layout); - cairo_destroy(cr); - - return surface; -} - -cairo_surface_t*pixdecor_theme_t::get_button_surface(button_type_t button, - const button_state_t& state, bool active) const -{ - cairo_surface_t *button_surface = NULL; - - switch (button) - { - case BUTTON_CLOSE: - if (!std::string(button_close_image).empty()) - { - button_surface = cairo_image_surface_create_from_png(std::string(button_close_image).c_str()); - } - - break; - - case BUTTON_TOGGLE_MAXIMIZE: - if (!std::string(button_maximize_image).empty()) - { - button_surface = cairo_image_surface_create_from_png(std::string(button_maximize_image).c_str()); - } - - break; - - case BUTTON_MINIMIZE: - if (!std::string(button_minimize_image).empty()) - { - button_surface = cairo_image_surface_create_from_png(std::string(button_minimize_image).c_str()); - } - - break; - - default: - break; - } - - if (button_surface && (cairo_surface_status(button_surface) == CAIRO_STATUS_SUCCESS)) - { - return button_surface; - } - - auto w = state.width; - auto h = state.height; - - button_surface = cairo_image_surface_create( - CAIRO_FORMAT_ARGB32, w, h); - - auto cr = cairo_create(button_surface); - cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); - - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - cairo_set_source_rgba(cr, 0, 0, 0, 0); - cairo_rectangle(cr, 0, 0, w, h); - cairo_fill(cr); - - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - - /** Draw the button */ - cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_source_rgba(cr, - wf::color_t(button_color).r, - wf::color_t(button_color).g, - wf::color_t(button_color).b, - wf::color_t(button_color).a); - double line_width = button_line_thickness; - switch (button) - { - case BUTTON_CLOSE: - cairo_set_line_width(cr, line_width * state.border); - cairo_move_to(cr, 1.0 * w / 4.0, - 1.0 * h / 4.0); - cairo_line_to(cr, 3.0 * w / 4.0, - 3.0 * h / 4.0); - cairo_move_to(cr, 3.0 * w / 4.0, - 1.0 * h / 4.0); - cairo_line_to(cr, 1.0 * w / 4.0, - 3.0 * h / 4.0); - cairo_stroke(cr); - break; - - case BUTTON_TOGGLE_MAXIMIZE: - cairo_set_line_width(cr, line_width * state.border); - cairo_rectangle(cr, w / 4.0, h / 4.0, w / 2.0, h / 2.0); - cairo_stroke(cr); - break; - - case BUTTON_MINIMIZE: - cairo_set_line_width(cr, line_width * state.border); - cairo_move_to(cr, 1.0 * w / 4.0, - 3.0 * h / 4.0); - cairo_line_to(cr, 3.0 * w / 4.0, - 3.0 * h / 4.0); - cairo_stroke(cr); - break; - - default: - assert(false); - } - - cairo_destroy(cr); - - return button_surface; -} -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-theme.hpp wayfire-plugins-extra/subprojects/pixdecor/src/deco-theme.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/deco-theme.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/deco-theme.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,102 +0,0 @@ -#pragma once -#include -#include -#include "deco-button.hpp" -#include "deco-effects.hpp" - -#define MIN_RESIZE_HANDLE_SIZE 5 -#define LARGE_ICON_THRESHOLD 20 -#define MIN_BAR_HEIGHT 20 - -namespace wf -{ -namespace pixdecor -{ -/** - * A class which manages the outlook of decorations. - * It is responsible for determining the background colors, sizes, etc. - */ -class pixdecor_theme_t -{ - public: - wf::option_wrapper_t title_font{"pixdecor/title_font"}; - wf::option_wrapper_t overlay_engine{"pixdecor/overlay_engine"}; - wf::option_wrapper_t effect_type{"pixdecor/effect_type"}; - wf::option_wrapper_t maximized_borders{"pixdecor/maximized_borders"}; - wf::option_wrapper_t maximized_shadows{"pixdecor/maximized_shadows"}; - wf::option_wrapper_t title_text_align{"pixdecor/title_text_align"}; - /** Create a new theme with the default parameters */ - pixdecor_theme_t(); - ~pixdecor_theme_t(); - - /** @return The height of the system font in pixels */ - int get_font_height_px(); - /** @return The available height for displaying the title */ - int get_title_height(); - /** @return The available border for rendering */ - int get_border_size() const; - /** @return The available border for resizing */ - int get_input_size() const; - /** @return The decoration color */ - wf::color_t get_decor_color(bool active) const; - PangoFontDescription *create_font_description(); - PangoFontDescription *get_font_description(); - - void update_colors(void); - - /** - * Fill the given rectangle with the background color(s). - * - * @param fb The target framebuffer, must have been bound already. - * @param rectangle The rectangle to redraw. - * @param scissor The GL scissor rectangle to use. - * @param active Whether to use active or inactive colors - */ - void render_background(const wf::scene::render_instruction_t& data, - wf::geometry_t rectangle, bool active, wf::pointf_t p); - - /** - * Render the given text on a cairo_surface_t with the given size. - * The caller is responsible for freeing the memory afterwards. - */ - cairo_surface_t *render_text(std::string text, int width, int height, int t_width, int border, - int buttons_width, bool active); - - struct button_state_t - { - /** Button width */ - double width; - /** Button height */ - double height; - /** Button outline size */ - double border; - /* Hovering... */ - bool hover; - }; - - /** background effects */ - smoke_t smoke; - - /** - * Get the icon for the given button. - * The caller is responsible for freeing the memory afterwards. - * - * @param button The button type. - * @param state The button state. - */ - cairo_surface_t *get_button_surface(button_type_t button, - const button_state_t& state, bool active) const; - - void set_maximize(bool state); - - private: - - GSettings *gs; - wf::color_t fg; - wf::color_t bg; - wf::color_t fg_text; - wf::color_t bg_text; - bool maximized; -}; -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/meson.build wayfire-plugins-extra/subprojects/pixdecor/src/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/meson.build 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,5 +0,0 @@ -pixdecor = shared_module('pixdecor', - ['decoration.cpp', 'deco-subsurface.cpp', 'deco-button.cpp', 'deco-layout.cpp', 'deco-theme.cpp', 'deco-effects.cpp'], - dependencies: [wayfire], - install: true, - install_dir: join_paths(get_option('libdir'), 'wayfire')) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/shade.hpp wayfire-plugins-extra/subprojects/pixdecor/src/shade.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/shade.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/shade.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,290 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "deco-subsurface.hpp" - -const std::string shade_transformer_name = "pixdecor_shade"; - -namespace wf -{ -namespace pixdecor -{ -using namespace wf::scene; -using namespace wf::animation; -class shade_animation_t : public duration_t -{ - public: - using duration_t::duration_t; - timed_transition_t shade{*this}; -}; -class pixdecor_shade : public wf::scene::view_2d_transformer_t -{ - nonstd::observer_ptr deco = nullptr; - wayfire_view view; - wf::output_t *output; - int titlebar_height; - wf::option_wrapper_t shade_duration{"pixdecor/shade_duration"}; - - public: - bool last_direction; - shade_animation_t progression{shade_duration}; - class simple_node_render_instance_t : public wf::scene::transformer_render_instance_t - { - wf::signal::connection_t on_node_damaged = - [=] (node_damage_signal *ev) - { - push_to_parent(ev->region); - }; - - pixdecor_shade *self; - wayfire_view view; - damage_callback push_to_parent; - - public: - simple_node_render_instance_t(pixdecor_shade *self, damage_callback push_damage, - wayfire_view view) : wf::scene::transformer_render_instance_t(self, - push_damage, - view->get_output()) - { - this->self = self; - this->view = view; - this->push_to_parent = push_damage; - self->connect(&on_node_damaged); - } - - ~simple_node_render_instance_t() - {} - - void schedule_instructions( - std::vector& instructions, - const wf::render_target_t& target, wf::region_t& damage) - { - // We want to render ourselves only, the node does not have children - instructions.push_back(render_instruction_t{ - .instance = this, - .target = target, - .damage = damage & self->get_bounding_box(), - }); - } - - void render(const wf::scene::render_instruction_t& data) - { - auto src_box = self->get_children_bounding_box(); - gl_geometry src_geometry = {(float)src_box.x, (float)src_box.y, - (float)src_box.x + src_box.width, (float)src_box.y + src_box.height}; - auto src_tex = wf::scene::transformer_render_instance_t::get_texture( - 1.0); - auto shade_region = data.damage; - int height = src_box.height; - auto titlebar = self->titlebar_height + self->get_shadow_margin(); - src_box.y += self->titlebar_height; - src_box.height *= 1.0 - - (self->progression.shade * - ((src_box.height - titlebar) / float(src_box.height))); - auto progress_height = src_box.height; - shade_region &= wf::region_t{src_box}; - wf::gles::run_in_context([&] - { - wf::gles::bind_render_buffer(data.target); - data.pass->custom_gles_subpass(data.target,[&] - { - for (const auto& box : shade_region) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::render_transformed_texture(wf::gles_texture_t{src_tex}, - {src_geometry.x1, src_geometry.y1 - (height - progress_height), src_geometry.x2, - src_geometry.y2 - (height - progress_height)}, {}, - wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); - } - }); - - shade_region = data.damage; - src_box = self->get_children_bounding_box(); - src_box.height = self->titlebar_height; - shade_region &= wf::region_t{src_box}; - //for (const auto& box : shade_region) - //{ - // target.logic_scissor(wlr_box_from_pixman_box(box)); - data.pass->custom_gles_subpass(data.target,[&] - { - for (const auto& box : shade_region) - { - wf::gles::render_target_logic_scissor(data.target, wlr_box_from_pixman_box(box)); - OpenGL::render_transformed_texture(wf::gles_texture_t{src_tex}, src_geometry, {}, - wf::gles::render_target_orthographic_projection(data.target), glm::vec4(1.0), 0); - } - }); - - }); - } - }; - - pixdecor_shade(wayfire_view view, int titlebar_height) : wf::scene::view_2d_transformer_t(view) - { - this->view = view; - this->output = view->get_output(); - this->titlebar_height = titlebar_height; - this->progression.shade.set(0.0, 1.0); - if (output) - { - output->render->add_effect(&pre_hook, wf::OUTPUT_EFFECT_PRE); - } - - if (auto toplevel = wf::toplevel_cast(view)) - { - this->deco = toplevel->toplevel()->get_data(); - } - } - - void pop_transformer(wayfire_view view) - { - if (view->get_transformed_node()->get_transformer(shade_transformer_name)) - { - view->get_transformed_node()->rem_transformer(shade_transformer_name); - } - - if (!deco && view->has_data(custom_data_name)) - { - view->erase_data(custom_data_name); - } - } - - wf::effect_hook_t pre_hook = [=] () - { - if (auto toplevel = wf::toplevel_cast(view)) - { - if (deco) - { - /* SSD */ - deco->get_margins(toplevel->toplevel()->pending()); - } else - { - /* CSD */ - auto bg = view->get_surface_root_node()->get_bounding_box(); - auto vg = toplevel->get_geometry(); - auto margins = - wf::decoration_margins_t{vg.x - bg.x, vg.y - bg.y, - bg.width - ((vg.x - bg.x) + vg.width), bg.height - ((vg.y - bg.y) + vg.height)}; - if (view->has_data(custom_data_name)) - { - view->get_data(custom_data_name)->set_margins( - {0, 0, 0, - int(((toplevel->get_geometry().height + margins.bottom) - titlebar_height) * - progression.shade)}); - } else - { - view->store_data(std::make_unique(), custom_data_name); - view->get_data(custom_data_name)->set_margins( - {0, 0, 0, - int(((toplevel->get_geometry().height + margins.bottom) - titlebar_height) * - progression.shade)}); - } - } - } - - view->damage(); - if (!this->progression.running() && !last_direction) - { - if (output) - { - output->render->rem_effect(&pre_hook); - } - - pop_transformer(view); - } - }; - - void gen_render_instances(std::vector& instances, - damage_callback push_damage, wf::output_t *shown_on) override - { - instances.push_back(std::make_unique( - this, push_damage, view)); - } - - std::optional find_node_at(const wf::pointf_t& at) override - { - auto bbox = this->get_children_bounding_box(); - if (((at.y - bbox.y) < - ((1.0 - - (this->progression.shade * ((bbox.height - this->titlebar_height) / float(bbox.height)))) * - bbox.height)) && - ((at.y - bbox.y) > 0.0)) - { - return floating_inner_node_t::find_node_at(at); - } - - return {}; - } - - void init_animation(bool shade) - { - if (shade == last_direction) - { - return; - } - - if (this->progression.running()) - { - this->progression.reverse(); - } else - { - if ((shade && !this->progression.get_direction()) || - (!shade && this->progression.get_direction())) - { - this->progression.reverse(); - } - - this->progression.start(); - } - - last_direction = shade; - } - - void set_titlebar_height(int titlebar_height) - { - this->titlebar_height = titlebar_height; - } - - int get_shadow_margin() - { - if (deco) - { - return deco->shadow_thickness; - } else - { - if (auto toplevel = wf::toplevel_cast(view)) - { - auto bg = view->get_surface_root_node()->get_bounding_box(); - auto vg = toplevel->get_geometry(); - return bg.height - ((vg.y - bg.y) + vg.height); - } - } - - return 0; - } - - bool get_direction() - { - return this->last_direction; - } - - virtual ~pixdecor_shade() - { - if (output) - { - output->render->rem_effect(&pre_hook); - } - } -}; -} -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/smoke-shaders.hpp wayfire-plugins-extra/subprojects/pixdecor/src/smoke-shaders.hpp --- wayfire-plugins-extra-0.10.0/subprojects/pixdecor/src/smoke-shaders.hpp 2025-07-13 14:56:04.000000000 -0600 +++ wayfire-plugins-extra/subprojects/pixdecor/src/smoke-shaders.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,445 +0,0 @@ -static const char *motion_source = - R"( -#version 320 es - -precision lowp image2D; - -layout (binding = 1, r32f) uniform readonly image2D in_b0u; -layout (binding = 1, r32f) uniform writeonly image2D out_b0u; -layout (binding = 2, r32f) uniform readonly image2D in_b0v; -layout (binding = 2, r32f) uniform writeonly image2D out_b0v; -layout (binding = 3, r32f) uniform readonly image2D in_b0d; -layout (binding = 3, r32f) uniform writeonly image2D out_b0d; -layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; - -layout(location = 1) uniform int title_height; -layout(location = 2) uniform int border_size; -layout(location = 3) uniform int px; -layout(location = 4) uniform int py; -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 7) uniform int rand1; -layout(location = 8) uniform int rand2; -layout(location = 9) uniform int radius; - -void motion(int x, int y) -{ - int i, i0, i1, j, j0, j1, d = 2; - - if (x - d < 1) - i0 = 1; - else - i0 = x - d; - if (i0 + 2 * d > width - 1) - i1 = width - 1; - else - i1 = i0 + 2 * d; - - if (y - d < 1) - j0 = 1; - else - j0 = y - d; - if (j0 + 2 * d > height - 1) - j1 = height - 1; - else - j1 = j0 + 2 * d; - - for (i = i0; i < i1; i++) - { - for (j = j0; j < j1; j++) { - if (i < radius || j < radius || i > (width - 1) - radius || j > (height - 1) - radius || (i > border_size && i < (width - 1) - border_size && j > (title_height - 1) && j < (height - 1) - border_size)) - { - continue; - } - vec4 b0u = imageLoad(in_b0u, ivec2(i, j)); - vec4 b0v = imageLoad(in_b0v, ivec2(i, j)); - vec4 b0d = imageLoad(in_b0d, ivec2(i, j)); - float u = b0u.x; - float v = b0v.x; - float d = b0d.x; - imageStore(out_b0u, ivec2(i, j), vec4(u + float(256 - (rand1 & 512)), 0.0, 0.0, 0.0)); - imageStore(out_b0v, ivec2(i, j), vec4(v + float(256 - (rand2 & 512)), 0.0, 0.0, 0.0)); - imageStore(out_b0d, ivec2(i, j), vec4(d + 1.0, 0.0, 0.0, 0.0)); - } - } -} - -void main() -{ - motion(px, py); -} -)"; - -// Generic smoke shader beginning -static const char *smoke_header = - R"( -#version 320 es - -precision lowp image2D; - -layout (binding = 0, rgba32f) uniform readonly image2D in_tex; -layout (binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout (binding = 1, r32f) uniform readonly image2D in_b0u; -layout (binding = 1, r32f) uniform writeonly image2D out_b0u; -layout (binding = 2, r32f) uniform readonly image2D in_b0v; -layout (binding = 2, r32f) uniform writeonly image2D out_b0v; -layout (binding = 3, r32f) uniform readonly image2D in_b0d; -layout (binding = 3, r32f) uniform writeonly image2D out_b0d; -layout (binding = 4, r32f) uniform readonly image2D in_b1u; -layout (binding = 4, r32f) uniform writeonly image2D out_b1u; -layout (binding = 5, r32f) uniform readonly image2D in_b1v; -layout (binding = 5, r32f) uniform writeonly image2D out_b1v; -layout (binding = 6, r32f) uniform readonly image2D in_b1d; -layout (binding = 6, r32f) uniform writeonly image2D out_b1d; -layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 5) uniform int width; -layout(location = 6) uniform int height; -layout(location = 10) uniform int regionInfo[20]; -)"; - -// Generic main method for a compute shader which runs for a particular region -static const char *effect_run_for_region_main = - R"( -void main() -{ - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - int z = int(gl_GlobalInvocationID.z); - - ivec4 myRegion = ivec4(regionInfo[z * 5], regionInfo[z * 5 + 1], regionInfo[z * 5 + 2], regionInfo[z * 5 + 3]); - if (regionInfo[z * 5 + 4] > 0) - { - pos = pos.yx; - } - - if (all(lessThan(pos, myRegion.zw))) - { - pos += myRegion.xy; - run_pixel(pos.x, pos.y); - } -})"; - -static const char *diffuse1_source = - R"( -void run_pixel(int x, int y) -{ - int k; - float t, a = 0.0002; - - vec4 s = imageLoad(in_b0u, ivec2(x, y)); - vec4 d1 = imageLoad(in_b1u, ivec2(x - 1, y)); - vec4 d2 = imageLoad(in_b1u, ivec2(x + 1, y)); - vec4 d3 = imageLoad(in_b1u, ivec2(x, y - 1)); - vec4 d4 = imageLoad(in_b1u, ivec2(x, y + 1)); - float sx = s.x; - float du1 = d1.x; - float du2 = d2.x; - float du3 = d3.x; - float du4 = d4.x; - float t1 = du1 + du2 + du3 + du4; - s = imageLoad(in_b0v, ivec2(x, y)); - d1 = imageLoad(in_b1v, ivec2(x - 1, y)); - d2 = imageLoad(in_b1v, ivec2(x + 1, y)); - d3 = imageLoad(in_b1v, ivec2(x, y - 1)); - d4 = imageLoad(in_b1v, ivec2(x, y + 1)); - float sy = s.x; - du1 = d1.x; - du2 = d2.x; - du3 = d3.x; - du4 = d4.x; - float t2 = du1 + du2 + du3 + du4; - imageStore(out_b1u, ivec2(x, y), vec4((sx + a * t1) / (1.0 + 4.0 * a) * 0.995, 0.0, 0.0, 0.0)); - imageStore(out_b1v, ivec2(x, y), vec4((sy + a * t2) / (1.0 + 4.0 * a) * 0.995, 0.0, 0.0, 0.0)); -} -)"; - -static const char *project1_source = - R"( -void run_pixel(int x, int y) { - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s1 = imageLoad(in_b1u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b1u, ivec2(x + 1, y)); - vec4 s3 = imageLoad(in_b1v, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b1v, ivec2(x, y + 1)); - float u1 = s1.x; - float u2 = s2.x; - float v1 = s3.x; - float v2 = s4.x; - imageStore(out_b0u, ivec2(x, y), vec4(0.0, 0.0, 0.0, 0.0)); - imageStore(out_b0v, ivec2(x, y), vec4(-0.5 * h * (u2 - u1 + v2 - v1), 0.0, 0.0, 0.0)); -} -)"; - -static const char *project2_source = - R"( -void run_pixel(int x, int y) -{ - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s0 = imageLoad(in_b0v, ivec2(x, y)); - vec4 s1 = imageLoad(in_b0u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b0u, ivec2(x + 1, y)); - vec4 s3 = imageLoad(in_b0u, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b0u, ivec2(x, y + 1)); - float u1 = s1.x; - float u2 = s2.x; - float u3 = s3.x; - float u4 = s4.x; - imageStore(out_b0u, ivec2(x, y), vec4((s0.x + u1 + u2 + u3 + u4) / 4.0, 0.0, 0.0, 0.0)); -})"; - -static const char *project3_source = - R"( -void run_pixel(int x, int y) -{ - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s0x = imageLoad(in_b1u, ivec2(x, y)); - vec4 s1 = imageLoad(in_b0u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b0u, ivec2(x + 1, y)); - vec4 s0y = imageLoad(in_b1v, ivec2(x, y)); - vec4 s3 = imageLoad(in_b0u, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b0u, ivec2(x, y + 1)); - float su = s0x.x; - float u1 = s1.x; - float u2 = s2.x; - float sv = s0y.x; - float u3 = s3.x; - float u4 = s4.x; - imageStore(out_b1u, ivec2(x, y), vec4(su - 0.5 * (u2 - u1) / h, 0.0, 0.0, 0.0)); - imageStore(out_b1v, ivec2(x, y), vec4(sv - 0.5 * (u4 - u3) / h, 0.0, 0.0, 0.0)); -})"; - -static const char *advect1_source = - R"( -void run_pixel(int x, int y) /* b1.u, b1.v, b1.u, b0.u */ -{ - int stride; - int i, j; - float fx, fy; - stride = width; - - vec4 sx = imageLoad(in_b1u, ivec2(x, y)); - vec4 sy = imageLoad(in_b1v, ivec2(x, y)); - float ix = float(x) - sx.x; - float iy = float(y) - sy.x; - if (ix < 0.5) - ix = 0.5; - if (iy < 0.5) - iy = 0.5; - if (ix > float(width) - 1.5) - ix = float(width) - 1.5; - if (iy > float(height) - 1.5) - iy = float(height) - 1.5; - i = int(ix); - j = int(iy); - fx = ix - float(i); - fy = iy - float(j); - vec4 s0x = imageLoad(in_b1u, ivec2(i, j)); - vec4 s1x = imageLoad(in_b1u, ivec2(i + 1, j)); - vec4 s2x = imageLoad(in_b1u, ivec2(i, j + 1)); - vec4 s3x = imageLoad(in_b1u, ivec2(i + 1, j + 1)); - float p1 = (s0x.x * (1.0 - fx) + s1x.x * fx) * (1.0 - fy) + (s2x.x * (1.0 - fx) + s3x.x * fx) * fy; - imageStore(out_b0u, ivec2(x, y), vec4(p1, 0.0, 0.0, 0.0)); - ix = float(x) - sx.x; - iy = float(y) - sy.x; - if (ix < 0.5) - ix = 0.5; - if (iy < 0.5) - iy = 0.5; - if (ix > float(width) - 1.5) - ix = float(width) - 1.5; - if (iy > float(height) - 1.5) - iy = float(height) - 1.5; - i = int(ix); - j = int(iy); - fx = ix - float(i); - fy = iy - float(j); - vec4 s0y = imageLoad(in_b1v, ivec2(i, j)); - vec4 s1y = imageLoad(in_b1v, ivec2(i + 1, j)); - vec4 s2y = imageLoad(in_b1v, ivec2(i, j + 1)); - vec4 s3y = imageLoad(in_b1v, ivec2(i + 1, j + 1)); - float p2 = (s0y.x * (1.0 - fx) + s1y.x * fx) * (1.0 - fy) + (s2y.x * (1.0 - fx) + s3y.x * fx) * fy; - imageStore(out_b0v, ivec2(x, y), vec4(p2, 0.0, 0.0, 0.0)); -})"; - -static const char *project4_source = - R"( -void run_pixel(int x, int y) -{ - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s1 = imageLoad(in_b0u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b0u, ivec2(x + 1, y)); - vec4 s3 = imageLoad(in_b0v, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b0v, ivec2(x, y + 1)); - float u1 = s1.x; - float u2 = s2.x; - float v1 = s3.x; - float v2 = s4.x; - imageStore(out_b1u, ivec2(x, y), vec4(0.0, 0.0, 0.0, 0.0)); - imageStore(out_b1v, ivec2(x, y), vec4(-0.5 * h * (u2 - u1 + v2 - v1), 0.0, 0.0, 0.0)); -})"; - -static const char *project5_source = - R"( -void run_pixel(int x, int y) -{ - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s0 = imageLoad(in_b1v, ivec2(x, y)); - vec4 s1 = imageLoad(in_b1u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b1u, ivec2(x + 1, y)); - vec4 s3 = imageLoad(in_b1u, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b1u, ivec2(x, y + 1)); - float u1 = s1.x; - float u2 = s2.x; - float u3 = s3.x; - float u4 = s4.x; - imageStore(out_b1u, ivec2(x, y), vec4((s0.x + u1 + u2 + u3 + u4) / 4.0, 0.0, 0.0, 0.0)); -})"; - -static const char *project6_source = - R"( -void run_pixel(int x, int y) -{ - int k, l, s; - float h; - - h = 1.0 / float(width); - s = width; - - vec4 s0x = imageLoad(in_b0u, ivec2(x, y)); - vec4 s1 = imageLoad(in_b1u, ivec2(x - 1, y)); - vec4 s2 = imageLoad(in_b1u, ivec2(x + 1, y)); - vec4 s0y = imageLoad(in_b0v, ivec2(x, y)); - vec4 s3 = imageLoad(in_b1u, ivec2(x, y - 1)); - vec4 s4 = imageLoad(in_b1u, ivec2(x, y + 1)); - float su = s0x.x; - float u1 = s1.x; - float u2 = s2.x; - float sv = s0y.x; - float u3 = s3.x; - float u4 = s4.x; - imageStore(out_b0u, ivec2(x, y), vec4(su - 0.5 * (u2 - u1) / h, 0.0, 0.0, 0.0)); - imageStore(out_b0v, ivec2(x, y), vec4(sv - 0.5 * (u4 - u3) / h, 0.0, 0.0, 0.0)); -})"; - -static const char *diffuse2_source = - R"( -void run_pixel(int x, int y) -{ - int k, stride; - float t, a = 0.0002; - stride = width; - - vec4 s = imageLoad(in_b0d, ivec2(x, y)); - vec4 d1 = imageLoad(in_b1d, ivec2(x - 1, y)); - vec4 d2 = imageLoad(in_b1d, ivec2(x + 1, y)); - vec4 d3 = imageLoad(in_b1d, ivec2(x, y - 1)); - vec4 d4 = imageLoad(in_b1d, ivec2(x, y + 1)); - float sz = s.x; - float du1 = d1.x; - float du2 = d2.x; - float du3 = d3.x; - float du4 = d4.x; - t = du1 + du2 + du3 + du4; - imageStore(out_b1d, ivec2(x, y), vec4((sz + a * t) / (1.0 + 4.0 * a) * 0.995, 0.0, 0.0, 0.0)); -})"; - -static const char *advect2_source = - R"( -void run_pixel(int x, int y) /*b0u, b0v, b1d, b0d*/ -{ - int stride; - int i, j; - float fx, fy; - stride = width; - - vec4 sx = imageLoad(in_b0u, ivec2(x, y)); - vec4 sy = imageLoad(in_b0v, ivec2(x, y)); - float ix = float(x) - sx.x; - float iy = float(y) - sy.x; - if (ix < 0.5) - ix = 0.5; - if (iy < 0.5) - iy = 0.5; - if (ix > float(width) - 1.5) - ix = float(width) - 1.5; - if (iy > float(height) - 1.5) - iy = float(height) - 1.5; - i = int(ix); - j = int(iy); - fx = ix - float(i); - fy = iy - float(j); - vec4 s0z = imageLoad(in_b1d, ivec2(i, j)); - vec4 s1z = imageLoad(in_b1d, ivec2(i + 1, j)); - vec4 s2z = imageLoad(in_b1d, ivec2(i, j + 1)); - vec4 s3z = imageLoad(in_b1d, ivec2(i + 1, j + 1)); - float p1 = (s0z.x * (1.0 - fx) + s1z.x * fx) * (1.0 - fy) + (s2z.x * (1.0 - fx) + s3z.x * fx) * fy; - imageStore(out_b0d, ivec2(x, y), vec4(p1, 0.0, 0.0, 0.0)); -})"; - -static const char *render_source = - R"( -#version 320 es - -precision lowp image2D; - -layout (binding = 0, rgba32f) uniform writeonly image2D out_tex; -layout (binding = 3, r32f) uniform readonly image2D in_b0d; -layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; - -layout(location = 4) uniform bool ink; -layout(location = 8) uniform vec4 smoke_color; -layout(location = 9) uniform vec4 decor_color; -layout(location = 10) uniform int regionInfo[20]; - -void run_pixel(int x, int y) -{ - float c, r, g, b, a; - - vec4 s = imageLoad(in_b0d, ivec2(x, y)); - c = s.x * 800.0; - if (c > 255.0) - c = 255.0; - a = c; - vec3 color; - if (ink) - { - if (c > 2.0) - color = mix(decor_color.rgb, smoke_color.rgb, clamp(a, 0.0, 1.0)); - else - color = mix(decor_color.rgb, vec3(0.0, 0.0, 0.0), clamp(a, 0.0, 1.0)); - if (c > 1.5) - imageStore(out_tex, ivec2(x, y), vec4(color, 1.0)); - else - imageStore(out_tex, ivec2(x, y), decor_color); - return; - } else - { - color = mix(decor_color.rgb, smoke_color.rgb, clamp(a, 0.0, 1.0)); - } - imageStore(out_tex, ivec2(x, y), vec4(color, decor_color.a)); -})"; diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/.gitignore wayfire-plugins-extra/subprojects/wayfire-shadows/.gitignore --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/.gitignore 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/.gitignore 1969-12-31 17:00:00.000000000 -0700 @@ -1,2 +0,0 @@ -build -.cache diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/LICENSE wayfire-plugins-extra/subprojects/wayfire-shadows/LICENSE --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/LICENSE 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/LICENSE 1969-12-31 17:00:00.000000000 -0700 @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2021 Tim Göttlicher - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/meson.build wayfire-plugins-extra/subprojects/wayfire-shadows/meson.build --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/meson.build 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/meson.build 1969-12-31 17:00:00.000000000 -0700 @@ -1,49 +0,0 @@ -project( - 'wayfire-plugin-winshadows', - 'c', - 'cpp', - version: '0.1', - license: 'MIT', - meson_version: '>=0.51.0', - default_options: [ - 'cpp_std=c++17', - 'c_std=c11', - 'warning_level=2', - 'werror=false', - ], -) - -wayfire = dependency('wayfire') -wfconfig = dependency('wf-config') - -add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c']) -add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c']) -add_project_link_arguments(['-rdynamic'], language:'cpp') - -shadows = shared_module( - 'winshadows', [ - 'winshadows.cpp', - 'node.cpp', - 'renderer.cpp', - 'shaders.glsl.cpp', - ], - - dependencies: [ - wfconfig, - wayfire - ], - - install: true, - install_dir: join_paths( get_option( 'libdir' ), 'wayfire' ) -) - -install_data( 'winshadows.xml', install_dir: wayfire.get_variable( pkgconfig: 'metadatadir' ) ) - -summary = [ - '', - '----------------', - 'wayfire-plugin-winshadows @0@'.format( meson.project_version() ), - '----------------', - '' -] -message('\n'.join(summary)) diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/node.cpp wayfire-plugins-extra/subprojects/wayfire-shadows/node.cpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/node.cpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/node.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,70 +0,0 @@ -#include "node.hpp" - -namespace winshadows { - -shadow_node_t::shadow_node_t( wayfire_toplevel_view view ): wf::scene::node_t(false) { - this->view = view; - on_geometry_changed.set_callback([this] (auto) { - update_geometry(); - }); - on_activated_changed.set_callback([this] (auto) { - this->view->damage(); - }); - view->connect(&on_geometry_changed); - view->connect(&on_activated_changed); - update_geometry(); -} - -shadow_node_t::~shadow_node_t() { - view->disconnect(&on_geometry_changed); -} - -wf::geometry_t shadow_node_t::get_bounding_box() { - return geometry; -} - -void shadow_node_t::gen_render_instances(std::vector &instances, wf::scene::damage_callback push_damage, wf::output_t *output) { - // define renderer - class shadow_render_instance_t : public wf::scene::simple_render_instance_t { - public: - using simple_render_instance_t::simple_render_instance_t; - void render(const wf::scene::render_instruction_t& data ) override - { - // coordinates relative to view origin (not bounding box origin) - wf::point_t frame_origin = self->frame_offset; - wf::region_t paint_region = self->shadow_region + frame_origin; - paint_region &= data.damage; - - for (const auto& box : paint_region) - - { - self->shadow.render(data, frame_origin, wlr_box_from_pixman_box(box) , self->view->activated); - } - self->_was_activated = self->view->activated; - } - }; - - instances.push_back(std::make_unique(this, push_damage, output)); -} - -void shadow_node_t::update_geometry() { - wf::geometry_t frame_geometry = view->get_geometry(); - shadow.resize(frame_geometry.width, frame_geometry.height); - - // TODO: Check whether this can be done in a nicer/easier way - wf::pointf_t view_origin_f = view->get_surface_root_node()->to_global({0, 0}); - wf::point_t view_origin {(int)view_origin_f.x, (int)view_origin_f.y}; - - // Offset between view origin and frame top left corner - frame_offset = wf::origin(frame_geometry) - view_origin; - - // Shadow geometry is relative to the top left corner of the frame (not the view) - wf::geometry_t shadow_geometry = shadow.get_geometry(); - - // move to view-relative coordinates - geometry = shadow_geometry + frame_offset; - - this->shadow_region = shadow.calculate_region(); -} - -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/node.hpp wayfire-plugins-extra/subprojects/wayfire-shadows/node.hpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/node.hpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/node.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "renderer.hpp" - -namespace winshadows { - -class shadow_node_t : public wf::scene::node_t { - private: - int _was_activated = 1; // used to check whether redrawing on focus is necessary - - // geometry of the node relative to the view origin - wf::geometry_t geometry; - - // offset between the node origin and the frame origin (i.e. top-left borders) - wf::point_t frame_offset; - - wayfire_toplevel_view view; - - int width = 100, height = 100; - wf::region_t shadow_region; - shadow_renderer_t shadow; - - wf::signal::connection_t on_geometry_changed; - wf::signal::connection_t on_activated_changed; - - void update_geometry(); - - public: - shadow_node_t(wayfire_toplevel_view view); - - virtual ~shadow_node_t(); - - void gen_render_instances(std::vector &instances, wf::scene::damage_callback push_damage, wf::output_t *output = nullptr) override; - - wf::geometry_t get_bounding_box() override; - -}; - -} - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/README.md wayfire-plugins-extra/subprojects/wayfire-shadows/README.md --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/README.md 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/README.md 1969-12-31 17:00:00.000000000 -0700 @@ -1,76 +0,0 @@ -# winshadows - -### Window Shadows Plugin for Wayfire - -This is a plugin for wayfire that adds window shadows. The code was initially a -fork of but only a small part of -that remains in the code. - -## Screenshots - -By default, the plugin will add fast and nice shadows around windows that use server side decorations. Additionally there is an option to make the focused window glow. - -![image](https://github.com/timgott/wayfire-shadows/assets/18331942/94d27159-573c-4613-8bf6-4527502539f5) - -
-Config used in screenshot - -```ini -[decoration] -active_color = \#7A98BA76 -border_size = 4 -inactive_color = \#20201838 -title_height = 0 - -[winshadows] -glow_enabled = true -shadow_radius = 50 -vertical_offset = 10 -horizontal_offset = 5 -# remaining values are default - -``` -
- -## Install - -1. Get the sources - ```bash - git clone https://github.com/timgott/wayfire-shadows.git - cd wayfire-shadows - ``` -2. ⚠️ Switch to the backport0.7 branch if you use wayfire version 0.7 (last stable release) - ```bash - git checkout backport0.7 # (if necessary) - ``` -3. Configure with meson and build & install with ninja. - ```bash - meson build --buildtype=release - cd build - # meson configure --prefix=... # if wayfire is not installed in /usr/local - ninja - sudo ninja install - ``` - -## Install with [wfplug](https://github.com/timgott/wfplug) - -As above, you have to change the branch on wayfire 0.7. - -```bash -# enable wfplug -source ~/wfplug/activate # edit path if necessary - -# get plugin -wfplug-goto-plugins -git clone https://github.com/timgott/wayfire-shadows.git winshadows - -# build and install to wfplug -wfplug-build winshadows -``` - -Try a testconfig with - -```bash -wfplug-test winshadows bluelight -``` - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/renderer.cpp wayfire-plugins-extra/subprojects/wayfire-shadows/renderer.cpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/renderer.cpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/renderer.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,220 +0,0 @@ -#include -#include -#include -#include "renderer.hpp" - -namespace winshadows { - -shadow_renderer_t::shadow_renderer_t() { - wf::gles::run_in_context([&] - { - generate_dither_texture(); - recompile_shaders(); - }); - - light_type_option.set_callback([this] () { - recompile_shaders(); - }); -} - -void shadow_renderer_t::recompile_shaders() { - wf::gles::run_in_context([&] - { - shadow_program.free_resources(); - shadow_glow_program.free_resources(); - - shadow_program.set_simple( - OpenGL::compile_program(shadow_vert_shader, frag_shader(light_type_option, /*no glow*/ false)) - ); - shadow_glow_program.set_simple( - OpenGL::compile_program(shadow_vert_shader, frag_shader(light_type_option, /*glow*/ true)) - ); - - }); -} - -void shadow_renderer_t::generate_dither_texture() { - const int size = 32; - GLuint data[size*size]; - - std::mt19937_64 gen{std::random_device{}()}; - std::uniform_int_distribution distrib; - - for (int i = 0; i < size*size; i++) { - data[i] = distrib(gen); - } - - GL_CALL(glGenTextures(1, &dither_texture)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, dither_texture)); - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); - GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); -} - -shadow_renderer_t::~shadow_renderer_t() { - wf::gles::run_in_context([&] - { - shadow_program.free_resources(); - shadow_glow_program.free_resources(); - - GL_CALL(glDeleteTextures(1, &dither_texture)); - - }); -} - -void shadow_renderer_t::render(const wf::scene::render_instruction_t& data, wf::point_t window_origin, const wf::geometry_t& scissor, const bool glow) { - float radius = shadow_radius_option; - - wf::color_t color = shadow_color_option; - - // Premultiply alpha for shader - glm::vec4 premultiplied = { - color.r * color.a, - color.g * color.a, - color.b * color.a, - color.a - }; - - // Glow color, alpha=0 => additive blending (exploiting premultiplied alpha) - wf::color_t glow_color = glow_color_option; - glm::vec4 glow_premultiplied = { - glow_color.r * glow_color.a, - glow_color.g * glow_color.a, - glow_color.b * glow_color.a, - glow_color.a * (1.0 - glow_emissivity_option) - }; - - // Enable glow shader only when glow radius > 0 and view is focused - bool use_glow = (glow && is_glow_enabled()); - OpenGL::program_t &program = - use_glow ? shadow_glow_program : shadow_program; - - data.pass->custom_gles_subpass(data.target,[&] - { - - wf::gles::render_target_logic_scissor(data.target, scissor); - program.use(wf::TEXTURE_TYPE_RGBA); - - // Compute vertex rectangle geometry - wf::geometry_t bounds = outer_geometry + window_origin; - float left = bounds.x; - float right = bounds.x + bounds.width; - float top = bounds.y; - float bottom = bounds.y + bounds.height; - - GLfloat vertexData[] = { - left, bottom, - right, bottom, - right, top, - left, top - }; - - glm::mat4 matrix = wf::gles::render_target_orthographic_projection(data.target); - - // vertex parameters - program.attrib_pointer("position", 2, 0, vertexData); - program.uniformMatrix4f("MVP", matrix); - - // fragment parameters - program.uniform1f("radius", radius); - program.uniform4f("color", premultiplied); - - const auto inner = window_geometry + window_origin; - const auto shadow_inner = shadow_projection_geometry + window_origin; - program.uniform2f("lower", shadow_inner.x, shadow_inner.y); - program.uniform2f("upper", shadow_inner.x + shadow_inner.width, shadow_inner.y + shadow_inner.height); - - if (use_glow) { - program.uniform2f("glow_lower", inner.x, inner.y); - program.uniform2f("glow_upper", inner.x + inner.width, inner.y + inner.height); - - program.uniform1f("glow_spread", glow_spread_option); - program.uniform4f("glow_color", glow_premultiplied); - program.uniform1f("glow_intensity", glow_intensity_option); - program.uniform1f("glow_threshold", glow_threshold_option); - } - - // dither texture - program.uniform1i("dither_texture", 0); - GL_CALL(glActiveTexture(GL_TEXTURE0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, dither_texture)); - - GL_CALL(glEnable(GL_BLEND)); - GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - GL_CALL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); - - program.deactivate(); - }); -} - -wf::region_t shadow_renderer_t::calculate_region() const { - // TODO: geometry and region depending on whether glow is active or not - wf::region_t region = wf::region_t(shadow_geometry) | wf::region_t(glow_geometry); - - if (clip_shadow_inside) { - region ^= window_geometry; - } - - return region; -} - -wf::geometry_t shadow_renderer_t::get_geometry() const { - return outer_geometry; -} - -wf::geometry_t expand_geometry(const wf::geometry_t& geometry, const int marginX, const int marginY) { - return { - geometry.x - marginX, - geometry.y - marginY, - geometry.width + marginX * 2, - geometry.height + marginY * 2 - }; -} - -wf::geometry_t expand_geometry(const wf::geometry_t& geometry, const int margin) { - return expand_geometry(geometry, margin, margin); -} - -wf::geometry_t inflate_geometry(const wf::geometry_t& geometry, const float inflation) { - int expandX = geometry.width * inflation * 0.5; - int expandY = geometry.height * inflation * 0.5; - return expand_geometry(geometry, expandX, expandY); -} - -void shadow_renderer_t::resize(const int window_width, const int window_height) { - window_geometry = { - 0, - 0, - window_width, - window_height - }; - - float overscale = overscale_option / 100.0; - const wf::point_t offset { horizontal_offset, vertical_offset }; - shadow_projection_geometry = - inflate_geometry(window_geometry, overscale) + offset; - - shadow_geometry = expand_geometry(shadow_projection_geometry, shadow_radius_option); - - int glow_radius = is_glow_enabled() ? glow_radius_limit_option : 0; - glow_geometry = expand_geometry(shadow_projection_geometry, glow_radius); - - int left = std::min(shadow_geometry.x, glow_geometry.x); - int top = std::min(shadow_geometry.y, glow_geometry.y); - int right = std::max(shadow_geometry.x + shadow_geometry.width, glow_geometry.x + glow_geometry.width); - int bottom = std::max(shadow_geometry.y + shadow_geometry.height, glow_geometry.y + glow_geometry.height); - outer_geometry = { - left, - top, - right - left, - bottom - top - }; -} - -bool shadow_renderer_t::is_glow_enabled() const { - return glow_enabled_option && (glow_radius_limit_option > 0) && (glow_intensity_option > 0); -} - -} diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/renderer.hpp wayfire-plugins-extra/subprojects/wayfire-shadows/renderer.hpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/renderer.hpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/renderer.hpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,59 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace winshadows { -/** - * A class that can render shadows. - * It manages the shader and calculates the necessary padding. - */ -class shadow_renderer_t { - public: - shadow_renderer_t(); - ~shadow_renderer_t(); - - void recompile_shaders(); - void render(const wf::scene::render_instruction_t& data, wf::point_t origin, const wf::geometry_t& scissor, const bool glow); - void resize(const int width, const int height); - wf::region_t calculate_region() const; - wf::geometry_t get_geometry() const; - bool is_glow_enabled() const; - - private: - OpenGL::program_t shadow_program; - OpenGL::program_t shadow_glow_program; - GLuint dither_texture; - void generate_dither_texture(); - - wf::geometry_t glow_geometry; - wf::geometry_t shadow_geometry; - wf::geometry_t shadow_projection_geometry; // projected window geometry - wf::geometry_t outer_geometry; - wf::geometry_t window_geometry; - wlr_box calculate_padding(const wf::geometry_t window_geometry) const; - - wf::option_wrapper_t shadow_color_option { "winshadows/shadow_color" }; - wf::option_wrapper_t shadow_radius_option { "winshadows/shadow_radius" }; - wf::option_wrapper_t clip_shadow_inside { "winshadows/clip_shadow_inside" }; - wf::option_wrapper_t vertical_offset { "winshadows/vertical_offset" }; - wf::option_wrapper_t horizontal_offset { "winshadows/horizontal_offset" }; - wf::option_wrapper_t light_type_option { "winshadows/light_type" }; - wf::option_wrapper_t overscale_option { "winshadows/overscale" }; - - wf::option_wrapper_t glow_enabled_option { "winshadows/glow_enabled" }; - wf::option_wrapper_t glow_color_option { "winshadows/glow_color" }; - wf::option_wrapper_t glow_emissivity_option { "winshadows/glow_emissivity" }; - wf::option_wrapper_t glow_spread_option { "winshadows/glow_spread" }; - wf::option_wrapper_t glow_intensity_option { "winshadows/glow_intensity" }; - wf::option_wrapper_t glow_threshold_option { "winshadows/glow_threshold" }; - wf::option_wrapper_t glow_radius_limit_option { "winshadows/glow_radius_limit" }; - - static const std::string shadow_vert_shader; - const std::string frag_shader(const std::string &light_type, const bool glow); -}; - -} - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/shaders.glsl.cpp wayfire-plugins-extra/subprojects/wayfire-shadows/shaders.glsl.cpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/shaders.glsl.cpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/shaders.glsl.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,272 +0,0 @@ -// GLSL as cpp string constant (.glsl extension for syntax highlighting) -#include "renderer.hpp" - - -/* Vertex shader */ - -const std::string winshadows::shadow_renderer_t::shadow_vert_shader = -R"( -#version 300 es - -in mediump vec2 position; -out mediump vec2 uvpos; - -uniform mat4 MVP; - -void main() { - gl_Position = MVP * vec4(position.xy, 0.0, 1.0); - uvpos = position.xy; -})"; - - - -/* Base fragment shader definitions */ - -const std::string flag_define(const std::string& name, const bool value) { - return "#define " + name + " " + (value? "1" : "0") + "\n"; -} - -const std::string frag_header(const std::string& light_type, const bool glow) { - return - "#version 300 es\n" + - flag_define("CIRCULAR_SHADOW", light_type == "circular") + - flag_define("GAUSSIAN_SHADOW", light_type == "gaussian") + - flag_define("SQUARE_SHADOW", light_type == "square") + - flag_define("GLOW", glow); -} - -// All definitions are inserted in the shader, the shader compiler will remove unused ones -const std::string frag_body = -R"( -precision highp float; -in vec2 uvpos; -out vec4 fragColor; -uniform vec2 lower; -uniform vec2 upper; -uniform vec4 color; - -uniform float radius; - -uniform sampler2D dither_texture; - -/* Gaussian shadow */ - -// Adapted from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/ -// License: CC0 (http://creativecommons.org/publicdomain/zero/1.0/) -// This approximates the error function, needed for the gaussian integral -vec4 erf(vec4 x) { - vec4 s = sign(x), a = abs(x); - x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a; - x *= x; - return s - s / (x * x); -} - -// Computes a gaussian convolution of a box from lower to upper -float boxGaussian(vec2 lower, vec2 upper, vec2 point, float sigma) { - vec4 query = vec4(lower - point, upper - point); - vec4 integral = 0.5 + 0.5 * erf(query * (sqrt(0.5) / sigma)); - return (integral.z - integral.x) * (integral.w - integral.y); -} - - -/* Circular shadow */ - -// Antiderivative of sqrt(1-x^2) -float circleIntegral(float x) { - return (sqrt(1.0-x*x)*x+asin(x)) / 2.0; -} - -#define M_PI 3.14159265358 - -float circleSegment(float dist) { - return sqrt(1.0-dist*dist); -} - -// assuming fullArea is the area of two parts of a circle cut by a horizontal stripe -// (top and bottom are the cut lines) -// compute the remaining area when cut vertically at right -float circleMinusWall(float top, float bottom, float right, float fullArea) { - if (right <= -1.0) { - return fullArea; // entire circle - } else if (right >= 1.0) { - return 0.0; // nothing - } else { - // compute circle segment half width - float w = circleSegment(right); - // circle segment area - float segmentTop = max(top, -w); - float segmentBottom = min(bottom, w); - float area = circleIntegral(segmentBottom) - circleIntegral(segmentTop) - (segmentBottom - segmentTop) * abs(right); - if (right < 0.0) { - return fullArea - area; - } else { - return area; - } - } -} - -// Circle-rectangle overlap -// circle is at (0,0) radius 1 -// only one top-left corner of rectangle is considered (assume rectangle >> circle) -float circleOverlap(vec2 lower, vec2 upper) { - // left/right half integral with vertical bounds - float top = max(lower.y, -1.0); - float bottom = min(upper.y, 1.0); - float inner = 2.0 * (circleIntegral(bottom) - circleIntegral(top)); - // left/right outer integrals for horizontal bounds - float outerLeft = circleMinusWall(top, bottom, -lower.x, inner); - float outerRight = circleMinusWall(top, bottom, upper.x, inner); - return (inner - outerLeft - outerRight) / M_PI; -} - -// Shadow of rectangle under circular area light -float circularLightShadow(vec2 lower, vec2 upper, vec2 point, float radius) { - vec4 query = vec4(lower - point, upper - point) / radius; - return max(circleOverlap(query.st, query.pq), 0.0); -} - -// Shadow of rectangle under square area light -float squareShadow(vec2 lower, vec2 upper, vec2 point, float radius) { - vec2 squareLower = point - radius; - vec2 squareUpper = point + radius; - vec2 overlapLower = max(lower, squareLower); - vec2 overlapUpper = min(upper, squareUpper); - vec2 overlap = max(overlapUpper - overlapLower, 0.0); - float maxArea = radius * radius * 4.0; - return overlap.x * overlap.y / maxArea; // area -} - - -/* Glow */ - -uniform vec4 glow_color; -uniform float glow_spread; -uniform vec2 glow_lower; -uniform vec2 glow_upper; - -uniform float glow_intensity; -uniform float glow_threshold; - -/* Inverse quartic falloff */ - -vec2 invQrtIntegralPartial(float xmin, float xmax, vec2 y, float z) { - // Rectangle integral over 1/(x^2+y^2+1)^2 - // Computed using FriCAS: - // formatExpression(integrate(integrate(1/((x^2+y^2+z^2)^2), x=a..b, "noPole"), y))$Format1D - // Then some rewriting to make it valid glsl and simplified a bit - - float a = xmin; - float b = xmax; - - float zsqr = z*z; - float s1 = zsqr+a*a; - float s2 = zsqr+b*b; - vec2 s3 = zsqr+y*y; - float t1 = sqrt(s1); - float t2 = sqrt(s2); - vec2 t3 = sqrt(s3); - - return (y*t1*t2*t3*(atan((b*t3)/(s3))-atan((a*t3)/(s3)))+(zsqr+y*y)*(b*t1*atan((y*t2)/(s2))+(-a)*t2*atan((y*t1)/(s1))))/((2.0*zsqr*(1.0+y*y*zsqr))*t1*t2); -} - -float boxInvQrtFalloff(vec2 lower, vec2 upper, vec2 point, float scale) { - vec4 query = vec4(lower - point, upper - point) / scale; - vec2 integralBounds = invQrtIntegralPartial(query.x, query.z, query.yw, 1.0); - return (integralBounds.y - integralBounds.x); -} - - -/* Inverse square falloff, but only vertically and horizontally */ - -float orthoInvSqrFalloff(vec2 lower, vec2 upper, vec2 point, float scale) { - // f = (x^2+1)^(-1) - // F = arctan(x) - vec4 query = vec4(lower - point, upper - point) / scale; - vec4 integral = atan(query); - return (integral.z - integral.x) * (integral.w - integral.y); -} - - -/* Inverse square falloff, but only 1d based on distance to window edge */ - -float distInvSqrFalloff(vec2 lower, vec2 upper, vec2 point, float scale) { - vec4 offsets = vec4(lower - point, point - upper) / scale; - float a = max(max(offsets.x, offsets.z), 0.0); - float b = max(max(offsets.y, offsets.w), 0.0); - float dsqr = a*a + b*b; - float invsqr = 1.0 / (dsqr + 1.0); - return invsqr;//invsqr.x*invsqr.z * invsqr.y*invsqr.w; -} - - -/* Inverse square falloff integral over window edges (neon) */ - -vec4 barInvSqrFalloffIntegral(vec4 t, vec4 d, float z) { - // FriCAS: integrate(1/(t^2+d^2+z^2), t) - vec4 rsqr = d*d+z*z; - vec4 r = sqrt(rsqr); - return atan(t * r / rsqr) / r; -} - -vec4 barInvCubicFalloffIntegral(vec4 t, vec4 d, float z) { - // FriCAS: integrate(1/(t^2+d^2+z^2)^(3/2), t) - vec4 rsqr = t*t+d*d+z*z; - vec4 r = sqrt(rsqr); - return -1.0/(t*r-rsqr); -} - -float edgeInvSqrGlow(vec2 lower, vec2 upper, vec2 point, float scale) { - // distance to edge left, top, right, bottom - vec4 edgeDists = vec4(lower - point, upper - point); - vec4 integralLower = barInvSqrFalloffIntegral(edgeDists.tsts, edgeDists, scale); - vec4 integralUpper = barInvSqrFalloffIntegral(edgeDists.qpqp, edgeDists, scale); - - vec4 integral = integralUpper - integralLower; - return (integral.s + integral.t + integral.p + integral.q); -} - -float lightThreshold(float x, float minThreshold) { - return max(x - minThreshold, 0.0); -} - -vec4 dither(vec2 pos) { - vec2 size = vec2(textureSize(dither_texture, 0)); - return texture(dither_texture, pos / size) / 256.0 - 0.5 / 256.0; -} - -vec4 shadow_color() -{ -#if CIRCULAR_SHADOW - return color * circularLightShadow(lower, upper, uvpos, radius); -#elif SQUARE_SHADOW - return color * squareShadow(lower, upper, uvpos, radius); -#else // GAUSSIAN_SHADOW - return color * boxGaussian(lower, upper, uvpos, radius / 2.7); -#endif -} - -/* Rectangle shadow+glow fragment shader */ - -void main() -{ -#if GLOW - float glow_value = edgeInvSqrGlow(glow_lower, glow_upper, uvpos, glow_spread), glow_neon_threshold; - //float glow_value = boxInvQrtFalloff(glow_lower, glow_upper, uvpos, glow_spread); - //float glow_value = boxGaussian(glow_lower, glow_upper, uvpos, glow_spread) - //float glow_value = distInvSqrFalloff(glow_lower, glow_upper, uvpos, glow_spread); - //float glow_value = orthoInvSqrFalloff(glow_lower, glow_upper, uvpos, glow_spread); - vec4 out_color = - shadow_color() + - glow_intensity * glow_color * lightThreshold(glow_value, glow_threshold); -#else - vec4 out_color = shadow_color(); -#endif - out_color += dither(uvpos + lower*upper); - fragColor = out_color; -} - -)"; - -const std::string winshadows::shadow_renderer_t::frag_shader(const std::string &light_type, const bool glow) { - return frag_header(light_type, glow) + frag_body; -} \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/bluelight.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/bluelight.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/bluelight.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/bluelight.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,76 +0,0 @@ -# shadows + glow + decoration - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = true -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 5 -vertical_offset = 10 -shadow_color = \#00000078 -shadow_radius = 80 - -[decoration] -active_color = \#7A98BA76 -border_size = 4 -inactive_color = \#20201838 -title_height = 0 - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - decoration \ - move \ - resize \ - place \ - vswitch \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - -# Background might be useful if you are testing decorations -background = swaybg --color "\#322d3d" - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = random - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/circular.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/circular.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/circular.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/circular.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,71 +0,0 @@ -# extreme circle - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = false -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 100 -vertical_offset = 100 -shadow_color = \#000000FF -shadow_radius = 100 -light_type = circular - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - -# Background might be useful if you are testing decorations -background_color = \#FFFFFFFF - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -#test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = center - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/decoborder.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/decoborder.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/decoborder.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/decoborder.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,76 +0,0 @@ -# shadows + glow + decoration - -[winshadows] -clip_shadow_inside = true -glow_color = \#FF00FFFF -glow_enabled = true -glow_intensity = 2.5 -glow_radius_limit = 50 -glow_spread = 3.0 -glow_threshold = 0.00 -horizontal_offset = 5 -vertical_offset = 10 -shadow_color = \#000000FF -shadow_radius = 80 - -[decoration] -active_color = \#FFFFFFFF -border_size = 30 -inactive_color = \#999999FF -title_height = 30 - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - decoration \ - move \ - resize \ - place \ - vswitch \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - -# Background might be useful if you are testing decorations -background = swaybg --color "\#322d3d" - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = random - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/gaussian.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/gaussian.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/gaussian.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/gaussian.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,74 +0,0 @@ -# extreme gaussian - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = false -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 100 -vertical_offset = 100 -shadow_color = \#000000FF -shadow_radius = 100 -light_type = gaussian - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch \ - follow-focus \ - showrepaint - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - -# Background might be useful if you are testing decorations -background_color = \#FFFFFFFF - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -#test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = center - -[showrepaint] -toggle = KEY_R \ No newline at end of file diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/glow.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/glow.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/glow.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/glow.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,69 +0,0 @@ -# shadows and focus glow - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = true -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 5 -vertical_offset = 10 -shadow_color = \#00000078 -shadow_radius = 80 - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - -# Background might be useful if you are testing decorations -background = swaybg --color "\#322d3d" - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = random - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/minimal.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/minimal.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/minimal.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/minimal.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,55 +0,0 @@ -# only shadows - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - -# Background might be useful if you are testing decorations -background = swaybg --color "\#322d3d" - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = random - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/overscale.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/overscale.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/overscale.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/overscale.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,73 +0,0 @@ -# extreme square - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = false -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 20 -vertical_offset = 30 -shadow_color = \#00000080 -shadow_radius = 10 -light_type = gaussian -overscale = 2.0 - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch \ - decoration \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - -# Background might be useful if you are testing decorations -background_color = \#EEEEEEFF - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -#test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = center - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/square.ini wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/square.ini --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/testconfig/square.ini 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/testconfig/square.ini 1969-12-31 17:00:00.000000000 -0700 @@ -1,71 +0,0 @@ -# extreme square - -[winshadows] -clip_shadow_inside = true -glow_color = \#3584E4FF -glow_enabled = false -glow_intensity = 0.5 -glow_radius_limit = 150 -glow_spread = 8.0 -glow_threshold = 0.03 -horizontal_offset = 100 -vertical_offset = 100 -shadow_color = \#000000FF -shadow_radius = 100 -light_type = square - -[core] - -plugins = \ - winshadows \ - autostart \ - command \ - move \ - resize \ - place \ - vswitch \ - follow-focus - -# Close focused window. -close_top_view = KEY_Q - -# server-side decorations to make testing decorations easier -preferred_decoration_mode = server - -xwayland = false - -# Background might be useful if you are testing decorations -background_color = \#FFFFFFFF - - -# Startup commands ───────────────────────────────────────────────────────────── -[autostart] - -# Disable panel, dock and default background -autostart_wf_shell = false - - -# Start some terminal windows for testing here! -test1 = sh -c "alacritty || foot || gnome-terminal" -#test2 = sh -c "alacritty || foot || gnome-terminal" - -# Bindings ─────────────────────────────────────────────────────────────── -[command] - -# Start a terminal -binding_terminal = KEY_ENTER -command_terminal = sh -c "alacritty || foot || gnome-terminal" - -# Drag windows by holding down Super and left mouse button. -[move] -activate = BTN_LEFT - -# Resize them with right mouse button + Super. -[resize] -activate = BTN_RIGHT - - -# Place windows randomly -[place] -mode = center - diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/winshadows.cpp wayfire-plugins-extra/subprojects/wayfire-shadows/winshadows.cpp --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/winshadows.cpp 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/winshadows.cpp 1969-12-31 17:00:00.000000000 -0700 @@ -1,129 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "node.hpp" - -struct view_shadow_data : wf::custom_data_t { - view_shadow_data(std::shared_ptr shadow_ptr) : shadow_ptr(shadow_ptr) {}; - - std::shared_ptr shadow_ptr; -}; - -class wayfire_shadows : public wf::plugin_interface_t { - const std::string surface_data_name = "shadow_surface"; - - wf::view_matcher_t enabled_views{"winshadows/enabled_views"}; - wf::option_wrapper_t include_undecorated_views{"winshadows/include_undecorated_views"}; - - // update new views - wf::signal::connection_t on_view_mapped = - [=](auto *data) { update_view_decoration(data->view); }; - // update when view enables or disables server side decoration - wf::signal::connection_t on_view_updated = - [=](auto *data) { update_view_decoration(data->view); }; - // update on tile state change, such that it is possible to exclude tiled windows - wf::signal::connection_t on_view_tiled = - [=](auto *data) { update_view_decoration(data->view); }; - -public: - void init() override { - if (!wf::get_core().is_gles2()) - { - LOGE("winshadows plugin requires GLES2 renderer!"); - return; - } - wf::get_core().connect(&on_view_mapped); - wf::get_core().connect(&on_view_updated); - wf::get_core().connect(&on_view_tiled); - - for (auto &view : wf::get_core().get_all_views()) { - update_view_decoration(view); - } - } - - void fini() override { - wf::get_core().disconnect(&on_view_mapped); - wf::get_core().disconnect(&on_view_updated); - wf::get_core().disconnect(&on_view_tiled); - - for (auto &view : wf::get_core().get_all_views()) { - deinit_view(view); - } - } - - /** - * Checks whether the given view has server side decoration and is in - * the white list. - * - * @param view The view to match - * @return Whether the view should get a shadow. - */ - bool is_view_shadow_enabled(wayfire_toplevel_view view) { - return enabled_views.matches(view) && (is_view_decorated(view) || include_undecorated_views); - } - - bool is_view_decorated(wayfire_toplevel_view view) { - return view->should_be_decorated(); - } - - const wf::scene::floating_inner_ptr& get_shadow_root_node(wayfire_view view) const { - return view->get_surface_root_node(); - } - - wf::wl_idle_call idle_deactivate; - void update_view_decoration(wayfire_view view) { - auto toplevel = wf::toplevel_cast(view); - if (toplevel) { - if (is_view_shadow_enabled(toplevel)) { - auto shadow_data = view->get_data(surface_data_name); - if (!shadow_data) { - // No shadow yet, create it now. - init_view(toplevel); - } else { - // in some situations the shadow node might have been removed due to unmap, but the view is reused (including the custom data) - auto shadow_root = get_shadow_root_node(view); - if (shadow_data->shadow_ptr->parent() != shadow_root.get()) { - wf::scene::add_back(shadow_root, shadow_data->shadow_ptr); - } - } - } else { - deinit_view(view); - } - } - } - - bool is_view_initialized(wayfire_view view) { - return view->has_data(surface_data_name); - } - - void init_view(wayfire_toplevel_view view) { - // create the shadow node and add it to the view - auto node = std::make_shared(view); - wf::scene::add_back(get_shadow_root_node(view), node); - - // store the shadow node in the view so we can remove it later - auto view_data = std::make_unique(node); - view->store_data(std::move(view_data), surface_data_name); - - view->damage(); - } - - void deinit_view(wayfire_view view) { - auto view_data = view->get_data(surface_data_name); - if (view_data != nullptr) { - wf::scene::remove_child(view_data->shadow_ptr); - view->damage(); - view->erase_data(surface_data_name); - } - } -}; - -DECLARE_WAYFIRE_PLUGIN(wayfire_shadows); diff --color -Naurp wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/winshadows.xml wayfire-plugins-extra/subprojects/wayfire-shadows/winshadows.xml --- wayfire-plugins-extra-0.10.0/subprojects/wayfire-shadows/winshadows.xml 2025-07-20 09:49:48.000000000 -0600 +++ wayfire-plugins-extra/subprojects/wayfire-shadows/winshadows.xml 1969-12-31 17:00:00.000000000 -0700 @@ -1,118 +0,0 @@ - - - - <_short>Window Shadows - <_long>Server Side Shadows for windows on Wayfire - Effects - - - - - <_short>Shadow - - - - - - - - - <_short>Glow - <_long>Make windows edges emit light when focused - - - - - - <_short>Advanced - - - - - - -