mirror of
https://github.com/swaywm/sway.git
synced 2025-10-31 22:25:26 -04:00
Compare commits
242 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
055be4ec35 | ||
|
|
b7eb6177e1 | ||
|
|
90d3270970 | ||
|
|
ecfea6b8ae | ||
|
|
b4a9a1716f | ||
|
|
d9e615c507 | ||
|
|
bc96d0acdf | ||
|
|
a7d9535eb3 | ||
|
|
7c1e192ea3 | ||
|
|
50a8750e01 | ||
|
|
a41b25020d | ||
|
|
35b69158d7 | ||
|
|
862e9b8c20 | ||
|
|
68ac52ffc2 | ||
|
|
e6fc3ffa3f | ||
|
|
70c51c44f6 | ||
|
|
ca45c22376 | ||
|
|
c5456be750 | ||
|
|
aaab7f961e | ||
|
|
73c244fb48 | ||
|
|
b3dcde8d69 | ||
|
|
0770a8d643 | ||
|
|
340505bb6f | ||
|
|
f50e307227 | ||
|
|
87fbcf0574 | ||
|
|
357d341f8f | ||
|
|
14fbe9242f | ||
|
|
e50b16a699 | ||
|
|
cb33701f5e | ||
|
|
08142c3f3a | ||
|
|
3826535ab0 | ||
|
|
f57c82a6f7 | ||
|
|
8d7c756276 | ||
|
|
94c819cc1f | ||
|
|
6fed1f9d89 | ||
|
|
bac8c0f4d0 | ||
|
|
c7d7d56f61 | ||
|
|
a1ac2a2e93 | ||
|
|
56f2db062d | ||
|
|
0cd45d4ad2 | ||
|
|
3d6b9a2848 | ||
|
|
e28e6484e8 | ||
|
|
4f59eeef05 | ||
|
|
c2f08075ec | ||
|
|
170c9c9525 | ||
|
|
eb8acfd7b1 | ||
|
|
25ea1a0af2 | ||
|
|
4b15b3427f | ||
|
|
17f7c1b782 | ||
|
|
6c27c2cdf2 | ||
|
|
1ab573bf54 | ||
|
|
0a740a24d9 | ||
|
|
3d401d9390 | ||
|
|
6816b51c86 | ||
|
|
9fb9e9f7d5 | ||
|
|
7e7994dbb2 | ||
|
|
63689bfb83 | ||
|
|
45267bb576 | ||
|
|
534491d3aa | ||
|
|
005924f260 | ||
|
|
88c7b4a7eb | ||
|
|
1b47277962 | ||
|
|
5cfcd1c7c2 | ||
|
|
8fecf3aa8c | ||
|
|
fb6d61b58f | ||
|
|
810142dcc4 | ||
|
|
a4072486de | ||
|
|
652019d6da | ||
|
|
3fbff5b4bb | ||
|
|
8d3a52aa30 | ||
|
|
6021f4d83f | ||
|
|
4ab411cab0 | ||
|
|
f9945d81fb | ||
|
|
8ac1f72c9e | ||
|
|
6cac61b6b9 | ||
|
|
6894b498a8 | ||
|
|
5b8874e3f4 | ||
|
|
38a42f97d4 | ||
|
|
0e19d85d37 | ||
|
|
86ff19fade | ||
|
|
1d4632f97f | ||
|
|
0153bc92ab | ||
|
|
d3e1c13e1f | ||
|
|
8a8c78deac | ||
|
|
7733bf9963 | ||
|
|
3f0b3f8f9b | ||
|
|
4943534929 | ||
|
|
240a69ad63 | ||
|
|
ab2e1f5817 | ||
|
|
53126cdceb | ||
|
|
92c82e6952 | ||
|
|
e51ecf71aa | ||
|
|
0a9b0b83eb | ||
|
|
583862e6d1 | ||
|
|
cc482228a4 | ||
|
|
541183b322 | ||
|
|
5e6a6ea340 | ||
|
|
8f089f0229 | ||
|
|
cb246cb9c2 | ||
|
|
a25645a5a6 | ||
|
|
ab455bbada | ||
|
|
c2d6aff64c | ||
|
|
4b185a0fe0 | ||
|
|
d148560f50 | ||
|
|
30434b2beb | ||
|
|
3a49409dae | ||
|
|
2f5b3c0999 | ||
|
|
61cc08cf3c | ||
|
|
8238e5242b | ||
|
|
5d7b9a8320 | ||
|
|
9dcccf784b | ||
|
|
048e304b8a | ||
|
|
e3d9cc2aa5 | ||
|
|
962e1e70a6 | ||
|
|
8a60f30423 | ||
|
|
7fab75a7a6 | ||
|
|
0da0d37f3d | ||
|
|
38005bd854 | ||
|
|
10e50e6bf9 | ||
|
|
c1031d8465 | ||
|
|
4852087e61 | ||
|
|
851b8c6fb6 | ||
|
|
d093c2e358 | ||
|
|
3ff60987f3 | ||
|
|
8acb0482da | ||
|
|
30c858423d | ||
|
|
0b08dce08c | ||
|
|
f177d05441 | ||
|
|
3ab1f0ca3d | ||
|
|
60f06fc4f1 | ||
|
|
cff16d32f9 | ||
|
|
e3f0ba4cd9 | ||
|
|
3629a832e5 | ||
|
|
a6c0441ee0 | ||
|
|
c7c0a5a1b3 | ||
|
|
a1838c5522 | ||
|
|
0c60d1581f | ||
|
|
c55dff95bc | ||
|
|
801bc76ce3 | ||
|
|
f293418d9d | ||
|
|
4eb86fce07 | ||
|
|
1d783794b5 | ||
|
|
4faf0f9098 | ||
|
|
bbadf9b8b1 | ||
|
|
e2409aa496 | ||
|
|
5312376077 | ||
|
|
fec3da7d58 | ||
|
|
a2c73c9b8b | ||
|
|
6111297d91 | ||
|
|
96db66abf0 | ||
|
|
fdc4318ac6 | ||
|
|
463c4c9369 | ||
|
|
f23d100747 | ||
|
|
03483ff370 | ||
|
|
62fd8c4d01 | ||
|
|
78fa4e9856 | ||
|
|
4cfcb3643b | ||
|
|
d417a8fcd0 | ||
|
|
f38719f575 | ||
|
|
1e53007bc3 | ||
|
|
e7c972b04a | ||
|
|
839434abc0 | ||
|
|
015e357fce | ||
|
|
a63027245a | ||
|
|
17ecb9eb1d | ||
|
|
af0d4a048a | ||
|
|
7e0c0dda42 | ||
|
|
7d93652105 | ||
|
|
35d8adefc4 | ||
|
|
8363699f14 | ||
|
|
ce6b2db0f2 | ||
|
|
db76fefd0c | ||
|
|
dd063a0ef7 | ||
|
|
17e2e52c6d | ||
|
|
7f1cd0b73b | ||
|
|
f855b0898b | ||
|
|
c90cb37b2a | ||
|
|
9a9be01ad4 | ||
|
|
a2757e5f16 | ||
|
|
a0b3606f17 | ||
|
|
00e9a94152 | ||
|
|
63345977e2 | ||
|
|
cdff4f7c74 | ||
|
|
b73f54a966 | ||
|
|
b6da218974 | ||
|
|
861dde100a | ||
|
|
e9dd218231 | ||
|
|
74e507962e | ||
|
|
023f6b0a50 | ||
|
|
1537c9dae5 | ||
|
|
48069097ea | ||
|
|
266cd4515a | ||
|
|
e940acd374 | ||
|
|
9765c29be1 | ||
|
|
034d02f8a5 | ||
|
|
785a459a55 | ||
|
|
f957c7e658 | ||
|
|
d7a76d381b | ||
|
|
29b3f00e6f | ||
|
|
0496477f92 | ||
|
|
a0c0349934 | ||
|
|
fb5eadc363 | ||
|
|
c5ba7f23a5 | ||
|
|
f4a6b0395f | ||
|
|
14bff7b451 | ||
|
|
4f9ce4675c | ||
|
|
fc6b8d6af2 | ||
|
|
4fe054c6db | ||
|
|
cfb292cca7 | ||
|
|
af28ac04a4 | ||
|
|
6045ad9a02 | ||
|
|
b83e5aaa54 | ||
|
|
be840f730e | ||
|
|
980a4e0211 | ||
|
|
f2b2a81149 | ||
|
|
77b9ddabe2 | ||
|
|
f00f964abf | ||
|
|
7288f77bbe | ||
|
|
f9c0f043e5 | ||
|
|
ae7c1b139a | ||
|
|
c30c451907 | ||
|
|
c3279944fb | ||
|
|
5a3621460f | ||
|
|
6576b99c24 | ||
|
|
b44015578a | ||
|
|
9ba1beee58 | ||
|
|
f344e9d5a5 | ||
|
|
951a22c244 | ||
|
|
32e5e5232d | ||
|
|
3e956b9229 | ||
|
|
05e895c463 | ||
|
|
9a1c411abd | ||
|
|
b881c2e84c | ||
|
|
6e4ccb99c3 | ||
|
|
9bb45a4037 | ||
|
|
7e74a49142 | ||
|
|
4d4c88f0a7 | ||
|
|
3f327b3db0 | ||
|
|
a3a9ec1211 | ||
|
|
50073dc579 | ||
|
|
fc2796aee8 | ||
|
|
274a5fcb73 |
121 changed files with 1933 additions and 1099 deletions
|
|
@ -25,16 +25,16 @@ packages:
|
|||
- hwdata-dev
|
||||
sources:
|
||||
- https://github.com/swaywm/sway
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git#0.18
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||
tasks:
|
||||
- wlroots: |
|
||||
cd wlroots
|
||||
meson --prefix=/usr build -Dexamples=false
|
||||
meson setup --prefix=/usr build -Dexamples=false
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
- setup: |
|
||||
cd sway
|
||||
meson build --fatal-meson-warnings -Dauto_features=enabled -Dtray=disabled
|
||||
meson setup build --fatal-meson-warnings -Dauto_features=enabled -Dtray=disabled
|
||||
- build: |
|
||||
cd sway
|
||||
ninja -C build
|
||||
|
|
@ -52,5 +52,5 @@ tasks:
|
|||
mkdir subprojects
|
||||
ln -s ../../wlroots subprojects/wlroots
|
||||
rm -rf build
|
||||
meson build --fatal-meson-warnings --default-library=static --force-fallback-for=wlroots
|
||||
meson setup build --fatal-meson-warnings --default-library=static --force-fallback-for=wlroots
|
||||
ninja -C build
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@ packages:
|
|||
- hwdata
|
||||
sources:
|
||||
- https://github.com/swaywm/sway
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git#0.18
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||
tasks:
|
||||
- wlroots: |
|
||||
cd wlroots
|
||||
meson --prefix=/usr build -Dexamples=false
|
||||
meson setup --prefix=/usr build -Dexamples=false
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
- setup: |
|
||||
cd sway
|
||||
meson build --fatal-meson-warnings -Dauto_features=enabled -Dsd-bus-provider=libsystemd
|
||||
meson setup build --fatal-meson-warnings -Dauto_features=enabled -Dsd-bus-provider=libsystemd
|
||||
- build: |
|
||||
cd sway
|
||||
ninja -C build
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ packages:
|
|||
- misc/hwdata
|
||||
sources:
|
||||
- https://github.com/swaywm/sway
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git#0.18
|
||||
- https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||
tasks:
|
||||
- setup: |
|
||||
cd sway
|
||||
|
|
@ -39,7 +39,7 @@ tasks:
|
|||
cd subprojects
|
||||
ln -s ../../wlroots wlroots
|
||||
cd ..
|
||||
meson build --fatal-meson-warnings -Dtray=enabled -Dsd-bus-provider=basu
|
||||
meson setup build --fatal-meson-warnings -Dtray=enabled -Dsd-bus-provider=basu
|
||||
- build: |
|
||||
cd sway
|
||||
ninja -C build
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ _\* Compile-time dep_
|
|||
|
||||
نفذ هذه الأوامر:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
66
README.az.md
Normal file
66
README.az.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# sway
|
||||
|
||||
sway [i3]-ə uyğun [Wayland] kompozitorudur. [Tez-tez verilən sualları] oxuyun.
|
||||
[IRC kanalına] qoşulun ("irc.libera.chat"-da #sway).
|
||||
|
||||
## Buraxılış İmzaları
|
||||
|
||||
Buraxılışlar [E88F5E48] ilə imzalanıb və [GitHub-da][GitHub releases] dərc edilib.
|
||||
|
||||
## Quraşdırma
|
||||
|
||||
### Paketlərdən
|
||||
|
||||
Sway bir çox distributivdə mövcuddur. Öz distributiviniz üçün
|
||||
"sway" paketini quraşdırmağa çalışın.
|
||||
|
||||
### Mənbə kodundan kompilyasiya
|
||||
|
||||
Test və ya inkişaf üçün sway və wlroots-un HEAD-ini qurmaq istəyirsinizsə,
|
||||
[bu viki səhifəsini][Development setup] nəzərdən keçirin.
|
||||
|
||||
Asılılıqları quraşdırın:
|
||||
|
||||
* meson \*
|
||||
* [wlroots]
|
||||
* wayland
|
||||
* wayland-protocols \*
|
||||
* pcre2
|
||||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (ixtiyari: sistem trayı üçün əlavə şəkil formatları)
|
||||
* [swaybg] (ixtiyari: divar kağızı)
|
||||
* [scdoc] (ixtiyari: man səhifələri) \*
|
||||
* git (ixtiyari: versiya məlumatı) \*
|
||||
|
||||
_\* Kompilyasiya asılılıqları_
|
||||
|
||||
Bu əmrləri icra edin:
|
||||
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
## Konfiqurasiya
|
||||
|
||||
Əgər artıq i3-dən istifadə edirsinizsə, i3 konfiqurasiyanızı `~/.config/sway/config`
|
||||
ünvanına köçürün və o, dərhal işləyəcək. Əks halda, nümunə konfiqurasiya faylını
|
||||
`~/.config/sway/config` ünvanına köçürün. O, adətən `/etc/sway/config` ünvanında yerləşir.
|
||||
Konfiqurasiya haqqında məlumat üçün `man 5 sway` əmrini icra edin.
|
||||
|
||||
## İşə Salma
|
||||
|
||||
TTY-dan `sway`-ı işə salın. Bəzi ekran menecerləri işləyə bilər, lakin sway tərəfindən
|
||||
dəstəklənmir (gdm-in kifayət qədər yaxşı işlədiyi məlumdur).
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[Tez-tez verilən sualları]: https://github.com/swaywm/sway/wiki
|
||||
[IRC kanalına]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||
[swaybg]: https://github.com/swaywm/swaybg/
|
||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||
30
README.cs.md
30
README.cs.md
|
|
@ -1,25 +1,24 @@
|
|||
# sway
|
||||
|
||||
[English][en] - [عربي][ar] - **[Česky][cs]** - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
|
||||
sway je s [i3] kompatibilní [Wayland] kompozitor. Přečtěte si [FAQ]. Připojte se na
|
||||
[IRC kanál][IRC channel] \(#sway na irc.libera.chat).
|
||||
sway je [waylandový][Wayland] kompozitor kompatibilní s [i3]. Přečtěte si
|
||||
[FAQ (anglicky)][FAQ]. Připojte se na [IRC kanál (anglicky)][IRC channel]
|
||||
\(#sway na irc.libera.chat).
|
||||
|
||||
## Podpisy vydání
|
||||
|
||||
Vydání jsou podepsána [E88F5E48] a publikována [na GitHubu][GitHub releases].
|
||||
Vydané verze jsou podepsány klíčem [E88F5E48] a publikovány
|
||||
[na GitHubu][GitHub releases].
|
||||
|
||||
## Instalace
|
||||
|
||||
### Z balíčků
|
||||
### Z balíků
|
||||
|
||||
Sway je dostupný ve spoustě distribucí. Zkuste nainstalovat balíček "sway" ve vaší
|
||||
distribuci.
|
||||
Sway je dostupný v mnoha distribucích. Zkuste v té vaší nainstalovat balík "sway".
|
||||
|
||||
### Kompilace ze zdrojových kódů
|
||||
|
||||
Podívejte se na [tuto stránku wiki][Development setup], pokud chcete sestavit HEAD
|
||||
sway a wlroots pro testování nebo vývoj.
|
||||
Pokud chcete sestavit HEAD repozitáře sway a wlroots pro testování nebo vývoj,
|
||||
použijte návod na [této stránce na wiki (anglicky)][Development setup].
|
||||
|
||||
Nainstalujte závislosti:
|
||||
|
||||
|
|
@ -31,16 +30,16 @@ Nainstalujte závislosti:
|
|||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (volitelné: oznamovací oblast)
|
||||
* [swaybg] (volitelné: tapeta)
|
||||
* [scdoc] (volitelné: manuálové stránky) \*
|
||||
* gdk-pixbuf2 (volitelné: dodatečné formáty ikon pro oznamovací oblast)
|
||||
* [swaybg] (volitelné: tapeta plochy)
|
||||
* [scdoc] (volitelné: man stránky) \*
|
||||
* git (volitelné: informace o verzi) \*
|
||||
|
||||
_\* Závislost pouze pro kompilaci_
|
||||
|
||||
Spusťte tyto příkazy:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
@ -53,8 +52,7 @@ Pro více informací o konfiguraci spusťte `man 5 sway`.
|
|||
|
||||
## Spuštění
|
||||
|
||||
Spusťte `sway` z TTY. Některé správce zobrazení mohou fungovat, ale nejsou
|
||||
podporovány sway (je známo, že gdm funguje docela dobře).
|
||||
Spusťte `sway` z TTY nebo ze správce displeje.
|
||||
|
||||
[en]: https://github.com/swaywm/sway#readme
|
||||
[ar]: README.ar.md
|
||||
|
|
|
|||
37
README.de.md
37
README.de.md
|
|
@ -1,21 +1,21 @@
|
|||
# Sway
|
||||
Sway ist ein [i3](https://i3wm.org/)-kompatibler [Wayland](http://wayland.freedesktop.org/)-Compositor. Lies die [FAQ](https://github.com/swaywm/sway/wiki). Tritt dem [IRC Channel](https://web.libera.chat/gamja/?channels=#sway) bei (#sway on irc.libera.chat; Englisch).
|
||||
Sway ist ein [i3]-kompatibler [Wayland]-Compositor. Lies die [FAQ]. Tritt dem [IRC Channel] bei (#sway on irc.libera.chat; Englisch).
|
||||
|
||||
## Signaturen
|
||||
Jedes Release wird mit dem PGP-Schlüssel [E88F5E48](https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48) signiert und [auf GitHub](https://github.com/swaywm/sway/releases) veröffentlicht.
|
||||
Jeder Release wird mit dem PGP-Schlüssel [E88F5E48] signiert und [auf GitHub][GitHub releases] veröffentlicht.
|
||||
|
||||
## Installation
|
||||
|
||||
### Über die Paketverwaltung
|
||||
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Versuche einfach das Packet "sway" zu installieren.
|
||||
Sway kann in vielen Distributionen direkt durch die Paketverwaltung installiert werden. Versuche einfach das Paket "sway" zu installieren.
|
||||
|
||||
### Quellcode selbst kompilieren
|
||||
|
||||
sway benötigt die folgenden Pakete:
|
||||
|
||||
* meson\*
|
||||
* [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots)
|
||||
* meson \*
|
||||
* [wlroots]
|
||||
* wayland
|
||||
* wayland-protocols\*
|
||||
* pcre2
|
||||
|
|
@ -23,21 +23,34 @@ sway benötigt die folgenden Pakete:
|
|||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (Optional, wird für das Benachrichtigungsfeld (System Tray) benötigt)
|
||||
* [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (Optional, wird für die Dokumentation (Man Pages) benötigt)\*
|
||||
* [swaybg] (Optional, wird für das Setzen von Desktophintergrundbildern benötigt)
|
||||
* [scdoc] (Optional, wird für die Dokumentation (Man Pages) benötigt)\*
|
||||
* git (Optional: Versionsinfo)\*
|
||||
|
||||
_\*Werden nur während des Kompilierens benötigt_
|
||||
_\*Werden nur für das Kompilieren benötigt_
|
||||
|
||||
Führe die folgenden Befehle aus:
|
||||
|
||||
meson build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
Schaue in das [Wiki][Development setup] (Englisch) für Informationen, falls du zum Testen oder Entwickeln den neuesten Stand (HEAD) von sway und wlroots kompilieren willst.
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Falls du von i3 migrierst, kannst du deine Konfigurationsdatei nach `~/.config/sway/config` kopieren und die Einstellungen sollten ohne Weiteres funktionieren. Ansonsten kannst du die Beispielkonfiguration, die normalerweise in `/etc/sway/config` liegt, nach `~/.config/sway/config` kopieren. Die Dokumentation zur Konfigurationsdatei findest du in `man 5 sway`.
|
||||
|
||||
## Sway starten
|
||||
Sway kann einfach mit dem Befehl `sway` vom TTY gestartet werden.
|
||||
Display-Manager werden nicht offiziell unterstützt. Es gibt aber durchaus einige, die mit Sway funktionieren (z.B. gdm).
|
||||
Sway kann einfach mit dem Befehl `sway` vom TTY oder mithilfe eines Displaymanagers gestartet werden.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[FAQ]: https://github.com/swaywm/sway/wiki
|
||||
[IRC channel]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||
[swaybg]: https://github.com/swaywm/swaybg
|
||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ _\*Kompileringsafhængighed_
|
|||
|
||||
Kør følgende kommandoer:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -54,8 +54,7 @@ Hvis du allerede bruger i3 kan du bare kopiere din i3 konfiguration til
|
|||
|
||||
## Eksekvering
|
||||
|
||||
Kør `sway` fra en TTY. Nogle display managers kan fungere, men Sway yder ikke
|
||||
support til dem (gdm er kendt for at fungere temmelig godt).
|
||||
Kør `sway` fra en TTY eller fra en display manager.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\*Compile-time dep_
|
|||
|
||||
Desde su consola, ejecute las órdenes:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ _\* Requis uniquement pour la compilation_
|
|||
|
||||
Exécutez ces commandes :
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -61,9 +61,7 @@ documentation pour la configuration de sway.
|
|||
|
||||
## Exécution
|
||||
|
||||
Exécutez `sway` à partir d'un TTY. Certains gestionnaires d'affichage peuvent
|
||||
fonctionner, mais ne sont pas supportés par Sway (gdm est réputé pour assez
|
||||
bien fonctionner).
|
||||
Exécutez `sway` à partir d'un TTY ou d'un gestionnaires d'affichage.
|
||||
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[i3]: https://i3wm.org/
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ _\* Compile-time dep_
|
|||
|
||||
გაუშვით ეს ბრძანებები:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\*Compile-time dep_
|
|||
|
||||
Τρέξτε αυτά τα commands:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ _\* Compilation के समय आवश्यक_
|
|||
|
||||
ये commands चलाएं:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
16
README.hu.md
16
README.hu.md
|
|
@ -1,10 +1,10 @@
|
|||
# sway
|
||||
|
||||
A Sway egy [i3]-kompatibilis [Wayland] kompozitor. Olvasd el a [Gyarkan Ismételt Kérdéseket][FAQ]. Csatlakozz az [IRC csatornához][IRC channel] \(`#sway` az `irc.libera.chat`-en).
|
||||
A Sway egy [i3]-kompatibilis [Wayland]-kompozitor. Olvasd el a [Gyarkan Ismételt Kérdéseket][FAQ]. Csatlakozz az [IRC-csatornához][IRC channel] \(`#sway` az `irc.libera.chat`-en).
|
||||
|
||||
## Csomag aláírások
|
||||
## Csomagaláírások
|
||||
|
||||
A kiadott csomagok az [E88F5E48] kulccsal vannak aláírva és [GitHub-on][GitHub releases] publikálva.
|
||||
A kiadott csomagok az [E88F5E48] kulccsal vannak aláírva, és [GitHubon][GitHub releases] publikálva.
|
||||
|
||||
## Telepítés
|
||||
|
||||
|
|
@ -13,12 +13,12 @@ A kiadott csomagok az [E88F5E48] kulccsal vannak aláírva és [GitHub-on][GitHu
|
|||
A Sway sok disztribúció csomagkezelőjéből elérhető, próbáld meg a "sway"
|
||||
csomagot telepíteni az általad használt eszközzel.
|
||||
|
||||
Ha szeretnél csomagot készíteni a saját disztribúciódhoz, ugorj be az IRC
|
||||
Ha szeretnél csomagot készíteni a saját disztribúciódhoz, ugorj be az IRC-
|
||||
csatornára, vagy küldj levelet a sir@cmpwn.com címre tanácsokért.
|
||||
|
||||
### Fordítás forráskódból
|
||||
|
||||
Olvasd el [ezt a wiki oldalt][Development setup], ha szeretnéd tesztelési vagy
|
||||
Olvasd el [ezt a wikioldalt][Development setup], ha szeretnéd tesztelési vagy
|
||||
fejlesztési célokból lefordítani az aktuális (HEAD) állapotát a `sway`-nek és a
|
||||
`wlroots`-nak.
|
||||
|
||||
|
|
@ -40,13 +40,13 @@ _\*Fordításidejű függőség_
|
|||
|
||||
Futtasd ezeket a parancsokat:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
## Konfiguráció
|
||||
|
||||
Ha előzőleg i3-mat használtál, akkor átmásolhatod az i3 beállításaidat a
|
||||
Ha előzőleg i3-at használtál, akkor átmásolhatod az i3-beállításaidat a
|
||||
`~/.config/sway/config` file-ba és ugyanúgy működni fognak. Egyéb esetben másold
|
||||
le kiindulási alapnak a mintát, ami általában az `etc/sway/config` elérési
|
||||
útvonalon található.
|
||||
|
|
@ -55,7 +55,7 @@ kapcsolatban.
|
|||
|
||||
## Futtatás
|
||||
|
||||
Futtasd a `sway` parancsot egy TTY felületről. Néhány bejelentkezéskezelő
|
||||
Futtasd a `sway` parancsot egy TTY-felületről. Néhány bejelentkezéskezelő
|
||||
(display manager) működhet, de alapvetően nem támogatottak a sway által. (A
|
||||
gdm-ről ismeretes, hogy egész jól működik.)
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ _\*نیازمندیهای زمان کامپایل برنامه_
|
|||
|
||||
این فرمانها را اجرا کنید:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# sway
|
||||
|
||||
sway è un compositore di [Wayland] compatibile con [i3]. Leggi le [FAQ].
|
||||
Unisciti al [canale di IRC] \(#sway su irc.libera.chat).
|
||||
Unisciti al [canale IRC] \(#sway su irc.libera.chat).
|
||||
|
||||
## Firma delle versioni
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ _\* Dipendenza necessaria per la compilazione_
|
|||
|
||||
Esegui questi comandi:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
@ -52,13 +52,12 @@ configurazione.
|
|||
|
||||
## Esecuzione
|
||||
|
||||
Lancia `sway` da un TTY. Alcuni gestori d'accesso potrebbero funzionare ma non
|
||||
sono supportati da sway (gdm funziona abbastanza bene).
|
||||
Lancia `sway` da un TTY o da un display manager.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[FAQ]: https://github.com/swaywm/sway/wiki
|
||||
[canale di IRC]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[canale IRC]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ _\*コンパイル時の依存_
|
|||
|
||||
次のコマンドを実行してください:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -52,5 +52,4 @@ _\*コンパイル時の依存_
|
|||
|
||||
## 実行
|
||||
|
||||
`sway`をTTYから実行してください。いくつかのディスプレイマネージャは動くかもしれませんが、Swayからサポートされていません(gdmは非常に良く動作することが知られています)。
|
||||
|
||||
`sway`をTTYまたはディスプレイマネージャから実行してください。
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ _\*컴파일 떄 필요_
|
|||
|
||||
다음 명령을 실행하세요:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -52,4 +52,4 @@ i3를 이미 사용 중이라면, i3 config을 `~/.config/sway/config`로 복사
|
|||
|
||||
## 실행
|
||||
|
||||
TTY에서 `sway`를 실행하세요. 일부 display manager는 작동하지만, sway로 부터 지원되지 않습니다(gdm은 상당히 잘 작동한다고 알려져 있습니다).
|
||||
TTY나 display manager에서 `sway`를 실행하세요.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# sway
|
||||
|
||||
**[English][en]** - [عربي][ar] - [Česky][cs] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
**[English][en]** - [عربي][ar] - [Azərbaycanca][az] - [Česky][cs] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - [ქართული][ge] - [Ελληνικά][gr] - [हिन्दी][hi] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Norsk][no] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Српски][sr] - [Svenska][sv] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
|
||||
sway is an [i3]-compatible [Wayland] compositor. Read the [FAQ]. Join the
|
||||
[IRC channel] \(#sway on irc.libera.chat).
|
||||
|
|
@ -40,7 +40,7 @@ _\* Compile-time dep_
|
|||
|
||||
Run these commands:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
@ -53,11 +53,11 @@ Run `man 5 sway` for information on the configuration.
|
|||
|
||||
## Running
|
||||
|
||||
Run `sway` from a TTY. Some display managers may work but are not supported by
|
||||
sway (gdm is known to work fairly well).
|
||||
Run `sway` from a TTY or from a display manager.
|
||||
|
||||
[en]: https://github.com/swaywm/sway#readme
|
||||
[ar]: README.ar.md
|
||||
[az]: README.az.md
|
||||
[cs]: README.cs.md
|
||||
[de]: README.de.md
|
||||
[dk]: README.dk.md
|
||||
|
|
@ -77,6 +77,7 @@ sway (gdm is known to work fairly well).
|
|||
[pt]: README.pt.md
|
||||
[ro]: README.ro.md
|
||||
[ru]: README.ru.md
|
||||
[sr]: README.sr.md
|
||||
[sv]: README.sv.md
|
||||
[tr]: README.tr.md
|
||||
[uk]: README.uk.md
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\* Compileerafhankelijkheden_
|
|||
|
||||
Voer deze opdrachten uit:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
51
README.no.md
51
README.no.md
|
|
@ -1,29 +1,25 @@
|
|||
# Sway
|
||||
|
||||
Sway er en [i3]-kompatibel [Wayland] compositor. Les [Ofte stilte spørsmål].
|
||||
Delta på [IRC kanalen][IRC kanal] \(#sway på irc.libera.chat).
|
||||
Sway er en [i3]-kompatibel [Wayland]-compositor. Les [Ofte stilte spørsmål].
|
||||
Delta på [IRC-kanalen][IRC-kanal] \(#sway på irc.libera.chat).
|
||||
|
||||
## Utgivelses Signaturer
|
||||
## Signaturer
|
||||
|
||||
Utgivelser er signert med [E88F5E48] og publisert [på GitHub][GitHub
|
||||
releases].
|
||||
Utgivelser er signert med [E88F5E48] og publisert [på GitHub][GitHub releases].
|
||||
|
||||
## Installasjon
|
||||
|
||||
### Fra system pakker
|
||||
### Fra systempakker
|
||||
|
||||
Sway er tilgjengelig i mange distribusjoner. Prøv å installere "sway" pakken
|
||||
Sway er tilgjengelig i mange distribusjoner. Prøv å installere pakken "sway"
|
||||
fra din distro sine repoer.
|
||||
|
||||
Er du interessert i å pakke Sway for din distribusjon kan du ta turen innom
|
||||
IRC-kanalen eller send en e-post til sir@cmpwn.com for råd.
|
||||
|
||||
### Kompilering fra kildekode
|
||||
|
||||
Se [denne wiki-siden][Oppsetting for utvikling] hvis du vil bygge fra HEAD grenen av sway og
|
||||
wlroots for testing eller utvikling.
|
||||
Se [denne wiki-siden][Oppsetting for utvikling] hvis du vil bygge fra HEAD-grenen av
|
||||
sway og wlroots for testing eller utvikling.
|
||||
|
||||
Installasjonsavhengigheter:
|
||||
Installer avhengigheter:
|
||||
|
||||
* meson \*
|
||||
* [wlroots]
|
||||
|
|
@ -33,36 +29,37 @@ Installasjonsavhengigheter:
|
|||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (valgfritt: system tray)
|
||||
* gdk-pixbuf2 (valgfritt: støtte for ekstra bildeformater i system tray)
|
||||
* [swaybg] (valgfritt: bakgrunnsbilde)
|
||||
* [scdoc] (valgfritt: man pages) \*
|
||||
* git \*
|
||||
* git (valgfritt: versjonsinformasjon) \*
|
||||
|
||||
_\*Kompileringsavhengigheter_
|
||||
_\* Kompileringsavhengigheter_
|
||||
|
||||
Kjør følgende kommandoer:
|
||||
|
||||
meson build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
## Konfigurasjon
|
||||
|
||||
Hvis du allerede bruker i3 kan du bare kopiere din i3 konfigurasjon til
|
||||
`~/.config/sway/config`. Ellers skal du kopiere eksempel konfigurasjonsfilen til
|
||||
`~/.config/sway/config`. Eksempel filen er normalt plasert i `/etc/sway/config`. Kjør
|
||||
`man 5 sway` for å få oplysninger om konfigurasjonen.
|
||||
Hvis du allerede bruker i3 kan du bare kopiere din i3-konfigurasjon til
|
||||
`~/.config/sway/config`. Ellers skal du kopiere eksempelkonfigurasjonsfilen til
|
||||
`~/.config/sway/config`. Eksempelfilen er normalt plasert i `/etc/sway/config`.
|
||||
Kjør `man 5 sway` for å få opplysninger om konfigurasjonen.
|
||||
|
||||
## Utførelse
|
||||
## Kjøring
|
||||
|
||||
Kjør `sway` fra en TTY. Noen display managers kan fungere, men Sway har ikke
|
||||
støtte for dem (gdm er kjent for å fungere ganske bra).
|
||||
Kjør `sway` fra en TTY eller fra en display manager.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[Ofte stilte spørsmål]: https://github.com/swaywm/sway/wiki
|
||||
[IRC kanal]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[IRC-kanal]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Oppsetting for utvikling]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||
[swaybg]: https://github.com/swaywm/swaybg/
|
||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\*zależności kompilacji_
|
|||
|
||||
Wykonaj następujące polecenia:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -53,5 +53,4 @@ Wykonaj polecenie `man 5 sway` aby uzyskać informacje dotyczące konfiguracji.
|
|||
|
||||
## Uruchamianie
|
||||
|
||||
Wykonaj polecenie `sway` z poziomu TTY. Niektóre menedżery wyświetlania mogą umożliwiać rozruch z ich
|
||||
poziomu, ale nie jest to wspierane przez sway (w gdm podobno działa to całkiem nieźle).
|
||||
Wykonaj polecenie `sway` z poziomu TTY lub menedżera wyświetlania.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ _\*Dependência de tempo de compilação_
|
|||
|
||||
Execute esses comandos:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ Dependențe pentru instalare:
|
|||
Rulați aceste comenzi:
|
||||
|
||||
```
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
```
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ _\*Зависимости для сборки_
|
|||
|
||||
Выполните эти команды:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
@ -54,8 +54,7 @@ _\*Зависимости для сборки_
|
|||
|
||||
## Запуск
|
||||
|
||||
Выполните команду `sway` прямо из TTY. Некоторые дисплейные менеджеры могут работать, но они не поддерживаются со стороны
|
||||
sway (gdm работает довольно неплохо).
|
||||
Выполните команду `sway` прямо из TTY или дисплейного менеджера.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
|
|
|
|||
65
README.sr.md
Normal file
65
README.sr.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# sway
|
||||
|
||||
sway је [i3]-компатибилан [Wayland] композитор. Прочитајте [FAQ]. Придружите се
|
||||
[IRC каналу] \(#sway на irc.libera.chat).
|
||||
|
||||
## Потписи Издања
|
||||
|
||||
Издања су потписана са [E88F5E48] и објављена [на GitHub-у][GitHub releases].
|
||||
|
||||
## Инсталација
|
||||
|
||||
### Из пакета
|
||||
|
||||
Sway је доступан у многим дистрибуцијама. Покушајте да инсталирате "sway" пакет за
|
||||
вашу.
|
||||
|
||||
### Компајлирање из Извора
|
||||
|
||||
Погледајте [ову вики страницу][Development setup], ако желите да компајлирате HEAD верзију
|
||||
sway-а и wlroots-а за тестирање или развој.
|
||||
|
||||
Инсталирајте зависности:
|
||||
|
||||
* meson \*
|
||||
* [wlroots]
|
||||
* wayland
|
||||
* wayland-protocols \*
|
||||
* pcre2
|
||||
* json-c
|
||||
* pango
|
||||
* cairo
|
||||
* gdk-pixbuf2 (опционо: додатни формати слика за системску траку)
|
||||
* [swaybg] (опционо: позадина)
|
||||
* [scdoc] (опционо: man странице) \*
|
||||
* git (опционо: информације о верзији) \*
|
||||
|
||||
_\* Потребно само за компајлирање_
|
||||
|
||||
Покрените следеће команде:
|
||||
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
## Конфигурација
|
||||
|
||||
Ако већ користите i3, копирајте вашу i3 конфигурацију у `~/.config/sway/config` и
|
||||
радиће одмах. У супротном, копирајте пример конфигурационе датотеке у
|
||||
`~/.config/sway/config`. Обично се налази у `/etc/sway/config`.
|
||||
Покрените `man 5 sway` за информације о конфигурацији.
|
||||
|
||||
## Покретање
|
||||
|
||||
Покрените `sway` из TTY-a или из менаџера приказа.
|
||||
|
||||
[i3]: https://i3wm.org/
|
||||
[Wayland]: http://wayland.freedesktop.org/
|
||||
[FAQ]: https://github.com/swaywm/sway/wiki
|
||||
[IRC каналу]: https://web.libera.chat/gamja/?channels=#sway
|
||||
[E88F5E48]: https://keys.openpgp.org/search?q=34FF9526CFEF0E97A340E2E40FDE7BE0E88F5E48
|
||||
[GitHub releases]: https://github.com/swaywm/sway/releases
|
||||
[Development setup]: https://github.com/swaywm/sway/wiki/Development-Setup
|
||||
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots
|
||||
[swaybg]: https://github.com/swaywm/swaybg/
|
||||
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
# sway
|
||||
|
||||
[English][en] - [Deutsch][de] - [Dansk][dk] - [Español][es] - [Français][fr] - **[Svenska][sv]** - [Ελληνικά][gr] - [Magyar][hu] - [فارسی][ir] - [Italiano][it] - [日本語][ja] - [한국어][ko] - [Nederlands][nl] - [Polski][pl] - [Português][pt] - [Română][ro] - [Русский][ru] - [Türkçe][tr] - [Українська][uk] - [中文-简体][zh-CN] - [中文-繁體][zh-TW]
|
||||
|
||||
sway är en [i3]-kompatibel [Wayland] compositor. Läs våran [FAQ]-sida. Gå med i vår
|
||||
[IRC-kanal] \(#sway på irc.libera.chat).
|
||||
|
||||
|
|
@ -37,7 +35,7 @@ _\* Krav för kompilering_
|
|||
|
||||
Kör dessa kommandon:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ _\*Derleme-anı bağımlılıkları_
|
|||
|
||||
Şu komutları çalıştırın:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ _\*Лише для компіляції_
|
|||
|
||||
Виконайте ці команди:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ _\*编译时依赖_
|
|||
|
||||
运行如下命令:
|
||||
|
||||
meson build/
|
||||
meson setup build/
|
||||
ninja -C build/
|
||||
sudo ninja -C build/ install
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\*編譯時相依_
|
|||
|
||||
執行這些指令:
|
||||
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
|
|
|
|||
|
|
@ -360,3 +360,7 @@ char *format_str(const char *fmt, ...) {
|
|||
va_end(args);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool has_prefix(const char *str, const char *prefix) {
|
||||
return strncmp(str, prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,3 +141,9 @@ bool sway_set_cloexec(int fd, bool cloexec) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t get_current_time_in_msec(void) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
||||
}
|
||||
|
|
|
|||
17
config.in
17
config.in
|
|
@ -46,14 +46,18 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
|
|||
#
|
||||
# Example configuration:
|
||||
#
|
||||
# input "2:14:SynPS/2_Synaptics_TouchPad" {
|
||||
# input type:touchpad {
|
||||
# dwt enabled
|
||||
# tap enabled
|
||||
# natural_scroll enabled
|
||||
# middle_emulation enabled
|
||||
# }
|
||||
#
|
||||
# You can get the names of your inputs by running: swaymsg -t get_inputs
|
||||
# input type:keyboard {
|
||||
# xkb_layout "eu"
|
||||
# }
|
||||
#
|
||||
# You can also configure each device individually.
|
||||
# Read `man 5 sway-input` for more information about this section.
|
||||
|
||||
### Key bindings
|
||||
|
|
@ -201,9 +205,18 @@ bindsym $mod+r mode "resize"
|
|||
bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
|
||||
bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
|
||||
bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
|
||||
|
||||
# Special keys to control media via playerctl
|
||||
bindsym --locked XF86AudioPlay exec playerctl play-pause
|
||||
bindsym --locked XF86AudioPause exec playerctl play-pause
|
||||
bindsym --locked XF86AudioPrev exec playerctl previous
|
||||
bindsym --locked XF86AudioNext exec playerctl next
|
||||
bindsym --locked XF86AudioStop exec playerctl stop
|
||||
|
||||
# Special keys to adjust brightness via brightnessctl
|
||||
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
|
||||
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
|
||||
|
||||
# Special key to take a screenshot with grim
|
||||
bindsym Print exec grim
|
||||
|
||||
|
|
|
|||
|
|
@ -40,4 +40,6 @@ bool expand_path(char **path);
|
|||
char *vformat_str(const char *fmt, va_list args) _SWAY_ATTRIB_PRINTF(1, 0);
|
||||
char *format_str(const char *fmt, ...) _SWAY_ATTRIB_PRINTF(1, 2);
|
||||
|
||||
bool has_prefix(const char *str, const char *prefix);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -290,6 +290,7 @@ sway_cmd output_cmd_color_profile;
|
|||
sway_cmd output_cmd_disable;
|
||||
sway_cmd output_cmd_dpms;
|
||||
sway_cmd output_cmd_enable;
|
||||
sway_cmd output_cmd_hdr;
|
||||
sway_cmd output_cmd_max_render_time;
|
||||
sway_cmd output_cmd_mode;
|
||||
sway_cmd output_cmd_modeline;
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ enum scale_filter_mode {
|
|||
};
|
||||
|
||||
enum render_bit_depth {
|
||||
RENDER_BIT_DEPTH_DEFAULT, // the default is currently 8
|
||||
RENDER_BIT_DEPTH_DEFAULT, // the default is currently 8 for SDR, 10 for HDR
|
||||
RENDER_BIT_DEPTH_6,
|
||||
RENDER_BIT_DEPTH_8,
|
||||
RENDER_BIT_DEPTH_10,
|
||||
|
|
@ -291,6 +291,7 @@ struct output_config {
|
|||
bool set_color_transform;
|
||||
struct wlr_color_transform *color_transform;
|
||||
int allow_tearing;
|
||||
int hdr;
|
||||
|
||||
char *background;
|
||||
char *background_option;
|
||||
|
|
@ -705,6 +706,8 @@ struct output_config *find_output_config(struct sway_output *output);
|
|||
void free_output_config(struct output_config *oc);
|
||||
|
||||
void request_modeset(void);
|
||||
void force_modeset(void);
|
||||
bool modeset_is_pending(void);
|
||||
|
||||
bool spawn_swaybg(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ struct criteria {
|
|||
char urgent; // 'l' for latest or 'o' for oldest
|
||||
struct pattern *workspace;
|
||||
pid_t pid;
|
||||
struct pattern *sandbox_engine;
|
||||
struct pattern *sandbox_app_id;
|
||||
struct pattern *sandbox_instance_id;
|
||||
struct pattern *tag;
|
||||
};
|
||||
|
||||
bool criteria_is_empty(struct criteria *criteria);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ enum sway_idle_inhibit_mode {
|
|||
struct sway_idle_inhibit_manager_v1 {
|
||||
struct wlr_idle_inhibit_manager_v1 *wlr_manager;
|
||||
struct wl_listener new_idle_inhibitor_v1;
|
||||
struct wl_listener manager_destroy;
|
||||
struct wl_list inhibitors;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ struct sway_input_manager {
|
|||
|
||||
struct sway_input_manager *input_manager_create(struct sway_server *server);
|
||||
|
||||
void input_manager_finish(struct sway_input_manager *input);
|
||||
|
||||
bool input_manager_has_focus(struct sway_node *node);
|
||||
|
||||
void input_manager_set_focus(struct sway_node *node);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ struct sway_input_method_relay {
|
|||
struct wlr_input_method_v2 *input_method; // doesn't have to be present
|
||||
|
||||
struct wl_listener text_input_new;
|
||||
struct wl_listener text_input_manager_destroy;
|
||||
|
||||
struct wl_listener input_method_new;
|
||||
struct wl_listener input_method_manager_destroy;
|
||||
struct wl_listener input_method_commit;
|
||||
struct wl_listener input_method_new_popup_surface;
|
||||
struct wl_listener input_method_grab_keyboard;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ struct sway_layer_surface {
|
|||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener surface_commit;
|
||||
struct wl_listener output_destroy;
|
||||
struct wl_listener node_destroy;
|
||||
struct wl_listener new_popup;
|
||||
|
||||
|
|
@ -19,6 +18,8 @@ struct sway_layer_surface {
|
|||
struct sway_popup_desc desc;
|
||||
|
||||
struct sway_output *output;
|
||||
struct wl_list link; // sway_output.layer_surfaces
|
||||
|
||||
struct wlr_scene_layer_surface_v1 *scene;
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
|
|
@ -41,4 +42,6 @@ struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
|||
|
||||
void arrange_layers(struct sway_output *output);
|
||||
|
||||
void destroy_layers(struct sway_output *output);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,28 +52,25 @@ struct sway_output {
|
|||
|
||||
bool enabled;
|
||||
list_t *workspaces;
|
||||
struct wl_list layer_surfaces; // sway_layer_surface.link
|
||||
|
||||
struct sway_output_state current;
|
||||
|
||||
struct wl_listener layout_destroy;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener present;
|
||||
struct wl_listener frame;
|
||||
struct wl_listener request_state;
|
||||
|
||||
struct {
|
||||
struct wl_signal disable;
|
||||
} events;
|
||||
|
||||
struct wlr_color_transform *color_transform;
|
||||
|
||||
struct timespec last_presentation;
|
||||
uint32_t refresh_nsec;
|
||||
int max_render_time; // In milliseconds
|
||||
struct wl_event_source *repaint_timer;
|
||||
bool gamma_lut_changed;
|
||||
|
||||
bool allow_tearing;
|
||||
bool hdr;
|
||||
};
|
||||
|
||||
struct sway_output_non_desktop {
|
||||
|
|
@ -93,6 +90,9 @@ struct sway_output *output_from_wlr_output(struct wlr_output *output);
|
|||
struct sway_output *output_get_in_direction(struct sway_output *reference,
|
||||
enum wlr_direction direction);
|
||||
|
||||
void output_configure_scene(struct sway_output *output,
|
||||
struct wlr_scene_node *node, float opacity);
|
||||
|
||||
void output_add_workspace(struct sway_output *output,
|
||||
struct sway_workspace *workspace);
|
||||
|
||||
|
|
@ -131,14 +131,13 @@ struct sway_container *output_find_container(struct sway_output *output,
|
|||
|
||||
void output_get_box(struct sway_output *output, struct wlr_box *box);
|
||||
|
||||
bool output_supports_hdr(struct wlr_output *output, const char **unsupported_reason_ptr);
|
||||
|
||||
enum sway_container_layout output_get_default_layout(
|
||||
struct sway_output *output);
|
||||
|
||||
enum wlr_direction opposite_direction(enum wlr_direction d);
|
||||
|
||||
|
||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct sway_session_lock {
|
|||
struct sway_server {
|
||||
struct wl_display *wl_display;
|
||||
struct wl_event_loop *wl_event_loop;
|
||||
const char *socket;
|
||||
char *socket;
|
||||
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_session *session;
|
||||
|
|
@ -46,6 +46,7 @@ struct sway_server {
|
|||
|
||||
struct wl_listener new_output;
|
||||
struct wl_listener renderer_lost;
|
||||
struct wl_event_source *recreating_renderer;
|
||||
|
||||
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
||||
struct sway_idle_inhibit_manager_v1 idle_inhibit_manager_v1;
|
||||
|
|
@ -104,17 +105,24 @@ struct sway_server {
|
|||
struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list;
|
||||
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
|
||||
struct wlr_content_type_manager_v1 *content_type_manager_v1;
|
||||
struct wlr_data_control_manager_v1 *data_control_manager_v1;
|
||||
struct wlr_data_control_manager_v1 *wlr_data_control_manager_v1;
|
||||
struct wlr_ext_data_control_manager_v1 *ext_data_control_manager_v1;
|
||||
struct wlr_screencopy_manager_v1 *screencopy_manager_v1;
|
||||
struct wlr_ext_image_copy_capture_manager_v1 *ext_image_copy_capture_manager_v1;
|
||||
struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1;
|
||||
struct wlr_security_context_manager_v1 *security_context_manager_v1;
|
||||
|
||||
struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *ext_foreign_toplevel_image_capture_source_manager_v1;
|
||||
struct wl_listener new_foreign_toplevel_capture_request;
|
||||
|
||||
struct wlr_xdg_activation_v1 *xdg_activation_v1;
|
||||
struct wl_listener xdg_activation_v1_request_activate;
|
||||
struct wl_listener xdg_activation_v1_new_token;
|
||||
|
||||
struct wl_listener xdg_toplevel_tag_manager_v1_set_tag;
|
||||
|
||||
struct wl_listener request_set_cursor_shape;
|
||||
|
||||
|
||||
struct wlr_tearing_control_manager_v1 *tearing_control_v1;
|
||||
struct wl_listener tearing_control_new_object;
|
||||
struct wl_list tearing_controllers; // sway_tearing_controller::link
|
||||
|
|
@ -148,20 +156,19 @@ struct sway_debug {
|
|||
bool noatomic; // Ignore atomic layout updates
|
||||
bool txn_timings; // Log verbose messages about transactions
|
||||
bool txn_wait; // Always wait for the timeout before applying
|
||||
bool legacy_wl_drm; // Enable the legacy wl_drm interface
|
||||
};
|
||||
|
||||
extern struct sway_debug debug;
|
||||
|
||||
extern bool allow_unsupported_gpu;
|
||||
|
||||
void sway_terminate(int exit_code);
|
||||
|
||||
bool server_init(struct sway_server *server);
|
||||
void server_fini(struct sway_server *server);
|
||||
bool server_start(struct sway_server *server);
|
||||
void server_run(struct sway_server *server);
|
||||
|
||||
void restore_nofile_limit(void);
|
||||
|
||||
void handle_new_output(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ struct sway_container {
|
|||
|
||||
struct wl_listener output_enter;
|
||||
struct wl_listener output_leave;
|
||||
struct wl_listener output_handler_destroy;
|
||||
|
||||
struct sway_container_state current;
|
||||
struct sway_container_state pending;
|
||||
|
|
@ -102,7 +103,7 @@ struct sway_container {
|
|||
char *title; // The view's title (unformatted)
|
||||
char *formatted_title; // The title displayed in the title bar
|
||||
int title_width;
|
||||
|
||||
|
||||
char *title_format;
|
||||
|
||||
enum sway_container_layout prev_split_layout;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ enum sway_view_type {
|
|||
enum sway_view_prop {
|
||||
VIEW_PROP_TITLE,
|
||||
VIEW_PROP_APP_ID,
|
||||
VIEW_PROP_TAG,
|
||||
VIEW_PROP_CLASS,
|
||||
VIEW_PROP_INSTANCE,
|
||||
VIEW_PROP_WINDOW_TYPE,
|
||||
|
|
@ -69,6 +70,9 @@ struct sway_view {
|
|||
struct wlr_scene_tree *content_tree;
|
||||
struct wlr_scene_tree *saved_surface_tree;
|
||||
|
||||
struct wlr_scene *image_capture_scene;
|
||||
struct wlr_ext_image_capture_source_v1 *image_capture_source;
|
||||
|
||||
struct sway_container *container; // NULL if unmapped and transactions finished
|
||||
struct wlr_surface *surface; // NULL for unmapped views
|
||||
struct sway_xdg_decoration *xdg_decoration;
|
||||
|
|
@ -124,6 +128,9 @@ struct sway_view {
|
|||
struct sway_xdg_shell_view {
|
||||
struct sway_view view;
|
||||
|
||||
struct wlr_scene_tree *image_capture_tree;
|
||||
char *tag;
|
||||
|
||||
struct wl_listener commit;
|
||||
struct wl_listener request_move;
|
||||
struct wl_listener request_resize;
|
||||
|
|
@ -142,6 +149,8 @@ struct sway_xwayland_view {
|
|||
|
||||
struct wlr_scene_tree *surface_tree;
|
||||
|
||||
struct wlr_scene_surface *image_capture_scene_surface;
|
||||
|
||||
struct wl_listener commit;
|
||||
struct wl_listener request_move;
|
||||
struct wl_listener request_resize;
|
||||
|
|
@ -192,10 +201,12 @@ struct sway_popup_desc {
|
|||
|
||||
struct sway_xdg_popup {
|
||||
struct sway_view *view;
|
||||
struct wlr_xdg_popup *wlr_xdg_popup;
|
||||
|
||||
struct wlr_scene_tree *scene_tree;
|
||||
struct wlr_scene_tree *xdg_surface_tree;
|
||||
struct wlr_xdg_popup *wlr_xdg_popup;
|
||||
|
||||
struct wlr_scene_tree *image_capture_tree;
|
||||
|
||||
struct sway_popup_desc desc;
|
||||
|
||||
|
|
@ -221,6 +232,14 @@ const char *view_get_window_role(struct sway_view *view);
|
|||
|
||||
uint32_t view_get_window_type(struct sway_view *view);
|
||||
|
||||
const char *view_get_sandbox_engine(struct sway_view *view);
|
||||
|
||||
const char *view_get_sandbox_app_id(struct sway_view *view);
|
||||
|
||||
const char *view_get_sandbox_instance_id(struct sway_view *view);
|
||||
|
||||
const char *view_get_tag(struct sway_view *view);
|
||||
|
||||
const char *view_get_shell(struct sway_view *view);
|
||||
|
||||
void view_get_constraints(struct sway_view *view, double *min_width,
|
||||
|
|
@ -345,4 +364,6 @@ void view_send_frame_done(struct sway_view *view);
|
|||
|
||||
bool view_can_tear(struct sway_view *view);
|
||||
|
||||
void xdg_toplevel_tag_manager_v1_handle_set_tag(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ void workspace_output_add_priority(struct sway_workspace *workspace,
|
|||
struct sway_output *output);
|
||||
|
||||
struct sway_output *workspace_output_get_highest_available(
|
||||
struct sway_workspace *ws, struct sway_output *exclude);
|
||||
struct sway_workspace *ws);
|
||||
|
||||
void workspace_detect_urgent(struct sway_workspace *workspace);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ struct box_colors {
|
|||
uint32_t text;
|
||||
};
|
||||
|
||||
struct box_size {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
struct config_output {
|
||||
struct wl_list link; // swaybar_config::outputs
|
||||
char *name;
|
||||
|
|
|
|||
|
|
@ -61,4 +61,6 @@ const char *sway_wl_output_subpixel_to_string(enum wl_output_subpixel subpixel);
|
|||
|
||||
bool sway_set_cloexec(int fd, bool cloexec);
|
||||
|
||||
uint32_t get_current_time_in_msec(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
46
meson.build
46
meson.build
|
|
@ -1,13 +1,14 @@
|
|||
project(
|
||||
'sway',
|
||||
'c',
|
||||
version: '1.10-rc4',
|
||||
version: '1.12-dev',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.60.0',
|
||||
meson_version: '>=1.3',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
'warning_level=2',
|
||||
'werror=true',
|
||||
'wrap_mode=nodownload',
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -38,14 +39,14 @@ if is_freebsd
|
|||
endif
|
||||
|
||||
# Execute the wlroots subproject, if any
|
||||
wlroots_version = ['>=0.18.0', '<0.19.0']
|
||||
wlroots_version = ['>=0.20.0', '<0.21.0']
|
||||
subproject(
|
||||
'wlroots',
|
||||
default_options: ['examples=false'],
|
||||
required: false,
|
||||
version: wlroots_version,
|
||||
)
|
||||
wlroots = dependency('wlroots-0.18', version: wlroots_version, fallback: 'wlroots')
|
||||
wlroots = dependency('wlroots-0.20', version: wlroots_version, fallback: 'wlroots')
|
||||
wlroots_features = {
|
||||
'xwayland': false,
|
||||
'libinput_backend': false,
|
||||
|
|
@ -64,7 +65,7 @@ pcre2 = dependency('libpcre2-8')
|
|||
wayland_server = dependency('wayland-server', version: '>=1.21.0')
|
||||
wayland_client = dependency('wayland-client')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.24', default_options: ['tests=false'])
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.41', default_options: ['tests=false'])
|
||||
xkbcommon = dependency('xkbcommon', version: '>=1.5.0')
|
||||
cairo = dependency('cairo')
|
||||
pango = dependency('pango')
|
||||
|
|
@ -79,7 +80,7 @@ libudev = wlroots_features['libinput_backend'] ? dependency('libudev') : null_de
|
|||
math = cc.find_library('m')
|
||||
rt = cc.find_library('rt')
|
||||
xcb_icccm = wlroots_features['xwayland'] ? dependency('xcb-icccm') : null_dep
|
||||
threads = dependency('threads') # for pthread_setschedparam
|
||||
threads = dependency('threads') # for pthread_setschedparam and pthread_atfork
|
||||
|
||||
if get_option('sd-bus-provider') == 'auto'
|
||||
if not get_option('tray').disabled()
|
||||
|
|
@ -109,11 +110,9 @@ conf_data.set10('HAVE_LIBSYSTEMD', sdbus.found() and sdbus.name() == 'libsystemd
|
|||
conf_data.set10('HAVE_LIBELOGIND', sdbus.found() and sdbus.name() == 'libelogind')
|
||||
conf_data.set10('HAVE_BASU', sdbus.found() and sdbus.name() == 'basu')
|
||||
conf_data.set10('HAVE_TRAY', have_tray)
|
||||
conf_data.set10('HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM', cc.has_header_symbol(
|
||||
'libinput.h',
|
||||
'LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM',
|
||||
dependencies: libinput,
|
||||
))
|
||||
foreach sym : ['LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM', 'LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY']
|
||||
conf_data.set10('HAVE_' + sym, cc.has_header_symbol('libinput.h', sym, dependencies: libinput))
|
||||
endforeach
|
||||
|
||||
scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages'))
|
||||
if scdoc.found()
|
||||
|
|
@ -172,31 +171,10 @@ if git.found()
|
|||
endif
|
||||
add_project_arguments('-DSWAY_VERSION=@0@'.format(version), language: 'c')
|
||||
|
||||
# Compute the relative path used by compiler invocations.
|
||||
source_root = meson.current_source_dir().split('/')
|
||||
build_root = meson.global_build_root().split('/')
|
||||
relative_dir_parts = []
|
||||
i = 0
|
||||
in_prefix = true
|
||||
foreach p : build_root
|
||||
if i >= source_root.length() or not in_prefix or p != source_root[i]
|
||||
in_prefix = false
|
||||
relative_dir_parts += '..'
|
||||
endif
|
||||
i += 1
|
||||
endforeach
|
||||
i = 0
|
||||
in_prefix = true
|
||||
foreach p : source_root
|
||||
if i >= build_root.length() or not in_prefix or build_root[i] != p
|
||||
in_prefix = false
|
||||
relative_dir_parts += p
|
||||
endif
|
||||
i += 1
|
||||
endforeach
|
||||
relative_dir = join_paths(relative_dir_parts) + '/'
|
||||
fs = import('fs')
|
||||
|
||||
# Strip relative path prefixes from the code if possible, otherwise hide them.
|
||||
relative_dir = fs.relative_to(meson.current_source_dir(), meson.global_build_root()) + '/'
|
||||
if cc.has_argument('-fmacro-prefix-map=/prefix/to/hide=')
|
||||
add_project_arguments(
|
||||
'-fmacro-prefix-map=@0@='.format(relative_dir),
|
||||
|
|
|
|||
|
|
@ -9,12 +9,8 @@ wayland_scanner = find_program(
|
|||
protocols = [
|
||||
wl_protocol_dir / 'stable/tablet/tablet-v2.xml',
|
||||
wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
|
||||
wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
||||
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
||||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||
wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'idle.xml',
|
||||
'wlr-output-power-management-unstable-v1.xml',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh -eu
|
||||
|
||||
prev=$(git describe --tags --abbrev=0)
|
||||
next=$(meson rewrite kwargs info project / 2>&1 >/dev/null | jq -r '.kwargs["project#/"].version')
|
||||
next=$(meson rewrite kwargs info project / | jq -r '.kwargs["project#/"].version')
|
||||
|
||||
case "$next" in
|
||||
*-dev)
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ Name=Sway
|
|||
Comment=An i3-compatible Wayland compositor
|
||||
Exec=sway
|
||||
Type=Application
|
||||
DesktopNames=sway;wlroots
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
|
|||
|
||||
--argc; ++argv;
|
||||
|
||||
if (strncmp(*argv, "→", strlen("→")) == 0) {
|
||||
if (has_prefix(*argv, "→")) {
|
||||
if (argc < 2) {
|
||||
free(criteria);
|
||||
return cmd_results_new(CMD_INVALID, "Missing workspace");
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) {
|
|||
char *font = join_args(argv, argc);
|
||||
free(config->current_bar->font);
|
||||
|
||||
if (strncmp(font, "pango:", 6) == 0) {
|
||||
if (has_prefix(font, "pango:")) {
|
||||
if (config->current_bar->pango_markup == PANGO_MARKUP_DEFAULT) {
|
||||
config->current_bar->pango_markup = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -367,8 +367,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
}
|
||||
} else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
|
||||
exclude_titlebar = true;
|
||||
} else if (strncmp("--input-device=", argv[0],
|
||||
strlen("--input-device=")) == 0) {
|
||||
} else if (has_prefix(argv[0], "--input-device=")) {
|
||||
free(binding->input);
|
||||
binding->input = strdup(argv[0] + strlen("--input-device="));
|
||||
strip_quotes(binding->input);
|
||||
|
|
@ -399,7 +398,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
|
|||
list_t *split = split_string(argv[0], "+");
|
||||
for (int i = 0; i < split->length; ++i) {
|
||||
// Check for group
|
||||
if (strncmp(split->items[i], "Group", strlen("Group")) == 0) {
|
||||
if (has_prefix(split->items[i], "Group")) {
|
||||
if (binding->group != XKB_LAYOUT_INVALID) {
|
||||
free_sway_binding(binding);
|
||||
list_free_items_and_destroy(split);
|
||||
|
|
|
|||
|
|
@ -25,16 +25,6 @@ struct cmd_results *cmd_exec_validate(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
static void export_xdga_token(struct launcher_ctx *ctx) {
|
||||
const char *token = launcher_ctx_get_token_name(ctx);
|
||||
setenv("XDG_ACTIVATION_TOKEN", token, 1);
|
||||
}
|
||||
|
||||
static void export_startup_id(struct launcher_ctx *ctx) {
|
||||
const char *token = launcher_ctx_get_token_name(ctx);
|
||||
setenv("DESKTOP_STARTUP_ID", token, 1);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_exec_process(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
char *cmd = NULL;
|
||||
|
|
@ -56,67 +46,37 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
|
|||
|
||||
sway_log(SWAY_DEBUG, "Executing %s", cmd);
|
||||
|
||||
int fd[2];
|
||||
if (pipe(fd) != 0) {
|
||||
sway_log(SWAY_ERROR, "Unable to create pipe for fork");
|
||||
}
|
||||
|
||||
pid_t pid, child;
|
||||
struct launcher_ctx *ctx = launcher_ctx_create_internal();
|
||||
|
||||
// Fork process
|
||||
if ((pid = fork()) == 0) {
|
||||
// Fork child process again
|
||||
restore_nofile_limit();
|
||||
pid_t child = fork();
|
||||
if (child == 0) {
|
||||
setsid();
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
close(fd[0]);
|
||||
if ((child = fork()) == 0) {
|
||||
close(fd[1]);
|
||||
if (ctx) {
|
||||
export_xdga_token(ctx);
|
||||
|
||||
if (ctx) {
|
||||
const char *token = launcher_ctx_get_token_name(ctx);
|
||||
setenv("XDG_ACTIVATION_TOKEN", token, 1);
|
||||
if (!no_startup_id) {
|
||||
setenv("DESKTOP_STARTUP_ID", token, 1);
|
||||
}
|
||||
if (ctx && !no_startup_id) {
|
||||
export_startup_id(ctx);
|
||||
}
|
||||
execlp("sh", "sh", "-c", cmd, (void *)NULL);
|
||||
sway_log_errno(SWAY_ERROR, "execlp failed");
|
||||
_exit(1);
|
||||
}
|
||||
ssize_t s = 0;
|
||||
while ((size_t)s < sizeof(pid_t)) {
|
||||
s += write(fd[1], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
|
||||
}
|
||||
close(fd[1]);
|
||||
|
||||
execlp("sh", "sh", "-c", cmd, (void*)NULL);
|
||||
sway_log_errno(SWAY_ERROR, "execve failed");
|
||||
_exit(0); // Close child process
|
||||
} else if (pid < 0) {
|
||||
} else if (child < 0) {
|
||||
launcher_ctx_destroy(ctx);
|
||||
free(cmd);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
return cmd_results_new(CMD_FAILURE, "fork() failed");
|
||||
}
|
||||
free(cmd);
|
||||
close(fd[1]); // close write
|
||||
ssize_t s = 0;
|
||||
while ((size_t)s < sizeof(pid_t)) {
|
||||
s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s);
|
||||
}
|
||||
close(fd[0]);
|
||||
// cleanup child process
|
||||
waitpid(pid, NULL, 0);
|
||||
if (child > 0) {
|
||||
sway_log(SWAY_DEBUG, "Child process created with pid %d", child);
|
||||
if (ctx != NULL) {
|
||||
sway_log(SWAY_DEBUG, "Recording workspace for process %d", child);
|
||||
ctx->pid = child;
|
||||
}
|
||||
} else {
|
||||
launcher_ctx_destroy(ctx);
|
||||
return cmd_results_new(CMD_FAILURE, "Second fork() failed");
|
||||
|
||||
sway_log(SWAY_DEBUG, "Child process created with pid %d", child);
|
||||
if (ctx != NULL) {
|
||||
sway_log(SWAY_DEBUG, "Recording workspace for process %d", child);
|
||||
ctx->pid = child;
|
||||
}
|
||||
|
||||
free(cmd);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#include <stddef.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
||||
void sway_terminate(int exit_code);
|
||||
#include "sway/server.h"
|
||||
|
||||
struct cmd_results *cmd_exit(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ struct cmd_results *cmd_font(int argc, char **argv) {
|
|||
char *font = join_args(argv, argc);
|
||||
free(config->font);
|
||||
|
||||
if (strncmp(font, "pango:", 6) == 0) {
|
||||
if (has_prefix(font, "pango:")) {
|
||||
config->pango_markup = true;
|
||||
config->font = strdup(font + 6);
|
||||
config->font = strdup(font + strlen("pango:"));
|
||||
free(font);
|
||||
} else {
|
||||
config->pango_markup = false;
|
||||
|
|
|
|||
|
|
@ -121,8 +121,7 @@ static struct cmd_results *cmd_bind_or_unbind_gesture(int argc, char **argv, boo
|
|||
binding->flags |= BINDING_EXACT;
|
||||
} else if (strcmp("--no-warn", argv[0]) == 0) {
|
||||
warn = false;
|
||||
} else if (strncmp("--input-device=", argv[0],
|
||||
strlen("--input-device=")) == 0) {
|
||||
} else if (has_prefix(argv[0], "--input-device=")) {
|
||||
free(binding->input);
|
||||
binding->input = strdup(argv[0] + strlen("--input-device="));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
struct cmd_results *cmd_include(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "include", EXPECTED_EQUAL_TO, 1))) {
|
||||
if ((error = checkarg(argc, "include", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *files = join_args(argv, argc);
|
||||
// We don't care if the included config(s) fails to load.
|
||||
load_include_configs(argv[0], config, &config->swaynag_config_errors);
|
||||
load_include_configs(files, config, &config->swaynag_config_errors);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_FAILURE, "No input device defined.");
|
||||
}
|
||||
|
||||
#if HAVE_LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY
|
||||
if (strcmp(argv[0], "enabled_sticky") == 0) {
|
||||
ic->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY;
|
||||
} else
|
||||
#endif
|
||||
if (parse_boolean(argv[0], true)) {
|
||||
ic->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_ENABLED;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static void toggle_select_send_events_for_device(struct input_config *ic,
|
|||
static void toggle_send_events(int argc, char **argv) {
|
||||
struct input_config *ic = config->handler_context.input_config;
|
||||
bool wildcard = strcmp(ic->identifier, "*") == 0;
|
||||
const char *type = strncmp(ic->identifier, "type:", strlen("type:")) == 0
|
||||
const char *type = has_prefix(ic->identifier, "type:")
|
||||
? ic->identifier + strlen("type:") : NULL;
|
||||
struct sway_input_device *device = NULL;
|
||||
wl_list_for_each(device, &server.input->devices, link) {
|
||||
|
|
@ -146,8 +146,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) {
|
|||
|
||||
toggle_send_events(argc - 1, argv + 1);
|
||||
|
||||
if (strcmp(ic->identifier, "*") == 0 ||
|
||||
strncmp(ic->identifier, "type:", strlen("type:")) == 0) {
|
||||
if (strcmp(ic->identifier, "*") == 0 || has_prefix(ic->identifier, "type:")) {
|
||||
// Update the device input configs and then reset the type/wildcard
|
||||
// config send events mode so that is does not override the device
|
||||
// ones. The device ones will be applied when attempting to apply
|
||||
|
|
|
|||
|
|
@ -134,6 +134,19 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
|
|||
// Operate on parent container, like i3.
|
||||
if (container) {
|
||||
container = container->pending.parent;
|
||||
// If parent has only a singe child operate on its parent and
|
||||
// flatten once, like i3
|
||||
if (container && container->pending.children->length == 1) {
|
||||
// Also check grandparent to avoid restricting layouts
|
||||
struct sway_container *parent = container->pending.parent;
|
||||
if (parent && parent->pending.children->length == 1) {
|
||||
struct sway_container *child = container->pending.children->items[0];
|
||||
struct sway_container *parent = container->pending.parent;
|
||||
container_replace(container, child);
|
||||
container_begin_destroy(container);
|
||||
container = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We could be working with a container OR a workspace. These are different
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
|
|||
}
|
||||
|
||||
bool add = false, toggle = false;
|
||||
while (argc > 0 && strncmp(*argv, "--", 2) == 0) {
|
||||
while (argc > 0 && has_prefix(*argv, "--")) {
|
||||
if (strcmp(*argv, "--add") == 0) {
|
||||
add = true;
|
||||
} else if (strcmp(*argv, "--replace") == 0) {
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ static void container_move_to_workspace(struct sway_container *container,
|
|||
container_detach(container);
|
||||
if (workspace_is_empty(workspace) && container->pending.children) {
|
||||
workspace_unwrap_children(workspace, container);
|
||||
container_reap_empty(container);
|
||||
} else {
|
||||
container->pending.width = container->pending.height = 0;
|
||||
container->width_fraction = container->height_fraction = 0;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/output.h"
|
||||
#include "log.h"
|
||||
|
||||
struct cmd_results *cmd_opacity(int argc, char **argv) {
|
||||
|
|
@ -37,6 +38,7 @@ struct cmd_results *cmd_opacity(int argc, char **argv) {
|
|||
}
|
||||
|
||||
con->alpha = val;
|
||||
output_configure_scene(NULL, &con->scene_tree->node, 1);
|
||||
container_update(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ static const struct cmd_handler output_handlers[] = {
|
|||
{ "disable", output_cmd_disable },
|
||||
{ "dpms", output_cmd_dpms },
|
||||
{ "enable", output_cmd_enable },
|
||||
{ "hdr", output_cmd_hdr },
|
||||
{ "max_render_time", output_cmd_max_render_time },
|
||||
{ "mode", output_cmd_mode },
|
||||
{ "modeline", output_cmd_modeline },
|
||||
|
|
|
|||
|
|
@ -3,10 +3,8 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/swaynag.h"
|
||||
#include "log.h"
|
||||
#include "stringop.h"
|
||||
|
||||
|
|
@ -42,14 +40,14 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
}
|
||||
|
||||
struct output_config *output = config->handler_context.output_config;
|
||||
|
||||
char *src = NULL;
|
||||
if (strcasecmp(argv[1], "solid_color") == 0) {
|
||||
if (!validate_color(argv[0])) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Colors should be of the form #RRGGBB");
|
||||
}
|
||||
output->background = strdup(argv[0]);
|
||||
output->background_option = strdup("solid_color");
|
||||
if (!(output->background = strdup(argv[0]))) goto cleanup;
|
||||
if (!(output->background_option = strdup("solid_color"))) goto cleanup;
|
||||
output->background_fallback = NULL;
|
||||
argc -= 2; argv += 2;
|
||||
} else {
|
||||
|
|
@ -77,37 +75,25 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "Missing background file");
|
||||
}
|
||||
|
||||
char *src = join_args(argv, j);
|
||||
if (!(src = join_args(argv, j))) goto cleanup;
|
||||
if (!expand_path(&src)) {
|
||||
struct cmd_results *cmd_res = cmd_results_new(CMD_INVALID,
|
||||
"Invalid syntax (%s)", src);
|
||||
free(src);
|
||||
return cmd_res;
|
||||
}
|
||||
if (!src) {
|
||||
sway_log(SWAY_ERROR, "Failed to allocate expanded path");
|
||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate resource");
|
||||
}
|
||||
|
||||
if (config->reading && *src != '/') {
|
||||
// src file is inside configuration dir
|
||||
|
||||
char *conf = strdup(config->current_config_path);
|
||||
if (!conf) {
|
||||
sway_log(SWAY_ERROR, "Failed to duplicate string");
|
||||
free(src);
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Unable to allocate resources");
|
||||
}
|
||||
if (!conf) goto cleanup;
|
||||
|
||||
char *conf_path = dirname(conf);
|
||||
char *real_src = malloc(strlen(conf_path) + strlen(src) + 2);
|
||||
if (!real_src) {
|
||||
free(src);
|
||||
free(conf);
|
||||
sway_log(SWAY_ERROR, "Unable to allocate memory");
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Unable to allocate resources");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
snprintf(real_src, strlen(conf_path) + strlen(src) + 2, "%s/%s", conf_path, src);
|
||||
|
|
@ -117,40 +103,48 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|||
}
|
||||
|
||||
bool can_access = access(src, F_OK) != -1;
|
||||
argc -= j + 1; argv += j + 1;
|
||||
free(output->background_option);
|
||||
free(output->background_fallback);
|
||||
free(output->background);
|
||||
output->background = output->background_option = output->background_fallback = NULL;
|
||||
char *fallback = NULL;
|
||||
|
||||
if (argc && *argv[0] == '#') {
|
||||
if (validate_color(argv[0])) {
|
||||
if (!(fallback = strdup(argv[0]))) goto cleanup;
|
||||
output->background_fallback = fallback;
|
||||
} else {
|
||||
sway_log(SWAY_ERROR, "fallback '%s' should be of the form #RRGGBB", argv[0]);
|
||||
config_add_swaynag_warning("fallback '%s' should be of the form #RRGGBB\n", argv[0]);
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
if (!can_access) {
|
||||
sway_log_errno(SWAY_ERROR, "Unable to access background file '%s'",
|
||||
src);
|
||||
config_add_swaynag_warning("Unable to access background file '%s'",
|
||||
src);
|
||||
struct cmd_results *result = cmd_results_new(CMD_FAILURE,
|
||||
"unable to access background file '%s'", src);
|
||||
free(src);
|
||||
return result;
|
||||
if (!fallback) {
|
||||
sway_log(SWAY_ERROR, "Unable to access background file '%s' "
|
||||
"and no valid fallback provided", src);
|
||||
struct cmd_results *res = cmd_results_new(CMD_FAILURE, "Unable to access "
|
||||
"background file '%s' and no valid fallback provided", src);
|
||||
free(src);
|
||||
return res;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "Cannot access file '%s', using fallback '%s'", src, fallback);
|
||||
output->background = fallback;
|
||||
if (!(output->background_option = strdup("solid_color"))) goto cleanup;
|
||||
output->background_fallback = NULL;
|
||||
} else {
|
||||
output->background = src;
|
||||
output->background_option = strdup(mode);
|
||||
}
|
||||
argc -= j + 1; argv += j + 1;
|
||||
|
||||
output->background_fallback = NULL;
|
||||
if (argc && *argv[0] == '#') {
|
||||
if (!validate_color(argv[0])) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"fallback color should be of the form #RRGGBB");
|
||||
}
|
||||
|
||||
output->background_fallback = strdup(argv[0]);
|
||||
argc--; argv++;
|
||||
|
||||
if (!can_access) {
|
||||
output->background = output->background_fallback;
|
||||
output->background_option = strdup("solid_color");
|
||||
output->background_fallback = NULL;
|
||||
}
|
||||
if (!(output->background_option = strdup(mode))) goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
config->handler_context.leftovers.argc = argc;
|
||||
config->handler_context.leftovers.argv = argv;
|
||||
return NULL;
|
||||
|
||||
cleanup:
|
||||
free(src);
|
||||
sway_log(SWAY_ERROR, "Failed to allocate resources");
|
||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate resources");
|
||||
}
|
||||
|
|
|
|||
37
sway/commands/output/hdr.c
Normal file
37
sway/commands/output/hdr.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include <strings.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/output.h"
|
||||
#include "util.h"
|
||||
|
||||
struct cmd_results *output_cmd_hdr(int argc, char **argv) {
|
||||
if (!config->handler_context.output_config) {
|
||||
return cmd_results_new(CMD_FAILURE, "Missing output config");
|
||||
}
|
||||
if (argc == 0) {
|
||||
return cmd_results_new(CMD_INVALID, "Missing hdr argument");
|
||||
}
|
||||
|
||||
bool current = false;
|
||||
if (strcasecmp(argv[0], "toggle") == 0) {
|
||||
const char *oc_name = config->handler_context.output_config->name;
|
||||
if (strcmp(oc_name, "*") == 0) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Cannot apply toggle to all outputs");
|
||||
}
|
||||
|
||||
struct sway_output *output = all_output_by_name_or_id(oc_name);
|
||||
if (!output) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Cannot apply toggle to unknown output %s", oc_name);
|
||||
}
|
||||
|
||||
current = output->hdr;
|
||||
}
|
||||
|
||||
config->handler_context.output_config->hdr = parse_boolean(argv[0], current);
|
||||
|
||||
config->handler_context.leftovers.argc = argc - 1;
|
||||
config->handler_context.leftovers.argv = argv + 1;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -80,61 +80,46 @@ void container_resize_tiled(struct sway_container *con,
|
|||
}
|
||||
|
||||
// For HORIZONTAL or VERTICAL, we are growing in two directions so select
|
||||
// both adjacent siblings. For RIGHT or DOWN, just select the next sibling.
|
||||
// For LEFT or UP, convert it to a RIGHT or DOWN resize and reassign con to
|
||||
// the previous sibling.
|
||||
struct sway_container *prev = NULL;
|
||||
struct sway_container *next = NULL;
|
||||
// all adjacent siblings. For RIGHT or DOWN or LEFT or UP select just the
|
||||
// previous or next sibling.
|
||||
list_t *resize = create_list();
|
||||
list_t *siblings = container_get_siblings(con);
|
||||
int index = container_sibling_index(con);
|
||||
|
||||
if (axis == AXIS_HORIZONTAL || axis == AXIS_VERTICAL) {
|
||||
if (index == 0) {
|
||||
next = siblings->items[1];
|
||||
} else if (index == siblings->length - 1) {
|
||||
// Convert edge to top/left
|
||||
next = con;
|
||||
con = siblings->items[index - 1];
|
||||
amount = -amount;
|
||||
} else {
|
||||
prev = siblings->items[index - 1];
|
||||
next = siblings->items[index + 1];
|
||||
}
|
||||
list_cat(resize, siblings);
|
||||
} else if (axis == WLR_EDGE_TOP || axis == WLR_EDGE_LEFT) {
|
||||
if (!sway_assert(index > 0, "Didn't expect first child")) {
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
next = con;
|
||||
con = siblings->items[index - 1];
|
||||
amount = -amount;
|
||||
list_add(resize, siblings->items[index - 1]);
|
||||
list_add(resize, con);
|
||||
} else {
|
||||
if (!sway_assert(index < siblings->length - 1,
|
||||
"Didn't expect last child")) {
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
next = siblings->items[index + 1];
|
||||
list_add(resize, con);
|
||||
list_add(resize, siblings->items[index + 1]);
|
||||
}
|
||||
|
||||
// Apply new dimensions
|
||||
int sibling_amount = prev ? ceil((double)amount / 2.0) : amount;
|
||||
int sibling_amount = ceil((double)amount / (double)(resize->length - 1));
|
||||
|
||||
if (is_horizontal(axis)) {
|
||||
if (con->pending.width + amount < MIN_SANE_W) {
|
||||
return;
|
||||
}
|
||||
if (next->pending.width - sibling_amount < MIN_SANE_W) {
|
||||
return;
|
||||
}
|
||||
if (prev && prev->pending.width - sibling_amount < MIN_SANE_W) {
|
||||
return;
|
||||
for (int i = 0; i < resize->length; i++) {
|
||||
struct sway_container *sibling = resize->items[i];
|
||||
double change = sibling == con ? amount : -sibling_amount;
|
||||
if (sibling->pending.width + change < MIN_SANE_W) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (con->child_total_width <= 0) {
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// We're going to resize so snap all the width fractions to full pixels
|
||||
// to avoid rounding issues
|
||||
list_t *siblings = container_get_siblings(con);
|
||||
for (int i = 0; i < siblings->length; ++i) {
|
||||
struct sway_container *con = siblings->items[i];
|
||||
con->width_fraction = con->pending.width / con->child_total_width;
|
||||
|
|
@ -142,30 +127,27 @@ void container_resize_tiled(struct sway_container *con,
|
|||
|
||||
double amount_fraction = (double)amount / con->child_total_width;
|
||||
double sibling_amount_fraction =
|
||||
prev ? amount_fraction / 2.0 : amount_fraction;
|
||||
amount_fraction / (double)(resize->length - 1);
|
||||
|
||||
con->width_fraction += amount_fraction;
|
||||
next->width_fraction -= sibling_amount_fraction;
|
||||
if (prev) {
|
||||
prev->width_fraction -= sibling_amount_fraction;
|
||||
for (int i = 0; i < resize->length; i++) {
|
||||
struct sway_container *sibling = resize->items[i];
|
||||
sibling->width_fraction +=
|
||||
sibling == con ? amount_fraction : -sibling_amount_fraction;
|
||||
}
|
||||
} else {
|
||||
if (con->pending.height + amount < MIN_SANE_H) {
|
||||
return;
|
||||
}
|
||||
if (next->pending.height - sibling_amount < MIN_SANE_H) {
|
||||
return;
|
||||
}
|
||||
if (prev && prev->pending.height - sibling_amount < MIN_SANE_H) {
|
||||
return;
|
||||
for (int i = 0; i < resize->length; i++) {
|
||||
struct sway_container *sibling = resize->items[i];
|
||||
double change = sibling == con ? amount : -sibling_amount;
|
||||
if (sibling->pending.height + change < MIN_SANE_H) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (con->child_total_height <= 0) {
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// We're going to resize so snap all the height fractions to full pixels
|
||||
// to avoid rounding issues
|
||||
list_t *siblings = container_get_siblings(con);
|
||||
for (int i = 0; i < siblings->length; ++i) {
|
||||
struct sway_container *con = siblings->items[i];
|
||||
con->height_fraction = con->pending.height / con->child_total_height;
|
||||
|
|
@ -173,12 +155,12 @@ void container_resize_tiled(struct sway_container *con,
|
|||
|
||||
double amount_fraction = (double)amount / con->child_total_height;
|
||||
double sibling_amount_fraction =
|
||||
prev ? amount_fraction / 2.0 : amount_fraction;
|
||||
amount_fraction / (double)(resize->length - 1);
|
||||
|
||||
con->height_fraction += amount_fraction;
|
||||
next->height_fraction -= sibling_amount_fraction;
|
||||
if (prev) {
|
||||
prev->height_fraction -= sibling_amount_fraction;
|
||||
for (int i = 0; i < resize->length; i++) {
|
||||
struct sway_container *sibling = resize->items[i];
|
||||
sibling->height_fraction +=
|
||||
sibling == con ? amount_fraction : -sibling_amount_fraction;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,6 +169,9 @@ void container_resize_tiled(struct sway_container *con,
|
|||
} else {
|
||||
arrange_workspace(con->pending.workspace);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
list_free(resize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -457,7 +442,7 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
|||
if (argc > num_consumed_args) {
|
||||
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||
}
|
||||
if (width.unit == MOVEMENT_UNIT_INVALID) {
|
||||
if (height.unit == MOVEMENT_UNIT_INVALID) {
|
||||
return cmd_results_new(CMD_INVALID, "%s", usage);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,10 +118,10 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
|
|||
|
||||
// If using criteria, this command is executed for every container which
|
||||
// matches the criteria. If this container isn't in the scratchpad,
|
||||
// we'll just silently return a success. The same is true if the
|
||||
// we'll return an error. The same is true if the
|
||||
// overridden node is not a container.
|
||||
if (!con || !con->scratchpad) {
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
return cmd_results_new(CMD_INVALID, "Container is not in scratchpad.");
|
||||
}
|
||||
scratchpad_toggle_container(con);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ struct cmd_results *cmd_ws_auto_back_and_forth(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
config->auto_back_and_forth =
|
||||
config->auto_back_and_forth =
|
||||
parse_boolean(argv[0], config->auto_back_and_forth);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -552,28 +552,12 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
|||
return success;
|
||||
}
|
||||
|
||||
static bool load_include_config(const char *path, const char *parent_dir,
|
||||
struct sway_config *config, struct swaynag_instance *swaynag) {
|
||||
static bool load_include_config(const char *path, struct sway_config *config,
|
||||
struct swaynag_instance *swaynag) {
|
||||
// save parent config
|
||||
const char *parent_config = config->current_config_path;
|
||||
|
||||
char *full_path;
|
||||
int len = strlen(path);
|
||||
if (len >= 1 && path[0] != '/') {
|
||||
len = len + strlen(parent_dir) + 2;
|
||||
full_path = malloc(len * sizeof(char));
|
||||
if (!full_path) {
|
||||
sway_log(SWAY_ERROR,
|
||||
"Unable to allocate full path to included config");
|
||||
return false;
|
||||
}
|
||||
snprintf(full_path, len, "%s/%s", parent_dir, path);
|
||||
} else {
|
||||
full_path = strdup(path);
|
||||
}
|
||||
|
||||
char *real_path = realpath(full_path, NULL);
|
||||
free(full_path);
|
||||
char *real_path = realpath(path, NULL);
|
||||
|
||||
if (real_path == NULL) {
|
||||
sway_log(SWAY_DEBUG, "%s not found.", path);
|
||||
|
|
@ -625,7 +609,7 @@ void load_include_configs(const char *path, struct sway_config *config,
|
|||
char **w = p.we_wordv;
|
||||
size_t i;
|
||||
for (i = 0; i < p.we_wordc; ++i) {
|
||||
load_include_config(w[i], parent_dir, config, swaynag);
|
||||
load_include_config(w[i], config, swaynag);
|
||||
}
|
||||
wordfree(&p);
|
||||
}
|
||||
|
|
@ -925,8 +909,8 @@ char *do_var_replacement(char *str) {
|
|||
// Find matching variable
|
||||
for (i = 0; i < config->symbols->length; ++i) {
|
||||
struct sway_variable *var = config->symbols->items[i];
|
||||
int vnlen = strlen(var->name);
|
||||
if (strncmp(find, var->name, vnlen) == 0) {
|
||||
if (has_prefix(find, var->name)) {
|
||||
int vnlen = strlen(var->name);
|
||||
int vvlen = strlen(var->value);
|
||||
char *newstr = malloc(strlen(str) - vnlen + vvlen + 1);
|
||||
if (!newstr) {
|
||||
|
|
|
|||
|
|
@ -213,36 +213,21 @@ static void invoke_swaybar(struct bar_config *bar) {
|
|||
sway_log(SWAY_ERROR, "Failed to create fork for swaybar");
|
||||
return;
|
||||
} else if (pid == 0) {
|
||||
// Remove the SIGUSR1 handler that wlroots adds for xwayland
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
restore_nofile_limit();
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||
_exit(EXIT_FAILURE);
|
||||
} else if (pid == 0) {
|
||||
if (!sway_set_cloexec(sockets[1], false)) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char wayland_socket_str[16];
|
||||
snprintf(wayland_socket_str, sizeof(wayland_socket_str),
|
||||
"%d", sockets[1]);
|
||||
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||
|
||||
// run custom swaybar
|
||||
char *const cmd[] = {
|
||||
bar->swaybar_command ? bar->swaybar_command : "swaybar",
|
||||
"-b", bar->id, NULL};
|
||||
execvp(cmd[0], cmd);
|
||||
if (!sway_set_cloexec(sockets[1], false)) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
char wayland_socket_str[16];
|
||||
snprintf(wayland_socket_str, sizeof(wayland_socket_str),
|
||||
"%d", sockets[1]);
|
||||
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||
|
||||
// run custom swaybar
|
||||
char *const cmd[] = {
|
||||
bar->swaybar_command ? bar->swaybar_command : "swaybar",
|
||||
"-b", bar->id, NULL};
|
||||
execvp(cmd[0], cmd);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (close(sockets[1]) != 0) {
|
||||
|
|
@ -250,11 +235,6 @@ static void invoke_swaybar(struct bar_config *bar) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (waitpid(pid, NULL, 0) < 0) {
|
||||
sway_log_errno(SWAY_ERROR, "waitpid failed");
|
||||
return;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Spawned swaybar %s", bar->id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ struct input_config *store_input_config(struct input_config *ic,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool type = strncmp(ic->identifier, "type:", strlen("type:")) == 0;
|
||||
bool type = has_prefix(ic->identifier, "type:");
|
||||
if (type && error && !validate_type_on_existing(ic, error)) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
|
@ -66,7 +67,7 @@ struct output_config *new_output_config(const char *name) {
|
|||
oc->refresh_rate = -1;
|
||||
oc->custom_mode = -1;
|
||||
oc->drm_mode.type = -1;
|
||||
oc->x = oc->y = -1;
|
||||
oc->x = oc->y = INT_MAX;
|
||||
oc->scale = -1;
|
||||
oc->scale_filter = SCALE_FILTER_DEFAULT;
|
||||
oc->transform = -1;
|
||||
|
|
@ -78,6 +79,7 @@ struct output_config *new_output_config(const char *name) {
|
|||
oc->color_transform = NULL;
|
||||
oc->power = -1;
|
||||
oc->allow_tearing = -1;
|
||||
oc->hdr = -1;
|
||||
return oc;
|
||||
}
|
||||
|
||||
|
|
@ -92,11 +94,11 @@ static void supersede_output_config(struct output_config *dst, struct output_con
|
|||
if (src->height != -1) {
|
||||
dst->height = -1;
|
||||
}
|
||||
if (src->x != -1) {
|
||||
dst->x = -1;
|
||||
if (src->x != INT_MAX) {
|
||||
dst->x = INT_MAX;
|
||||
}
|
||||
if (src->y != -1) {
|
||||
dst->y = -1;
|
||||
if (src->y != INT_MAX) {
|
||||
dst->y = INT_MAX;
|
||||
}
|
||||
if (src->scale != -1) {
|
||||
dst->scale = -1;
|
||||
|
|
@ -128,6 +130,13 @@ static void supersede_output_config(struct output_config *dst, struct output_con
|
|||
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
dst->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
|
||||
}
|
||||
if (src->set_color_transform) {
|
||||
if (dst->color_transform) {
|
||||
wlr_color_transform_unref(dst->color_transform);
|
||||
dst->color_transform = NULL;
|
||||
}
|
||||
dst->set_color_transform = false;
|
||||
}
|
||||
if (src->background) {
|
||||
free(dst->background);
|
||||
dst->background = NULL;
|
||||
|
|
@ -143,6 +152,12 @@ static void supersede_output_config(struct output_config *dst, struct output_con
|
|||
if (src->power != -1) {
|
||||
dst->power = -1;
|
||||
}
|
||||
if (src->allow_tearing != -1) {
|
||||
dst->allow_tearing = -1;
|
||||
}
|
||||
if (src->hdr != -1) {
|
||||
dst->hdr = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// merge_output_config sets all fields in dst that were set in src
|
||||
|
|
@ -156,10 +171,10 @@ static void merge_output_config(struct output_config *dst, struct output_config
|
|||
if (src->height != -1) {
|
||||
dst->height = src->height;
|
||||
}
|
||||
if (src->x != -1) {
|
||||
if (src->x != INT_MAX) {
|
||||
dst->x = src->x;
|
||||
}
|
||||
if (src->y != -1) {
|
||||
if (src->y != INT_MAX) {
|
||||
dst->y = src->y;
|
||||
}
|
||||
if (src->scale != -1) {
|
||||
|
|
@ -218,6 +233,9 @@ static void merge_output_config(struct output_config *dst, struct output_config
|
|||
if (src->allow_tearing != -1) {
|
||||
dst->allow_tearing = src->allow_tearing;
|
||||
}
|
||||
if (src->hdr != -1) {
|
||||
dst->hdr = src->hdr;
|
||||
}
|
||||
}
|
||||
|
||||
void store_output_config(struct output_config *oc) {
|
||||
|
|
@ -260,11 +278,11 @@ void store_output_config(struct output_config *oc) {
|
|||
|
||||
sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
|
||||
"position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) "
|
||||
"(max render time: %d) (allow tearing: %d)",
|
||||
"(max render time: %d) (allow tearing: %d) (hdr: %d)",
|
||||
oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate,
|
||||
oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel),
|
||||
oc->transform, oc->background, oc->background_option, oc->power,
|
||||
oc->max_render_time, oc->allow_tearing);
|
||||
oc->max_render_time, oc->allow_tearing, oc->hdr);
|
||||
|
||||
// If the configuration was not merged into an existing configuration, add
|
||||
// it to the list. Otherwise we're done with it and can free it.
|
||||
|
|
@ -330,6 +348,45 @@ static void set_modeline(struct wlr_output *output,
|
|||
#endif
|
||||
}
|
||||
|
||||
bool output_supports_hdr(struct wlr_output *output, const char **unsupported_reason_ptr) {
|
||||
const char *unsupported_reason = NULL;
|
||||
if (!(output->supported_primaries & WLR_COLOR_NAMED_PRIMARIES_BT2020)) {
|
||||
unsupported_reason = "BT2020 primaries not supported by output";
|
||||
} else if (!(output->supported_transfer_functions & WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) {
|
||||
unsupported_reason = "PQ transfer function not supported by output";
|
||||
} else if (!server.renderer->features.output_color_transform) {
|
||||
unsupported_reason = "renderer doesn't support output color transforms";
|
||||
}
|
||||
if (unsupported_reason_ptr != NULL) {
|
||||
*unsupported_reason_ptr = unsupported_reason;
|
||||
}
|
||||
return unsupported_reason == NULL;
|
||||
}
|
||||
|
||||
static void set_hdr(struct wlr_output *output, struct wlr_output_state *pending, bool enabled) {
|
||||
const char *unsupported_reason = NULL;
|
||||
if (enabled && !output_supports_hdr(output, &unsupported_reason)) {
|
||||
sway_log(SWAY_ERROR, "Cannot enable HDR on output %s: %s",
|
||||
output->name, unsupported_reason);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
if (output->supported_primaries != 0 || output->supported_transfer_functions != 0) {
|
||||
sway_log(SWAY_DEBUG, "Disabling HDR on output %s", output->name);
|
||||
wlr_output_state_set_image_description(pending, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Enabling HDR on output %s", output->name);
|
||||
const struct wlr_output_image_description image_desc = {
|
||||
.primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020,
|
||||
.transfer_function = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ,
|
||||
};
|
||||
wlr_output_state_set_image_description(pending, &image_desc);
|
||||
}
|
||||
|
||||
/* Some manufacturers hardcode the aspect-ratio of the output in the physical
|
||||
* size field. */
|
||||
static bool phys_size_is_aspect_ratio(struct wlr_output *output) {
|
||||
|
|
@ -404,6 +461,16 @@ static enum render_bit_depth bit_depth_from_format(uint32_t render_format) {
|
|||
return RENDER_BIT_DEPTH_DEFAULT;
|
||||
}
|
||||
|
||||
static enum render_bit_depth get_config_render_bit_depth(const struct output_config *oc) {
|
||||
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
return oc->render_bit_depth;
|
||||
}
|
||||
if (oc && oc->hdr == 1) {
|
||||
return RENDER_BIT_DEPTH_10;
|
||||
}
|
||||
return RENDER_BIT_DEPTH_8;
|
||||
}
|
||||
|
||||
static bool render_format_is_bgr(uint32_t fmt) {
|
||||
return fmt == DRM_FORMAT_XBGR2101010 || fmt == DRM_FORMAT_XBGR8888;
|
||||
}
|
||||
|
|
@ -474,24 +541,29 @@ static void queue_output_config(struct output_config *oc,
|
|||
}
|
||||
}
|
||||
|
||||
if (oc && oc->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
if (oc->render_bit_depth == RENDER_BIT_DEPTH_10 &&
|
||||
bit_depth_from_format(output->wlr_output->render_format) == oc->render_bit_depth) {
|
||||
// 10-bit was set successfully before, try to save some tests by reusing the format
|
||||
wlr_output_state_set_render_format(pending, output->wlr_output->render_format);
|
||||
} else if (oc->render_bit_depth == RENDER_BIT_DEPTH_10) {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB2101010);
|
||||
} else if (oc->render_bit_depth == RENDER_BIT_DEPTH_6){
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_RGB565);
|
||||
} else {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
enum render_bit_depth render_bit_depth = get_config_render_bit_depth(oc);
|
||||
if (render_bit_depth == RENDER_BIT_DEPTH_10 &&
|
||||
bit_depth_from_format(output->wlr_output->render_format) == render_bit_depth) {
|
||||
// 10-bit was set successfully before, try to save some tests by reusing the format
|
||||
wlr_output_state_set_render_format(pending, output->wlr_output->render_format);
|
||||
} else if (render_bit_depth == RENDER_BIT_DEPTH_10) {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB2101010);
|
||||
} else if (render_bit_depth == RENDER_BIT_DEPTH_6) {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_RGB565);
|
||||
} else {
|
||||
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
|
||||
bool hdr = oc && oc->hdr == 1;
|
||||
if (hdr && oc->color_transform != NULL) {
|
||||
sway_log(SWAY_ERROR, "Cannot HDR on output %s: output has an ICC profile set", wlr_output->name);
|
||||
hdr = false;
|
||||
}
|
||||
set_hdr(wlr_output, pending, hdr);
|
||||
}
|
||||
|
||||
static bool finalize_output_config(struct output_config *oc, struct sway_output *output) {
|
||||
static bool finalize_output_config(struct output_config *oc, struct sway_output *output,
|
||||
const struct wlr_output_state *applied) {
|
||||
if (output == root->fallback_output) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -526,21 +598,13 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
|||
}
|
||||
|
||||
// Find position for it
|
||||
if (oc && (oc->x != -1 || oc->y != -1)) {
|
||||
if (oc && oc->x != INT_MAX && oc->y != INT_MAX) {
|
||||
sway_log(SWAY_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y);
|
||||
wlr_output_layout_add(root->output_layout, wlr_output, oc->x, oc->y);
|
||||
} else {
|
||||
wlr_output_layout_add_auto(root->output_layout, wlr_output);
|
||||
}
|
||||
|
||||
// Update output->{lx, ly, width, height}
|
||||
struct wlr_box output_box;
|
||||
wlr_output_layout_get_box(root->output_layout, wlr_output, &output_box);
|
||||
output->lx = output_box.x;
|
||||
output->ly = output_box.y;
|
||||
output->width = output_box.width;
|
||||
output->height = output_box.height;
|
||||
|
||||
if (!output->enabled) {
|
||||
output_enable(output);
|
||||
}
|
||||
|
|
@ -558,10 +622,20 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
|||
|
||||
output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0;
|
||||
output->allow_tearing = oc && oc->allow_tearing > 0;
|
||||
output->hdr = applied->image_description != NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void output_update_position(struct sway_output *output) {
|
||||
struct wlr_box output_box;
|
||||
wlr_output_layout_get_box(root->output_layout, output->wlr_output, &output_box);
|
||||
output->lx = output_box.x;
|
||||
output->ly = output_box.y;
|
||||
output->width = output_box.width;
|
||||
output->height = output_box.height;
|
||||
}
|
||||
|
||||
// find_output_config_from_list returns a merged output_config containing all
|
||||
// stored configuration that applies to the specified output.
|
||||
static struct output_config *find_output_config_from_list(
|
||||
|
|
@ -772,17 +846,15 @@ static bool search_render_format(struct search_context *ctx, size_t output_idx)
|
|||
}
|
||||
|
||||
const struct wlr_drm_format_set *primary_formats =
|
||||
wlr_output_get_primary_formats(wlr_output, WLR_BUFFER_CAP_DMABUF);
|
||||
enum render_bit_depth needed_bits = RENDER_BIT_DEPTH_8;
|
||||
if (cfg->config && cfg->config->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
needed_bits = cfg->config->render_bit_depth;
|
||||
}
|
||||
wlr_output_get_primary_formats(wlr_output, server.allocator->buffer_caps);
|
||||
enum render_bit_depth needed_bits = get_config_render_bit_depth(cfg->config);
|
||||
for (size_t idx = 0; fmts[idx] != DRM_FORMAT_INVALID; idx++) {
|
||||
enum render_bit_depth format_bits = bit_depth_from_format(fmts[idx]);
|
||||
if (needed_bits < format_bits) {
|
||||
continue;
|
||||
}
|
||||
if (!wlr_drm_format_set_get(primary_formats, fmts[idx])) {
|
||||
// If primary_formats is NULL, all formats are supported
|
||||
if (primary_formats && !wlr_drm_format_set_get(primary_formats, fmts[idx])) {
|
||||
// This is not a supported format for this output
|
||||
continue;
|
||||
}
|
||||
|
|
@ -930,9 +1002,17 @@ static bool apply_resolved_output_configs(struct matched_output_config *configs,
|
|||
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
struct wlr_backend_output_state *backend_state = &states[idx];
|
||||
sway_log(SWAY_DEBUG, "Finalizing config for %s",
|
||||
cfg->output->wlr_output->name);
|
||||
finalize_output_config(cfg->config, cfg->output);
|
||||
finalize_output_config(cfg->config, cfg->output, &backend_state->base);
|
||||
}
|
||||
|
||||
// Output layout being applied in finalize_output_config can shift outputs
|
||||
// around, so we do a second pass to update positions and arrange.
|
||||
for (size_t idx = 0; idx < configs_len; idx++) {
|
||||
struct matched_output_config *cfg = &configs[idx];
|
||||
output_update_position(cfg->output);
|
||||
arrange_layers(cfg->output);
|
||||
}
|
||||
|
||||
|
|
@ -1008,6 +1088,7 @@ void free_output_config(struct output_config *oc) {
|
|||
free(oc->name);
|
||||
free(oc->background);
|
||||
free(oc->background_option);
|
||||
free(oc->background_fallback);
|
||||
wlr_color_transform_unref(oc->color_transform);
|
||||
free(oc);
|
||||
}
|
||||
|
|
@ -1049,42 +1130,27 @@ static bool _spawn_swaybg(char **command) {
|
|||
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||
return false;
|
||||
} else if (pid == 0) {
|
||||
restore_nofile_limit();
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||
_exit(EXIT_FAILURE);
|
||||
} else if (pid == 0) {
|
||||
if (!sway_set_cloexec(sockets[1], false)) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char wayland_socket_str[16];
|
||||
snprintf(wayland_socket_str, sizeof(wayland_socket_str),
|
||||
"%d", sockets[1]);
|
||||
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||
|
||||
execvp(command[0], command);
|
||||
sway_log_errno(SWAY_ERROR, "failed to execute '%s' "
|
||||
"(background configuration probably not applied)",
|
||||
command[0]);
|
||||
if (!sway_set_cloexec(sockets[1], false)) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
char wayland_socket_str[16];
|
||||
snprintf(wayland_socket_str, sizeof(wayland_socket_str),
|
||||
"%d", sockets[1]);
|
||||
setenv("WAYLAND_SOCKET", wayland_socket_str, true);
|
||||
|
||||
execvp(command[0], command);
|
||||
sway_log_errno(SWAY_ERROR, "failed to execute '%s' "
|
||||
"(background configuration probably not applied)",
|
||||
command[0]);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (close(sockets[1]) != 0) {
|
||||
sway_log_errno(SWAY_ERROR, "close failed");
|
||||
return false;
|
||||
}
|
||||
int fork_status = 0;
|
||||
if (waitpid(pid, &fork_status, 0) < 0) {
|
||||
sway_log_errno(SWAY_ERROR, "waitpid failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return WIFEXITED(fork_status) && WEXITSTATUS(fork_status) == EXIT_SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spawn_swaybg(void) {
|
||||
|
|
|
|||
117
sway/criteria.c
117
sway/criteria.c
|
|
@ -34,7 +34,11 @@ bool criteria_is_empty(struct criteria *criteria) {
|
|||
&& !criteria->tiling
|
||||
&& !criteria->urgent
|
||||
&& !criteria->workspace
|
||||
&& !criteria->pid;
|
||||
&& !criteria->pid
|
||||
&& !criteria->sandbox_engine
|
||||
&& !criteria->sandbox_app_id
|
||||
&& !criteria->sandbox_instance_id
|
||||
&& !criteria->tag;
|
||||
}
|
||||
|
||||
// The error pointer is used for parsing functions, and saves having to pass it
|
||||
|
|
@ -98,6 +102,10 @@ void criteria_destroy(struct criteria *criteria) {
|
|||
#endif
|
||||
pattern_destroy(criteria->con_mark);
|
||||
pattern_destroy(criteria->workspace);
|
||||
pattern_destroy(criteria->sandbox_engine);
|
||||
pattern_destroy(criteria->sandbox_app_id);
|
||||
pattern_destroy(criteria->sandbox_instance_id);
|
||||
pattern_destroy(criteria->tag);
|
||||
free(criteria->target);
|
||||
free(criteria->cmdlist);
|
||||
free(criteria->raw);
|
||||
|
|
@ -248,6 +256,86 @@ static bool criteria_matches_view(struct criteria *criteria,
|
|||
}
|
||||
}
|
||||
|
||||
if (criteria->sandbox_engine) {
|
||||
const char *sandbox_engine = view_get_sandbox_engine(view);
|
||||
if (!sandbox_engine) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (criteria->sandbox_engine->match_type) {
|
||||
case PATTERN_FOCUSED:
|
||||
if (focused && lenient_strcmp(sandbox_engine, view_get_sandbox_engine(focused))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PATTERN_PCRE2:
|
||||
if (regex_cmp(sandbox_engine, criteria->sandbox_engine->regex) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (criteria->sandbox_app_id) {
|
||||
const char *sandbox_app_id = view_get_sandbox_app_id(view);
|
||||
if (!sandbox_app_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (criteria->sandbox_app_id->match_type) {
|
||||
case PATTERN_FOCUSED:
|
||||
if (focused && lenient_strcmp(sandbox_app_id, view_get_sandbox_app_id(focused))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PATTERN_PCRE2:
|
||||
if (regex_cmp(sandbox_app_id, criteria->sandbox_app_id->regex) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (criteria->sandbox_instance_id) {
|
||||
const char *sandbox_instance_id = view_get_sandbox_instance_id(view);
|
||||
if (!sandbox_instance_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (criteria->sandbox_instance_id->match_type) {
|
||||
case PATTERN_FOCUSED:
|
||||
if (focused && lenient_strcmp(sandbox_instance_id, view_get_sandbox_instance_id(focused))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PATTERN_PCRE2:
|
||||
if (regex_cmp(sandbox_instance_id, criteria->sandbox_instance_id->regex) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (criteria->tag) {
|
||||
const char *tag = view_get_tag(view);
|
||||
if (!tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (criteria->tag->match_type) {
|
||||
case PATTERN_FOCUSED:
|
||||
if (focused && lenient_strcmp(tag, view_get_tag(focused))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PATTERN_PCRE2:
|
||||
if (regex_cmp(tag, criteria->tag->regex) < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!criteria_matches_container(criteria, view->container)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -475,6 +563,10 @@ enum criteria_token {
|
|||
T_URGENT,
|
||||
T_WORKSPACE,
|
||||
T_PID,
|
||||
T_SANDBOX_ENGINE,
|
||||
T_SANDBOX_APP_ID,
|
||||
T_SANDBOX_INSTANCE_ID,
|
||||
T_TAG,
|
||||
|
||||
T_INVALID,
|
||||
};
|
||||
|
|
@ -514,6 +606,14 @@ static enum criteria_token token_from_name(char *name) {
|
|||
return T_FLOATING;
|
||||
} else if (strcmp(name, "pid") == 0) {
|
||||
return T_PID;
|
||||
} else if (strcmp(name, "sandbox_engine") == 0) {
|
||||
return T_SANDBOX_ENGINE;
|
||||
} else if (strcmp(name, "sandbox_app_id") == 0) {
|
||||
return T_SANDBOX_APP_ID;
|
||||
} else if (strcmp(name, "sandbox_instance_id") == 0) {
|
||||
return T_SANDBOX_INSTANCE_ID;
|
||||
} else if (strcmp(name, "tag") == 0) {
|
||||
return T_TAG;
|
||||
}
|
||||
return T_INVALID;
|
||||
}
|
||||
|
|
@ -555,8 +655,7 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
|||
if (strcmp(value, "__focused__") == 0) {
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
struct sway_container *focus = seat_get_focused_container(seat);
|
||||
struct sway_view *view = focus ? focus->view : NULL;
|
||||
criteria->con_id = view ? view->container->node.id : 0;
|
||||
criteria->con_id = focus ? focus->node.id : 0;
|
||||
} else {
|
||||
criteria->con_id = strtoul(value, &endptr, 10);
|
||||
if (*endptr != 0) {
|
||||
|
|
@ -617,6 +716,18 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
|||
error = strdup("The value for 'pid' should be numeric");
|
||||
}
|
||||
break;
|
||||
case T_SANDBOX_ENGINE:
|
||||
pattern_create(&criteria->sandbox_engine, value);
|
||||
break;
|
||||
case T_SANDBOX_APP_ID:
|
||||
pattern_create(&criteria->sandbox_app_id, value);
|
||||
break;
|
||||
case T_SANDBOX_INSTANCE_ID:
|
||||
pattern_create(&criteria->sandbox_instance_id, value);
|
||||
break;
|
||||
case T_TAG:
|
||||
pattern_create(&criteria->tag, value);
|
||||
break;
|
||||
case T_INVALID:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
#include "log.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
#include "sway/input/seat.h"
|
||||
|
|
@ -44,6 +45,14 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
|||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
|
||||
void handle_manager_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager =
|
||||
wl_container_of(listener, manager, manager_destroy);
|
||||
|
||||
wl_list_remove(&manager->manager_destroy.link);
|
||||
wl_list_remove(&manager->new_idle_inhibitor_v1.link);
|
||||
}
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||
enum sway_idle_inhibit_mode mode) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
|
|
@ -103,11 +112,34 @@ void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
|||
}
|
||||
|
||||
bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||
if (server.session_lock.lock) {
|
||||
// A session lock is active. In this case, only application inhibitors
|
||||
// on the session lock surface can have any effect.
|
||||
if (inhibitor->mode != INHIBIT_IDLE_APPLICATION) {
|
||||
return false;
|
||||
}
|
||||
struct wlr_surface *wlr_surface = inhibitor->wlr_inhibitor->surface;
|
||||
if (!wlr_session_lock_surface_v1_try_from_wlr_surface(wlr_surface)) {
|
||||
return false;
|
||||
}
|
||||
return wlr_surface->mapped;
|
||||
}
|
||||
|
||||
switch (inhibitor->mode) {
|
||||
case INHIBIT_IDLE_APPLICATION:;
|
||||
// If there is no view associated with the inhibitor, assume visible
|
||||
struct sway_view *view = view_from_wlr_surface(inhibitor->wlr_inhibitor->surface);
|
||||
return !view || !view->container || view_is_visible(view);
|
||||
struct wlr_surface *wlr_surface = inhibitor->wlr_inhibitor->surface;
|
||||
struct wlr_layer_surface_v1 *layer_surface =
|
||||
wlr_layer_surface_v1_try_from_wlr_surface(wlr_surface);
|
||||
if (layer_surface) {
|
||||
// Layer surfaces can be occluded but are always on screen after
|
||||
// they have been mapped.
|
||||
return layer_surface->output && layer_surface->output->enabled &&
|
||||
wlr_surface->mapped;
|
||||
}
|
||||
|
||||
// If there is no view associated with the inhibitor, assume invisible
|
||||
struct sway_view *view = view_from_wlr_surface(wlr_surface);
|
||||
return view && view->container && view_is_visible(view);
|
||||
case INHIBIT_IDLE_FOCUS:;
|
||||
struct sway_seat *seat = NULL;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
|
|
@ -153,6 +185,9 @@ bool sway_idle_inhibit_manager_v1_init(void) {
|
|||
wl_signal_add(&manager->wlr_manager->events.new_inhibitor,
|
||||
&manager->new_idle_inhibitor_v1);
|
||||
manager->new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1;
|
||||
wl_signal_add(&manager->wlr_manager->events.destroy,
|
||||
&manager->manager_destroy);
|
||||
manager->manager_destroy.notify = handle_manager_destroy;
|
||||
wl_list_init(&manager->inhibitors);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -216,14 +216,6 @@ static struct sway_layer_surface *find_mapped_layer_by_client(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void handle_output_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_surface *layer =
|
||||
wl_container_of(listener, layer, output_destroy);
|
||||
|
||||
layer->output = NULL;
|
||||
wlr_scene_node_destroy(&layer->scene->tree->node);
|
||||
}
|
||||
|
||||
static void handle_node_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_surface *layer =
|
||||
wl_container_of(listener, layer, node_destroy);
|
||||
|
|
@ -256,10 +248,11 @@ static void handle_node_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&layer->unmap.link);
|
||||
wl_list_remove(&layer->surface_commit.link);
|
||||
wl_list_remove(&layer->node_destroy.link);
|
||||
wl_list_remove(&layer->output_destroy.link);
|
||||
wl_list_remove(&layer->new_popup.link);
|
||||
|
||||
layer->layer_surface->data = NULL;
|
||||
|
||||
wl_list_remove(&layer->link);
|
||||
free(layer);
|
||||
}
|
||||
|
||||
|
|
@ -268,12 +261,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, surface, surface_commit);
|
||||
|
||||
struct wlr_layer_surface_v1 *layer_surface = surface->layer_surface;
|
||||
if (!layer_surface->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t committed = layer_surface->current.committed;
|
||||
if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) {
|
||||
if (layer_surface->initialized && committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) {
|
||||
enum zwlr_layer_shell_v1_layer layer_type = layer_surface->current.layer;
|
||||
struct wlr_scene_tree *output_layer = sway_layer_get_scene(
|
||||
surface->output, layer_type);
|
||||
|
|
@ -478,6 +467,7 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
surface->output = output;
|
||||
wl_list_insert(&output->layer_surfaces, &surface->link);
|
||||
|
||||
// now that the surface's output is known, we can advertise its scale
|
||||
wlr_fractional_scale_v1_notify_scale(surface->layer_surface->surface,
|
||||
|
|
@ -495,9 +485,14 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
|
|||
surface->new_popup.notify = handle_new_popup;
|
||||
wl_signal_add(&layer_surface->events.new_popup, &surface->new_popup);
|
||||
|
||||
surface->output_destroy.notify = handle_output_destroy;
|
||||
wl_signal_add(&output->events.disable, &surface->output_destroy);
|
||||
|
||||
surface->node_destroy.notify = handle_node_destroy;
|
||||
wl_signal_add(&scene_surface->tree->node.events.destroy, &surface->node_destroy);
|
||||
}
|
||||
|
||||
void destroy_layers(struct sway_output *output) {
|
||||
struct sway_layer_surface *layer, *layer_tmp;
|
||||
wl_list_for_each_safe(layer, layer_tmp, &output->layer_surfaces, link) {
|
||||
layer->output = NULL;
|
||||
wlr_layer_surface_v1_destroy(layer->layer_surface);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
|
|
@ -98,11 +97,11 @@ struct buffer_timer {
|
|||
};
|
||||
|
||||
static int handle_buffer_timer(void *data) {
|
||||
struct wlr_scene_buffer *buffer = data;
|
||||
struct wlr_scene_surface *scene_surface = data;
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
wlr_scene_buffer_send_frame_done(buffer, &now);
|
||||
wlr_scene_surface_send_frame_done(scene_surface, &now);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +114,9 @@ static void handle_buffer_timer_destroy(struct wl_listener *listener,
|
|||
free(timer);
|
||||
}
|
||||
|
||||
static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_buffer *buffer) {
|
||||
static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_surface *scene_surface) {
|
||||
struct wlr_scene_buffer *buffer = scene_surface->buffer;
|
||||
|
||||
struct buffer_timer *timer =
|
||||
scene_descriptor_try_get(&buffer->node, SWAY_SCENE_DESC_BUFFER_TIMER);
|
||||
if (timer) {
|
||||
|
|
@ -128,7 +129,7 @@ static struct buffer_timer *buffer_timer_get_or_create(struct wlr_scene_buffer *
|
|||
}
|
||||
|
||||
timer->frame_done_timer = wl_event_loop_add_timer(server.wl_event_loop,
|
||||
handle_buffer_timer, buffer);
|
||||
handle_buffer_timer, scene_surface);
|
||||
if (!timer->frame_done_timer) {
|
||||
free(timer);
|
||||
return NULL;
|
||||
|
|
@ -152,6 +153,11 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
|
|||
return;
|
||||
}
|
||||
|
||||
struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(buffer);
|
||||
if (scene_surface == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_scene_node *current = &buffer->node;
|
||||
while (true) {
|
||||
struct sway_view *view = scene_descriptor_try_get(current,
|
||||
|
|
@ -174,13 +180,13 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
|
|||
struct buffer_timer *timer = NULL;
|
||||
|
||||
if (output->max_render_time != 0 && view_max_render_time != 0 && delay > 0) {
|
||||
timer = buffer_timer_get_or_create(buffer);
|
||||
timer = buffer_timer_get_or_create(scene_surface);
|
||||
}
|
||||
|
||||
if (timer) {
|
||||
wl_event_source_timer_update(timer->frame_done_timer, delay);
|
||||
} else {
|
||||
wlr_scene_buffer_send_frame_done(buffer, &data->when);
|
||||
wlr_scene_surface_send_frame_done(scene_surface, &data->when);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,8 +194,8 @@ static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output,
|
|||
struct wlr_scene_buffer *buffer) {
|
||||
// if we are scaling down, we should always choose linear
|
||||
if (buffer->dst_width > 0 && buffer->dst_height > 0 && (
|
||||
buffer->dst_width < buffer->buffer_width ||
|
||||
buffer->dst_height < buffer->buffer_height)) {
|
||||
buffer->dst_width < buffer->WLR_PRIVATE.buffer_width ||
|
||||
buffer->dst_height < buffer->WLR_PRIVATE.buffer_height)) {
|
||||
return WLR_SCALE_FILTER_BILINEAR;
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +209,7 @@ static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output,
|
|||
}
|
||||
}
|
||||
|
||||
static void output_configure_scene(struct sway_output *output,
|
||||
void output_configure_scene(struct sway_output *output,
|
||||
struct wlr_scene_node *node, float opacity) {
|
||||
if (!node->enabled) {
|
||||
return;
|
||||
|
|
@ -230,7 +236,9 @@ static void output_configure_scene(struct sway_output *output,
|
|||
// hack: don't call the scene setter because that will damage all outputs
|
||||
// We don't want to damage outputs that aren't our current output that
|
||||
// we're configuring
|
||||
buffer->filter_mode = get_scale_filter(output, buffer);
|
||||
if (output) {
|
||||
buffer->filter_mode = get_scale_filter(output, buffer);
|
||||
}
|
||||
|
||||
wlr_scene_buffer_set_opacity(buffer, opacity);
|
||||
} else if (node->type == WLR_SCENE_NODE_TREE) {
|
||||
|
|
@ -262,47 +270,29 @@ static bool output_can_tear(struct sway_output *output) {
|
|||
static int output_repaint_timer_handler(void *data) {
|
||||
struct sway_output *output = data;
|
||||
|
||||
if (!output->enabled) {
|
||||
output->wlr_output->frame_pending = false;
|
||||
if (!output->wlr_output->enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
output->wlr_output->frame_pending = false;
|
||||
|
||||
output_configure_scene(output, &root->root_scene->tree.node, 1.0f);
|
||||
|
||||
struct wlr_scene_output_state_options opts = {
|
||||
.color_transform = output->color_transform,
|
||||
};
|
||||
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct wlr_scene_output *scene_output = output->scene_output;
|
||||
if (!wlr_output->needs_frame && !output->gamma_lut_changed &&
|
||||
!pixman_region32_not_empty(&scene_output->pending_commit_damage)) {
|
||||
if (!wlr_scene_output_needs_frame(scene_output)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct wlr_output_state pending;
|
||||
wlr_output_state_init(&pending);
|
||||
if (!wlr_scene_output_build_state(output->scene_output, &pending, &opts)) {
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (output->gamma_lut_changed) {
|
||||
output->gamma_lut_changed = false;
|
||||
struct wlr_gamma_control_v1 *gamma_control =
|
||||
wlr_gamma_control_manager_v1_get_control(
|
||||
server.gamma_control_manager_v1, output->wlr_output);
|
||||
if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!wlr_output_test_state(output->wlr_output, &pending)) {
|
||||
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
|
||||
wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (output_can_tear(output)) {
|
||||
pending.tearing_page_flip = true;
|
||||
|
||||
|
|
@ -426,27 +416,43 @@ void request_modeset(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void begin_destroy(struct sway_output *output) {
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
bool modeset_is_pending(void) {
|
||||
return server.delayed_modeset != NULL;
|
||||
}
|
||||
|
||||
void force_modeset(void) {
|
||||
if (server.delayed_modeset != NULL) {
|
||||
wl_event_source_remove(server.delayed_modeset);
|
||||
server.delayed_modeset = NULL;
|
||||
}
|
||||
apply_stored_output_configs();
|
||||
}
|
||||
|
||||
output_begin_destroy(output);
|
||||
|
||||
wl_list_remove(&output->link);
|
||||
static void begin_destroy(struct sway_output *output) {
|
||||
|
||||
wl_list_remove(&output->layout_destroy.link);
|
||||
wl_list_remove(&output->destroy.link);
|
||||
wl_list_remove(&output->commit.link);
|
||||
wl_list_remove(&output->present.link);
|
||||
wl_list_remove(&output->frame.link);
|
||||
wl_list_remove(&output->request_state.link);
|
||||
|
||||
// Remove the scene_output first to ensure that the scene does not emit
|
||||
// events for this output.
|
||||
wlr_scene_output_destroy(output->scene_output);
|
||||
output->scene_output = NULL;
|
||||
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
}
|
||||
output_begin_destroy(output);
|
||||
wl_list_remove(&output->link);
|
||||
|
||||
output->wlr_output->data = NULL;
|
||||
output->wlr_output = NULL;
|
||||
|
||||
wl_event_source_remove(output->repaint_timer);
|
||||
output->repaint_timer = NULL;
|
||||
|
||||
request_modeset();
|
||||
}
|
||||
|
||||
|
|
@ -460,20 +466,6 @@ static void handle_layout_destroy(struct wl_listener *listener, void *data) {
|
|||
begin_destroy(output);
|
||||
}
|
||||
|
||||
static void handle_commit(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output = wl_container_of(listener, output, commit);
|
||||
struct wlr_output_event_commit *event = data;
|
||||
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Next time the output is enabled, try to re-apply the gamma LUT
|
||||
if ((event->state->committed & WLR_OUTPUT_STATE_ENABLED) && !output->wlr_output->enabled) {
|
||||
output->gamma_lut_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_present(struct wl_listener *listener, void *data) {
|
||||
struct sway_output *output = wl_container_of(listener, output, present);
|
||||
struct wlr_output_event_present *output_event = data;
|
||||
|
|
@ -482,7 +474,7 @@ static void handle_present(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
output->last_presentation = *output_event->when;
|
||||
output->last_presentation = output_event->when;
|
||||
output->refresh_nsec = output_event->refresh;
|
||||
}
|
||||
|
||||
|
|
@ -490,20 +482,44 @@ static void handle_request_state(struct wl_listener *listener, void *data) {
|
|||
struct sway_output *output =
|
||||
wl_container_of(listener, output, request_state);
|
||||
const struct wlr_output_event_request_state *event = data;
|
||||
const struct wlr_output_state *state = event->state;
|
||||
|
||||
uint32_t committed = event->state->committed;
|
||||
wlr_output_commit_state(output->wlr_output, event->state);
|
||||
|
||||
if (committed & (
|
||||
WLR_OUTPUT_STATE_MODE |
|
||||
WLR_OUTPUT_STATE_TRANSFORM |
|
||||
WLR_OUTPUT_STATE_SCALE)) {
|
||||
arrange_layers(output);
|
||||
arrange_output(output);
|
||||
transaction_commit_dirty();
|
||||
|
||||
update_output_manager_config(output->server);
|
||||
// Store the requested changes so that the active configuration is
|
||||
// consistent with the current state, and to avoid duplicate logic to apply
|
||||
// the changes.
|
||||
struct output_config *oc = new_output_config(output->wlr_output->name);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int committed = state->committed;
|
||||
if (committed & WLR_OUTPUT_STATE_MODE) {
|
||||
if (state->mode != NULL) {
|
||||
oc->width = state->mode->width;
|
||||
oc->height = state->mode->height;
|
||||
oc->refresh_rate = state->mode->refresh / 1000.f;
|
||||
} else {
|
||||
oc->width = state->custom_mode.width;
|
||||
oc->height = state->custom_mode.height;
|
||||
oc->refresh_rate = state->custom_mode.refresh / 1000.f;
|
||||
}
|
||||
committed &= ~WLR_OUTPUT_STATE_MODE;
|
||||
}
|
||||
if (committed & WLR_OUTPUT_STATE_SCALE) {
|
||||
oc->scale = state->scale;
|
||||
committed &= ~WLR_OUTPUT_STATE_SCALE;
|
||||
}
|
||||
if (committed & WLR_OUTPUT_STATE_TRANSFORM) {
|
||||
oc->transform = state->transform;
|
||||
committed &= ~WLR_OUTPUT_STATE_TRANSFORM;
|
||||
}
|
||||
|
||||
// We do not expect or support any other changes here
|
||||
assert(committed == 0);
|
||||
store_output_config(oc);
|
||||
|
||||
force_modeset();
|
||||
}
|
||||
|
||||
static unsigned int last_headless_num = 0;
|
||||
|
|
@ -567,8 +583,6 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||
output->layout_destroy.notify = handle_layout_destroy;
|
||||
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
||||
output->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&wlr_output->events.commit, &output->commit);
|
||||
output->commit.notify = handle_commit;
|
||||
wl_signal_add(&wlr_output->events.present, &output->present);
|
||||
output->present.notify = handle_present;
|
||||
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
||||
|
|
@ -586,24 +600,13 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||
request_modeset();
|
||||
}
|
||||
|
||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
|
||||
struct sway_server *server =
|
||||
wl_container_of(listener, server, gamma_control_set_gamma);
|
||||
const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
|
||||
|
||||
struct sway_output *output = event->output->data;
|
||||
|
||||
if(!output) {
|
||||
return;
|
||||
}
|
||||
|
||||
output->gamma_lut_changed = true;
|
||||
wlr_output_schedule_frame(output->wlr_output);
|
||||
}
|
||||
|
||||
static struct output_config *output_config_for_config_head(
|
||||
struct wlr_output_configuration_head_v1 *config_head) {
|
||||
struct output_config *oc = new_output_config(config_head->state.output->name);
|
||||
if (!oc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oc->enabled = config_head->state.enabled;
|
||||
if (!oc->enabled) {
|
||||
return oc;
|
||||
|
|
@ -634,7 +637,8 @@ static void output_manager_apply(struct sway_server *server,
|
|||
size_t configs_len = config->output_configs->length + wl_list_length(&cfg->heads);
|
||||
struct output_config **configs = calloc(configs_len, sizeof(*configs));
|
||||
if (!configs) {
|
||||
goto done;
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
goto error;
|
||||
}
|
||||
size_t start_new_configs = config->output_configs->length;
|
||||
for (size_t idx = 0; idx < start_new_configs; idx++) {
|
||||
|
|
@ -647,6 +651,10 @@ static void output_manager_apply(struct sway_server *server,
|
|||
// Generate the configuration and store it as a temporary
|
||||
// config. We keep a record of it so we can remove it later.
|
||||
struct output_config *oc = output_config_for_config_head(config_head);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
goto error_config;
|
||||
}
|
||||
configs[config_idx++] = oc;
|
||||
}
|
||||
|
||||
|
|
@ -654,6 +662,8 @@ static void output_manager_apply(struct sway_server *server,
|
|||
// if any output configured for enablement fails to be enabled, even if it
|
||||
// was not part of the config heads we were asked to configure.
|
||||
ok = apply_output_configs(configs, configs_len, test_only, false);
|
||||
|
||||
error_config:
|
||||
for (size_t idx = start_new_configs; idx < configs_len; idx++) {
|
||||
struct output_config *cfg = configs[idx];
|
||||
if (!test_only && ok) {
|
||||
|
|
@ -664,7 +674,7 @@ static void output_manager_apply(struct sway_server *server,
|
|||
}
|
||||
free(configs);
|
||||
|
||||
done:
|
||||
error:
|
||||
if (ok) {
|
||||
wlr_output_configuration_v1_send_succeeded(cfg);
|
||||
if (server->delayed_modeset != NULL) {
|
||||
|
|
@ -699,6 +709,11 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
|||
struct sway_output *output = event->output->data;
|
||||
|
||||
struct output_config *oc = new_output_config(output->wlr_output->name);
|
||||
if (!oc) {
|
||||
sway_log(SWAY_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->mode) {
|
||||
case ZWLR_OUTPUT_POWER_V1_MODE_OFF:
|
||||
oc->power = 0;
|
||||
|
|
|
|||
|
|
@ -309,12 +309,13 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
arrange_title_bar(child, title_offset, -title_bar_height,
|
||||
next_title_offset - title_offset, title_bar_height);
|
||||
wlr_scene_node_set_enabled(&child->border.tree->node, activated);
|
||||
wlr_scene_node_set_enabled(&child->scene_tree->node, true);
|
||||
wlr_scene_node_set_position(&child->scene_tree->node, 0, title_bar_height);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_bar_height,
|
||||
title_bar_height == 0, 0);
|
||||
int net_height = height - title_bar_height;
|
||||
if (activated && width > 0 && net_height > 0) {
|
||||
arrange_container(child, width, net_height, title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
|
@ -338,12 +339,13 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
|
||||
arrange_title_bar(child, 0, y - title_height, width, title_bar_height);
|
||||
wlr_scene_node_set_enabled(&child->border.tree->node, activated);
|
||||
wlr_scene_node_set_enabled(&child->scene_tree->node, true);
|
||||
wlr_scene_node_set_position(&child->scene_tree->node, 0, title_height);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_height,
|
||||
title_bar_height == 0, 0);
|
||||
int net_height = height - title_height;
|
||||
if (activated && width > 0 && net_height > 0) {
|
||||
arrange_container(child, width, net_height, title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
|
@ -359,8 +361,12 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_enabled(&child->border.tree->node, true);
|
||||
wlr_scene_node_set_position(&child->scene_tree->node, 0, off);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
arrange_container(child, width, cheight, true, gaps);
|
||||
off += cheight + gaps;
|
||||
if (width > 0 && cheight > 0) {
|
||||
arrange_container(child, width, cheight, true, gaps);
|
||||
off += cheight + gaps;
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
}
|
||||
} else if (layout == L_HORIZ) {
|
||||
int off = 0;
|
||||
|
|
@ -371,8 +377,12 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
wlr_scene_node_set_enabled(&child->border.tree->node, true);
|
||||
wlr_scene_node_set_position(&child->scene_tree->node, off, 0);
|
||||
wlr_scene_node_reparent(&child->scene_tree->node, content);
|
||||
arrange_container(child, cwidth, height, true, gaps);
|
||||
off += cwidth + gaps;
|
||||
if (cwidth > 0 && height > 0) {
|
||||
arrange_container(child, cwidth, height, true, gaps);
|
||||
off += cwidth + gaps;
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sway_assert(false, "unreachable");
|
||||
|
|
@ -424,13 +434,14 @@ static void arrange_container(struct sway_container *con,
|
|||
int border_bottom = con->current.border_bottom ? border_width : 0;
|
||||
int border_left = con->current.border_left ? border_width : 0;
|
||||
int border_right = con->current.border_right ? border_width : 0;
|
||||
int vert_border_height = MAX(0, height - border_top - border_bottom);
|
||||
|
||||
wlr_scene_rect_set_size(con->border.top, width, border_top);
|
||||
wlr_scene_rect_set_size(con->border.bottom, width, border_bottom);
|
||||
wlr_scene_rect_set_size(con->border.left,
|
||||
border_left, height - border_top - border_bottom);
|
||||
border_left, vert_border_height);
|
||||
wlr_scene_rect_set_size(con->border.right,
|
||||
border_right, height - border_top - border_bottom);
|
||||
border_right, vert_border_height);
|
||||
|
||||
wlr_scene_node_set_position(&con->border.top->node, 0, 0);
|
||||
wlr_scene_node_set_position(&con->border.bottom->node,
|
||||
|
|
@ -523,6 +534,7 @@ static void arrange_workspace_floating(struct sway_workspace *ws) {
|
|||
wlr_scene_node_set_position(&floater->scene_tree->node,
|
||||
floater->current.x, floater->current.y);
|
||||
wlr_scene_node_set_enabled(&floater->scene_tree->node, true);
|
||||
wlr_scene_node_set_enabled(&floater->border.tree->node, true);
|
||||
|
||||
arrange_container(floater, floater->current.width, floater->current.height,
|
||||
true, ws->gaps_inner);
|
||||
|
|
@ -575,15 +587,16 @@ static void arrange_output(struct sway_output *output, int width, int height) {
|
|||
wlr_scene_node_set_enabled(&child->layers.tiling->node, !fs);
|
||||
wlr_scene_node_set_enabled(&child->layers.fullscreen->node, fs);
|
||||
|
||||
arrange_workspace_floating(child);
|
||||
|
||||
wlr_scene_node_set_enabled(&output->layers.shell_background->node, !fs);
|
||||
wlr_scene_node_set_enabled(&output->layers.shell_bottom->node, !fs);
|
||||
wlr_scene_node_set_enabled(&output->layers.fullscreen->node, fs);
|
||||
|
||||
if (fs) {
|
||||
disable_workspace(child);
|
||||
|
||||
wlr_scene_rect_set_size(output->fullscreen_background, width, height);
|
||||
|
||||
arrange_workspace_floating(child);
|
||||
arrange_fullscreen(child->layers.fullscreen, fs, child,
|
||||
width, height);
|
||||
} else {
|
||||
|
|
@ -596,6 +609,7 @@ static void arrange_output(struct sway_output *output, int width, int height) {
|
|||
arrange_workspace_tiling(child,
|
||||
area->width - gaps->left - gaps->right,
|
||||
area->height - gaps->top - gaps->bottom);
|
||||
arrange_workspace_floating(child);
|
||||
}
|
||||
} else {
|
||||
wlr_scene_node_set_enabled(&child->layers.tiling->node, false);
|
||||
|
|
@ -651,6 +665,15 @@ static void arrange_root(struct sway_root *root) {
|
|||
struct sway_output *output = root->outputs->items[i];
|
||||
struct sway_workspace *ws = output->current.active_workspace;
|
||||
|
||||
wlr_scene_output_set_position(output->scene_output, output->lx, output->ly);
|
||||
|
||||
// disable all workspaces to get to a known state
|
||||
for (int j = 0; j < output->current.workspaces->length; j++) {
|
||||
struct sway_workspace *workspace = output->current.workspaces->items[j];
|
||||
disable_workspace(workspace);
|
||||
}
|
||||
|
||||
// arrange the active workspace
|
||||
if (ws) {
|
||||
arrange_workspace_floating(ws);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/types/wlr_xdg_toplevel_tag_v1.h>
|
||||
#include <wlr/util/edges.h>
|
||||
#include "log.h"
|
||||
#include "sway/decoration.h"
|
||||
|
|
@ -20,13 +21,13 @@
|
|||
|
||||
static struct sway_xdg_popup *popup_create(
|
||||
struct wlr_xdg_popup *wlr_popup, struct sway_view *view,
|
||||
struct wlr_scene_tree *parent);
|
||||
struct wlr_scene_tree *parent, struct wlr_scene_tree *image_capture_parent);
|
||||
|
||||
static void popup_handle_new_popup(struct wl_listener *listener, void *data) {
|
||||
struct sway_xdg_popup *popup =
|
||||
wl_container_of(listener, popup, new_popup);
|
||||
struct wlr_xdg_popup *wlr_popup = data;
|
||||
popup_create(wlr_popup, popup->view, popup->xdg_surface_tree);
|
||||
popup_create(wlr_popup, popup->view, popup->xdg_surface_tree, popup->image_capture_tree);
|
||||
}
|
||||
|
||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -77,7 +78,8 @@ static void popup_handle_reposition(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
|
||||
struct sway_view *view, struct wlr_scene_tree *parent) {
|
||||
struct sway_view *view, struct wlr_scene_tree *parent,
|
||||
struct wlr_scene_tree *image_capture_parent) {
|
||||
struct wlr_xdg_surface *xdg_surface = wlr_popup->base;
|
||||
|
||||
struct sway_xdg_popup *popup = calloc(1, sizeof(struct sway_xdg_popup));
|
||||
|
|
@ -113,6 +115,11 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
popup->image_capture_tree = wlr_scene_xdg_surface_create(image_capture_parent, xdg_surface);
|
||||
if (popup->image_capture_tree == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
popup->wlr_xdg_popup = xdg_surface->popup;
|
||||
struct sway_xdg_shell_view *shell_view =
|
||||
wl_container_of(view, shell_view, view);
|
||||
|
|
@ -151,7 +158,8 @@ static void get_constraints(struct sway_view *view, double *min_width,
|
|||
|
||||
static const char *get_string_prop(struct sway_view *view,
|
||||
enum sway_view_prop prop) {
|
||||
if (xdg_shell_view_from_view(view) == NULL) {
|
||||
struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
|
||||
if (xdg_shell_view == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
switch (prop) {
|
||||
|
|
@ -159,6 +167,8 @@ static const char *get_string_prop(struct sway_view *view,
|
|||
return view->wlr_xdg_toplevel->title;
|
||||
case VIEW_PROP_APP_ID:
|
||||
return view->wlr_xdg_toplevel->app_id;
|
||||
case VIEW_PROP_TAG:
|
||||
return xdg_shell_view->tag;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -259,6 +269,7 @@ static void destroy(struct sway_view *view) {
|
|||
if (xdg_shell_view == NULL) {
|
||||
return;
|
||||
}
|
||||
free(xdg_shell_view->tag);
|
||||
free(xdg_shell_view);
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +301,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||
// XXX: https://github.com/swaywm/sway/issues/2176
|
||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
|
||||
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
// TODO: wlr_xdg_toplevel_set_bounds()
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,18 +310,17 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct wlr_box new_geo;
|
||||
wlr_xdg_surface_get_geometry(xdg_surface, &new_geo);
|
||||
bool new_size = new_geo.width != view->geometry.width ||
|
||||
new_geo.height != view->geometry.height ||
|
||||
new_geo.x != view->geometry.x ||
|
||||
new_geo.y != view->geometry.y;
|
||||
struct wlr_box *new_geo = &xdg_surface->geometry;
|
||||
bool new_size = new_geo->width != view->geometry.width ||
|
||||
new_geo->height != view->geometry.height ||
|
||||
new_geo->x != view->geometry.x ||
|
||||
new_geo->y != view->geometry.y;
|
||||
|
||||
if (new_size) {
|
||||
// The client changed its surface size in this commit. For floating
|
||||
// containers, we resize the container to match. For tiling containers,
|
||||
// we only recenter the surface.
|
||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||
memcpy(&view->geometry, new_geo, sizeof(struct wlr_box));
|
||||
if (container_is_floating(view->container)) {
|
||||
view_update_size(view);
|
||||
// Only set the toplevel size the current container actually has a size.
|
||||
|
|
@ -360,7 +370,7 @@ static void handle_new_popup(struct wl_listener *listener, void *data) {
|
|||
struct wlr_xdg_popup *wlr_popup = data;
|
||||
|
||||
struct sway_xdg_popup *popup = popup_create(wlr_popup,
|
||||
&xdg_shell_view->view, root->layers.popup);
|
||||
&xdg_shell_view->view, root->layers.popup, xdg_shell_view->image_capture_tree);
|
||||
if (!popup) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -463,12 +473,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
struct sway_view *view = &xdg_shell_view->view;
|
||||
struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_toplevel;
|
||||
|
||||
view->natural_width = toplevel->base->current.geometry.width;
|
||||
view->natural_height = toplevel->base->current.geometry.height;
|
||||
if (!view->natural_width && !view->natural_height) {
|
||||
view->natural_width = toplevel->base->surface->current.width;
|
||||
view->natural_height = toplevel->base->surface->current.height;
|
||||
}
|
||||
view->natural_width = toplevel->base->geometry.width;
|
||||
view->natural_height = toplevel->base->geometry.height;
|
||||
|
||||
bool csd = false;
|
||||
|
||||
|
|
@ -575,6 +581,17 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
|
|||
wl_signal_add(&xdg_toplevel->events.destroy, &xdg_shell_view->destroy);
|
||||
|
||||
wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base);
|
||||
xdg_shell_view->image_capture_tree =
|
||||
wlr_scene_xdg_surface_create(&xdg_shell_view->view.image_capture_scene->tree, xdg_toplevel->base);
|
||||
|
||||
xdg_toplevel->base->data = xdg_shell_view;
|
||||
}
|
||||
|
||||
void xdg_toplevel_tag_manager_v1_handle_set_tag(struct wl_listener *listener, void *data) {
|
||||
const struct wlr_xdg_toplevel_tag_manager_v1_set_tag_event *event = data;
|
||||
struct sway_view *view = view_from_wlr_xdg_surface(event->toplevel->base);
|
||||
struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
|
||||
free(xdg_shell_view->tag);
|
||||
xdg_shell_view->tag = strdup(event->tag);
|
||||
view_execute_criteria(view);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
|
|||
surface->set_geometry.notify = unmanaged_handle_set_geometry;
|
||||
}
|
||||
|
||||
if (wlr_xwayland_or_surface_wants_focus(xsurface)) {
|
||||
if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
|
||||
wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
|
||||
|
|
@ -96,7 +96,7 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
|
|||
// This simply returns focus to the parent surface if there's one available.
|
||||
// This seems to handle JetBrains issues.
|
||||
if (xsurface->parent && xsurface->parent->surface
|
||||
&& wlr_xwayland_or_surface_wants_focus(xsurface->parent)) {
|
||||
&& wlr_xwayland_surface_override_redirect_wants_focus(xsurface->parent)) {
|
||||
seat_set_focus_surface(seat, xsurface->parent->surface, false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -289,9 +289,6 @@ static void set_activated(struct sway_view *view, bool activated) {
|
|||
}
|
||||
|
||||
wlr_xwayland_surface_activate(surface, activated);
|
||||
if (activated) {
|
||||
wlr_xwayland_surface_restack(surface, NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_tiled(struct sway_view *view, bool tiled) {
|
||||
|
|
@ -299,7 +296,7 @@ static void set_tiled(struct sway_view *view, bool tiled) {
|
|||
return;
|
||||
}
|
||||
struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
|
||||
wlr_xwayland_surface_set_maximized(surface, tiled);
|
||||
wlr_xwayland_surface_set_maximized(surface, tiled, tiled);
|
||||
}
|
||||
|
||||
static void set_fullscreen(struct sway_view *view, bool fullscreen) {
|
||||
|
|
@ -500,6 +497,9 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&xwayland_view->commit.link);
|
||||
wl_list_remove(&xwayland_view->surface_tree_destroy.link);
|
||||
|
||||
wlr_scene_node_destroy(&xwayland_view->image_capture_scene_surface->buffer->node);
|
||||
xwayland_view->image_capture_scene_surface = NULL;
|
||||
|
||||
if (xwayland_view->surface_tree) {
|
||||
wlr_scene_node_destroy(&xwayland_view->surface_tree->node);
|
||||
xwayland_view->surface_tree = NULL;
|
||||
|
|
@ -540,6 +540,9 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
&xwayland_view->surface_tree_destroy);
|
||||
}
|
||||
|
||||
xwayland_view->image_capture_scene_surface =
|
||||
wlr_scene_surface_create(&xwayland_view->view.image_capture_scene->tree, xsurface->surface);
|
||||
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,6 @@
|
|||
#include "sway/tree/workspace.h"
|
||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
||||
|
||||
static uint32_t get_current_time_msec(void) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node at the cursor's position. If there is a surface at that
|
||||
* location, it is stored in **surface (it may not be a view).
|
||||
|
|
@ -144,7 +138,7 @@ struct sway_node *node_at_coords(
|
|||
}
|
||||
|
||||
void cursor_rebase(struct sway_cursor *cursor) {
|
||||
uint32_t time_msec = get_current_time_msec();
|
||||
uint32_t time_msec = get_current_time_in_msec();
|
||||
seatop_rebase(cursor->seat, time_msec);
|
||||
}
|
||||
|
||||
|
|
@ -359,7 +353,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
|
|||
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
|
||||
enum wl_pointer_button_state state) {
|
||||
if (time_msec == 0) {
|
||||
time_msec = get_current_time_msec();
|
||||
time_msec = get_current_time_in_msec();
|
||||
}
|
||||
|
||||
seatop_button(cursor->seat, time_msec, device, button, state);
|
||||
|
|
@ -578,12 +572,13 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
|
|||
// tablet events until the drag is released, even if we are now over a
|
||||
// non-tablet surface.
|
||||
if (!cursor->simulating_pointer_from_tool_tip &&
|
||||
((surface && wlr_surface_accepts_tablet_v2(tablet->tablet_v2, surface)) ||
|
||||
((surface && wlr_surface_accepts_tablet_v2(surface, tablet->tablet_v2)) ||
|
||||
wlr_tablet_tool_v2_has_implicit_grab(tool->tablet_v2_tool))) {
|
||||
seatop_tablet_tool_motion(seat, tool, time_msec);
|
||||
} else {
|
||||
wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool);
|
||||
pointer_motion(cursor, time_msec, input_device->wlr_device, dx, dy, dx, dy);
|
||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -664,7 +659,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
|||
dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec,
|
||||
BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED);
|
||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||
} else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) {
|
||||
} else if (!surface || !wlr_surface_accepts_tablet_v2(surface, tablet_v2)) {
|
||||
// If we started holding the tool tip down on a surface that accepts
|
||||
// tablet v2, we should notify that surface if it gets released over a
|
||||
// surface that doesn't support v2.
|
||||
|
|
@ -749,7 +744,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
|
|||
bool mod_pressed = modifiers & config->floating_mod;
|
||||
|
||||
bool surface_supports_tablet_events =
|
||||
surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface);
|
||||
surface && wlr_surface_accepts_tablet_v2(surface, tablet_v2);
|
||||
|
||||
// Simulate pointer when:
|
||||
// 1. The modifier key is pressed, OR
|
||||
|
|
@ -1047,6 +1042,7 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
|
|||
wl_list_remove(&cursor->touch_frame.link);
|
||||
wl_list_remove(&cursor->tool_axis.link);
|
||||
wl_list_remove(&cursor->tool_tip.link);
|
||||
wl_list_remove(&cursor->tool_proximity.link);
|
||||
wl_list_remove(&cursor->tool_button.link);
|
||||
wl_list_remove(&cursor->request_set_cursor.link);
|
||||
|
||||
|
|
@ -1212,7 +1208,7 @@ uint32_t get_mouse_bindsym(const char *name, char **error) {
|
|||
SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT,
|
||||
SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA};
|
||||
return buttons[number - 1];
|
||||
} else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) {
|
||||
} else if (has_prefix(name, "BTN_")) {
|
||||
// Get event code from name
|
||||
int code = libevdev_event_code_from_name(EV_KEY, name);
|
||||
if (code == -1) {
|
||||
|
|
@ -1237,7 +1233,7 @@ uint32_t get_mouse_bindcode(const char *name, char **error) {
|
|||
return 0;
|
||||
}
|
||||
const char *event = libevdev_event_code_get_name(EV_KEY, code);
|
||||
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
|
||||
if (!event || !has_prefix(event, "BTN_")) {
|
||||
*error = format_str("Event code %d (%s) is not a button",
|
||||
code, event ? event : "(null)");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -493,6 +493,14 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
|
|||
return input;
|
||||
}
|
||||
|
||||
void input_manager_finish(struct sway_input_manager *input) {
|
||||
wl_list_remove(&input->new_input.link);
|
||||
wl_list_remove(&input->virtual_keyboard_new.link);
|
||||
wl_list_remove(&input->virtual_pointer_new.link);
|
||||
wl_list_remove(&input->keyboard_shortcuts_inhibit_new_inhibitor.link);
|
||||
wl_list_remove(&input->transient_seat_create.link);
|
||||
}
|
||||
|
||||
bool input_manager_has_focus(struct sway_node *node) {
|
||||
struct sway_seat *seat = NULL;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
|
|
@ -577,7 +585,7 @@ void input_manager_configure_all_input_mappings(void) {
|
|||
void input_manager_apply_input_config(struct input_config *input_config) {
|
||||
struct sway_input_device *input_device = NULL;
|
||||
bool wildcard = strcmp(input_config->identifier, "*") == 0;
|
||||
bool type_wildcard = strncmp(input_config->identifier, "type:", 5) == 0;
|
||||
bool type_wildcard = has_prefix(input_config->identifier, "type:");
|
||||
wl_list_for_each(input_device, &server.input->devices, link) {
|
||||
bool type_matches = type_wildcard &&
|
||||
strcmp(input_device_get_type(input_device), input_config->identifier + 5) == 0;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <wlr/config.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_keyboard_group.h>
|
||||
#include <xkbcommon/xkbcommon-names.h>
|
||||
|
|
@ -267,6 +268,7 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
|
|||
const xkb_keysym_t *pressed_keysyms, uint32_t modifiers, size_t keysyms_len) {
|
||||
for (size_t i = 0; i < keysyms_len; ++i) {
|
||||
xkb_keysym_t keysym = pressed_keysyms[i];
|
||||
|
||||
if (keysym >= XKB_KEY_XF86Switch_VT_1 &&
|
||||
keysym <= XKB_KEY_XF86Switch_VT_12) {
|
||||
#if WLR_HAS_SESSION
|
||||
|
|
@ -282,6 +284,36 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool keyboard_execute_pointer_keysyms(struct sway_keyboard *keyboard,
|
||||
uint32_t time, const xkb_keysym_t *pressed_keysyms, size_t keysyms_len,
|
||||
enum wl_keyboard_key_state state) {
|
||||
struct sway_cursor *cursor = keyboard->seat_device->sway_seat->cursor;
|
||||
|
||||
for (size_t i = 0; i < keysyms_len; ++i) {
|
||||
xkb_keysym_t keysym = pressed_keysyms[i];
|
||||
|
||||
uint32_t button = wlr_keyboard_keysym_to_pointer_button(keysym);
|
||||
if (button != 0) {
|
||||
dispatch_cursor_button(cursor, &keyboard->wlr->base, time, button,
|
||||
(enum wl_pointer_button_state)state);
|
||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||
return true;
|
||||
}
|
||||
|
||||
int dx, dy;
|
||||
wlr_keyboard_keysym_to_pointer_motion(keysym, &dx, &dy);
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED && (dx != 0 || dy != 0)) {
|
||||
dx *= 10;
|
||||
dy *= 10;
|
||||
pointer_motion(cursor, time, &keyboard->wlr->base, dx, dy, dx, dy);
|
||||
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keysyms and modifiers from the keyboard as xkb sees them.
|
||||
*
|
||||
|
|
@ -507,6 +539,11 @@ static void handle_key_event(struct sway_keyboard *keyboard,
|
|||
keyboard, keyinfo.raw_keysyms, keyinfo.raw_modifiers,
|
||||
keyinfo.raw_keysyms_len);
|
||||
}
|
||||
if (!handled) {
|
||||
handled = keyboard_execute_pointer_keysyms(keyboard, event->time_msec,
|
||||
keyinfo.translated_keysyms, keyinfo.translated_keysyms_len,
|
||||
event->state);
|
||||
}
|
||||
|
||||
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
// If the pressed event was sent to a client and we have a focused
|
||||
|
|
@ -943,10 +980,10 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
|
|||
wl_signal_add(&sway_group->wlr_group->keyboard.events.modifiers,
|
||||
&sway_group->keyboard_modifiers);
|
||||
sway_group->keyboard_modifiers.notify = handle_keyboard_group_modifiers;
|
||||
|
||||
|
||||
wl_signal_add(&sway_group->wlr_group->events.enter, &sway_group->enter);
|
||||
sway_group->enter.notify = handle_keyboard_group_enter;
|
||||
|
||||
|
||||
wl_signal_add(&sway_group->wlr_group->events.leave, &sway_group->leave);
|
||||
sway_group->leave.notify = handle_keyboard_group_leave;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -391,6 +391,19 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool sway_udev_device_is_builtin(struct udev_device *udev_device) {
|
||||
const char *id_path = udev_device_get_property_value(udev_device, "ID_PATH");
|
||||
if (!id_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_prefix(id_path, "platform-")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return has_prefix(id_path, "pci-") && strstr(id_path, "-platform-");
|
||||
}
|
||||
|
||||
bool sway_libinput_device_is_builtin(struct sway_input_device *sway_device) {
|
||||
if (!wlr_input_device_is_libinput(sway_device->wlr_device)) {
|
||||
return false;
|
||||
|
|
@ -404,18 +417,7 @@ bool sway_libinput_device_is_builtin(struct sway_input_device *sway_device) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const char *id_path = udev_device_get_property_value(udev_device, "ID_PATH");
|
||||
if (!id_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char prefix_platform[] = "platform-";
|
||||
if (strncmp(id_path, prefix_platform, strlen(prefix_platform)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char prefix_pci[] = "pci-";
|
||||
const char infix_platform[] = "-platform-";
|
||||
return (strncmp(id_path, prefix_pci, strlen(prefix_pci)) == 0) &&
|
||||
strstr(id_path, infix_platform);
|
||||
bool is_builtin = sway_udev_device_is_builtin(udev_device);
|
||||
udev_device_unref(udev_device);
|
||||
return is_builtin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -647,10 +647,6 @@ static void seat_reset_input_config(struct sway_seat *seat,
|
|||
sway_device->input_device->wlr_device, NULL);
|
||||
}
|
||||
|
||||
static bool has_prefix(const char *str, const char *prefix) {
|
||||
return strncmp(str, prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the built-in output, if any. Returns NULL if there isn't
|
||||
* exactly one built-in output.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
|
@ -273,7 +274,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
|
|||
// Handle tapping on an xwayland unmanaged view
|
||||
else if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
|
||||
xsurface->override_redirect &&
|
||||
wlr_xwayland_or_surface_wants_focus(xsurface)) {
|
||||
wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
|
||||
struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
|
||||
wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
|
||||
seat_set_focus_surface(seat, xsurface->surface, false);
|
||||
|
|
@ -355,6 +356,13 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
|
||||
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||
|
||||
bool mod_pressed = modifiers & config->floating_mod;
|
||||
uint32_t mod_move_btn = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
uint32_t mod_resize_btn = config->floating_mod_inverse ? BTN_LEFT : BTN_RIGHT;
|
||||
bool mod_move_btn_pressed = mod_pressed && button == mod_move_btn;
|
||||
bool mod_resize_btn_pressed = mod_pressed && button == mod_resize_btn;
|
||||
bool titlebar_left_btn_pressed = on_titlebar && button == BTN_LEFT;
|
||||
|
||||
// Handle mouse bindings
|
||||
if (trigger_pointer_button_binding(seat, device, button, state, modifiers,
|
||||
on_titlebar, on_border, on_contents, on_workspace)) {
|
||||
|
|
@ -403,33 +411,28 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
}
|
||||
|
||||
// Handle tiling resize via mod
|
||||
bool mod_pressed = modifiers & config->floating_mod;
|
||||
if (cont && !is_floating_or_child && mod_pressed &&
|
||||
if (cont && !is_floating_or_child && mod_pressed && mod_resize_btn_pressed &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
uint32_t btn_resize = config->floating_mod_inverse ?
|
||||
BTN_LEFT : BTN_RIGHT;
|
||||
if (button == btn_resize) {
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > cont->pending.y + cont->pending.height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > cont->pending.x + cont->pending.width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > cont->pending.y + cont->pending.height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
|
||||
const char *image = NULL;
|
||||
if (edge == (WLR_EDGE_LEFT | WLR_EDGE_TOP)) {
|
||||
image = "nw-resize";
|
||||
} else if (edge == (WLR_EDGE_TOP | WLR_EDGE_RIGHT)) {
|
||||
image = "ne-resize";
|
||||
} else if (edge == (WLR_EDGE_RIGHT | WLR_EDGE_BOTTOM)) {
|
||||
image = "se-resize";
|
||||
} else if (edge == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT)) {
|
||||
image = "sw-resize";
|
||||
}
|
||||
cursor_set_image(seat->cursor, image, NULL);
|
||||
seat_set_focus_container(seat, cont);
|
||||
seatop_begin_resize_tiling(seat, cont, edge);
|
||||
return;
|
||||
const char *image = NULL;
|
||||
if (edge == (WLR_EDGE_LEFT | WLR_EDGE_TOP)) {
|
||||
image = "nw-resize";
|
||||
} else if (edge == (WLR_EDGE_TOP | WLR_EDGE_RIGHT)) {
|
||||
image = "ne-resize";
|
||||
} else if (edge == (WLR_EDGE_RIGHT | WLR_EDGE_BOTTOM)) {
|
||||
image = "se-resize";
|
||||
} else if (edge == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT)) {
|
||||
image = "sw-resize";
|
||||
}
|
||||
cursor_set_image(seat->cursor, image, NULL);
|
||||
seat_set_focus_container(seat, cont);
|
||||
seatop_begin_resize_tiling(seat, cont, edge);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle changing focus when clicking on a container
|
||||
|
|
@ -454,12 +457,10 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
|
||||
// Handle beginning floating move
|
||||
if (cont && is_floating_or_child && !is_fullscreen_or_child &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
if (button == btn_move && (mod_pressed || on_titlebar)) {
|
||||
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
|
||||
return;
|
||||
}
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED &&
|
||||
(mod_move_btn_pressed || titlebar_left_btn_pressed)) {
|
||||
seatop_begin_move_floating(seat, container_toplevel_ancestor(cont));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle beginning floating resize
|
||||
|
|
@ -473,9 +474,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
}
|
||||
|
||||
// Via mod+click
|
||||
uint32_t btn_resize = config->floating_mod_inverse ?
|
||||
BTN_LEFT : BTN_RIGHT;
|
||||
if (mod_pressed && button == btn_resize) {
|
||||
if (mod_resize_btn_pressed) {
|
||||
struct sway_container *floater = container_toplevel_ancestor(cont);
|
||||
edge = 0;
|
||||
edge |= cursor->cursor->x > floater->pending.x + floater->pending.width / 2 ?
|
||||
|
|
@ -489,18 +488,15 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
}
|
||||
|
||||
// Handle moving a tiling container
|
||||
if (config->tiling_drag && (mod_pressed || on_titlebar) &&
|
||||
if (config->tiling_drag && (mod_move_btn_pressed || titlebar_left_btn_pressed) &&
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating_or_child &&
|
||||
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE &&
|
||||
button == (config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT)) {
|
||||
|
||||
cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) {
|
||||
// If moving a container by its title bar, use a threshold for the drag
|
||||
if (!mod_pressed && config->tiling_drag_threshold > 0) {
|
||||
seatop_begin_move_tiling_threshold(seat, cont);
|
||||
} else {
|
||||
seatop_begin_move_tiling(seat, cont);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -523,7 +519,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
if (surface &&
|
||||
(xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
|
||||
xsurface->override_redirect &&
|
||||
wlr_xwayland_or_surface_wants_focus(xsurface)) {
|
||||
wlr_xwayland_surface_override_redirect_wants_focus(xsurface)) {
|
||||
struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
|
||||
wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
|
||||
seat_set_focus_surface(seat, xsurface->surface, false);
|
||||
|
|
@ -669,7 +665,7 @@ static void handle_touch_down(struct sway_seat *seat,
|
|||
double sx, sy;
|
||||
node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy);
|
||||
|
||||
if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) {
|
||||
if (surface && wlr_surface_accepts_touch(surface, wlr_seat)) {
|
||||
if (seat_is_input_allowed(seat, surface)) {
|
||||
cursor->simulating_pointer_from_touch = false;
|
||||
seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly);
|
||||
|
|
@ -798,7 +794,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
|
|||
|
||||
if (!handled) {
|
||||
wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
event->orientation, scroll_factor * event->delta,
|
||||
roundf(scroll_factor * event->delta_discrete), event->source,
|
||||
event->relative_direction);
|
||||
}
|
||||
|
|
@ -1115,7 +1111,7 @@ static void handle_rebase(struct sway_seat *seat, uint32_t time_msec) {
|
|||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (surface) {
|
||||
if (seat_is_input_allowed(seat, surface)) {
|
||||
if (seat_is_input_allowed(seat, surface) && !cursor->hidden) {
|
||||
wlr_seat_pointer_notify_enter(seat->wlr_seat, surface, sx, sy);
|
||||
wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy);
|
||||
}
|
||||
|
|
@ -1153,5 +1149,7 @@ void seatop_begin_default(struct sway_seat *seat) {
|
|||
|
||||
seat->seatop_impl = &seatop_impl;
|
||||
seat->seatop_data = e;
|
||||
seatop_rebase(seat, 0);
|
||||
|
||||
uint32_t time_msec = get_current_time_in_msec();
|
||||
seatop_rebase(seat, time_msec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ static void handle_touch_down(struct sway_seat *seat,
|
|||
|
||||
if (focused_node) {
|
||||
seat_set_focus(seat, focused_node);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ void sway_tablet_pad_set_focus(struct sway_tablet_pad *tablet_pad,
|
|||
}
|
||||
|
||||
if (surface == NULL ||
|
||||
!wlr_surface_accepts_tablet_v2(tablet_pad->tablet->tablet_v2, surface)) {
|
||||
!wlr_surface_accepts_tablet_v2(surface, tablet_pad->tablet->tablet_v2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "sway/input/text_input_popup.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/server.h"
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
|
||||
static struct sway_text_input *relay_get_focusable_text_input(
|
||||
struct sway_input_method_relay *relay) {
|
||||
|
|
@ -41,23 +42,21 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
|
|||
if (!text_input) {
|
||||
return;
|
||||
}
|
||||
struct wlr_input_method_v2 *context = data;
|
||||
assert(context == relay->input_method);
|
||||
if (context->current.preedit.text) {
|
||||
if (relay->input_method->current.preedit.text) {
|
||||
wlr_text_input_v3_send_preedit_string(text_input->input,
|
||||
context->current.preedit.text,
|
||||
context->current.preedit.cursor_begin,
|
||||
context->current.preedit.cursor_end);
|
||||
relay->input_method->current.preedit.text,
|
||||
relay->input_method->current.preedit.cursor_begin,
|
||||
relay->input_method->current.preedit.cursor_end);
|
||||
}
|
||||
if (context->current.commit_text) {
|
||||
if (relay->input_method->current.commit_text) {
|
||||
wlr_text_input_v3_send_commit_string(text_input->input,
|
||||
context->current.commit_text);
|
||||
relay->input_method->current.commit_text);
|
||||
}
|
||||
if (context->current.delete.before_length
|
||||
|| context->current.delete.after_length) {
|
||||
if (relay->input_method->current.delete.before_length
|
||||
|| relay->input_method->current.delete.after_length) {
|
||||
wlr_text_input_v3_send_delete_surrounding_text(text_input->input,
|
||||
context->current.delete.before_length,
|
||||
context->current.delete.after_length);
|
||||
relay->input_method->current.delete.before_length,
|
||||
relay->input_method->current.delete.after_length);
|
||||
}
|
||||
wlr_text_input_v3_send_done(text_input->input);
|
||||
}
|
||||
|
|
@ -65,7 +64,7 @@ static void handle_im_commit(struct wl_listener *listener, void *data) {
|
|||
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_method_relay *relay = wl_container_of(listener, relay,
|
||||
input_method_keyboard_grab_destroy);
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = relay->input_method->keyboard_grab;
|
||||
struct wlr_seat *wlr_seat = keyboard_grab->input_method->seat;
|
||||
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
|
||||
|
||||
|
|
@ -109,8 +108,6 @@ static void text_input_set_pending_focused_surface(
|
|||
static void handle_im_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_method_relay *relay = wl_container_of(listener, relay,
|
||||
input_method_destroy);
|
||||
struct wlr_input_method_v2 *context = data;
|
||||
assert(context == relay->input_method);
|
||||
wl_list_remove(&relay->input_method_commit.link);
|
||||
wl_list_remove(&relay->input_method_grab_keyboard.link);
|
||||
wl_list_remove(&relay->input_method_destroy.link);
|
||||
|
|
@ -247,6 +244,10 @@ static void relay_send_im_state(struct sway_input_method_relay *relay,
|
|||
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
|
||||
struct sway_text_input *text_input = wl_container_of(listener, text_input,
|
||||
text_input_enable);
|
||||
if (text_input->input->focused_surface == NULL) {
|
||||
sway_log(SWAY_DEBUG, "Enabling text input, but no longer focused");
|
||||
return;
|
||||
}
|
||||
if (text_input->relay->input_method == NULL) {
|
||||
sway_log(SWAY_INFO, "Enabling text input when input method is gone");
|
||||
return;
|
||||
|
|
@ -259,6 +260,10 @@ static void handle_text_input_commit(struct wl_listener *listener,
|
|||
void *data) {
|
||||
struct sway_text_input *text_input = wl_container_of(listener, text_input,
|
||||
text_input_commit);
|
||||
if (text_input->input->focused_surface == NULL) {
|
||||
sway_log(SWAY_DEBUG, "Unfocused text input tried to commit an update");
|
||||
return;
|
||||
}
|
||||
if (!text_input->input->current_enabled) {
|
||||
sway_log(SWAY_INFO, "Inactive text input tried to commit an update");
|
||||
return;
|
||||
|
|
@ -313,8 +318,6 @@ static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
|
|||
void *data) {
|
||||
struct sway_text_input *text_input = wl_container_of(listener, text_input,
|
||||
pending_focused_surface_destroy);
|
||||
struct wlr_surface *surface = data;
|
||||
assert(text_input->pending_focused_surface == surface);
|
||||
text_input->pending_focused_surface = NULL;
|
||||
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
|
||||
wl_list_init(&text_input->pending_focused_surface_destroy.link);
|
||||
|
|
@ -385,6 +388,8 @@ static void input_popup_set_focus(struct sway_input_popup *popup,
|
|||
|
||||
struct wlr_layer_surface_v1 *layer_surface =
|
||||
wlr_layer_surface_v1_try_from_wlr_surface(surface);
|
||||
struct wlr_session_lock_surface_v1 *lock_surface =
|
||||
wlr_session_lock_surface_v1_try_from_wlr_surface(surface);
|
||||
|
||||
struct wlr_scene_tree *relative_parent;
|
||||
if (layer_surface) {
|
||||
|
|
@ -404,8 +409,30 @@ static void input_popup_set_focus(struct sway_input_popup *popup,
|
|||
// surface. Layer surfaces get destroyed as part of the output being
|
||||
// destroyed, thus also trickling down to popups.
|
||||
popup->fixed_output = layer->layer_surface->output;
|
||||
} else if (lock_surface) {
|
||||
wl_signal_add(&lock_surface->surface->events.unmap,
|
||||
&popup->focused_surface_unmap);
|
||||
|
||||
struct sway_layer_surface *lock = lock_surface->data;
|
||||
if (lock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
relative_parent = lock->scene->tree;
|
||||
popup->desc.view = NULL;
|
||||
|
||||
// we don't need to add an event here to NULL out this field because
|
||||
// this field will only be initialized if the popup is part of a layer
|
||||
// surface. Layer surfaces get destroyed as part of the output being
|
||||
// destroyed, thus also trickling down to popups.
|
||||
popup->fixed_output = lock->layer_surface->output;
|
||||
} else {
|
||||
struct sway_view *view = view_from_wlr_surface(surface);
|
||||
// In the future there may be other shells been added, so we also need to check here.
|
||||
if (view == NULL) {
|
||||
sway_log(SWAY_DEBUG, "Unsupported IME focus surface");
|
||||
return;
|
||||
}
|
||||
wl_signal_add(&view->events.unmap, &popup->focused_surface_unmap);
|
||||
relative_parent = view->scene_tree;
|
||||
popup->desc.view = view;
|
||||
|
|
@ -572,6 +599,34 @@ static void relay_handle_input_method(struct wl_listener *listener,
|
|||
}
|
||||
}
|
||||
|
||||
static void sway_input_method_relay_finish_text_input(struct sway_input_method_relay *relay) {
|
||||
wl_list_remove(&relay->text_input_new.link);
|
||||
wl_list_remove(&relay->text_input_manager_destroy.link);
|
||||
wl_list_init(&relay->text_input_new.link);
|
||||
wl_list_init(&relay->text_input_manager_destroy.link);
|
||||
}
|
||||
|
||||
static void relay_handle_text_input_manager_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_method_relay *relay = wl_container_of(listener, relay,
|
||||
text_input_manager_destroy);
|
||||
|
||||
sway_input_method_relay_finish_text_input(relay);
|
||||
}
|
||||
|
||||
static void sway_input_method_relay_finish_input_method(struct sway_input_method_relay *relay) {
|
||||
wl_list_remove(&relay->input_method_new.link);
|
||||
wl_list_remove(&relay->input_method_manager_destroy.link);
|
||||
wl_list_init(&relay->input_method_new.link);
|
||||
wl_list_init(&relay->input_method_manager_destroy.link);
|
||||
}
|
||||
|
||||
static void relay_handle_input_method_manager_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_method_relay *relay = wl_container_of(listener, relay,
|
||||
input_method_manager_destroy);
|
||||
|
||||
sway_input_method_relay_finish_input_method(relay);
|
||||
}
|
||||
|
||||
void sway_input_method_relay_init(struct sway_seat *seat,
|
||||
struct sway_input_method_relay *relay) {
|
||||
relay->seat = seat;
|
||||
|
|
@ -579,18 +634,24 @@ void sway_input_method_relay_init(struct sway_seat *seat,
|
|||
wl_list_init(&relay->input_popups);
|
||||
|
||||
relay->text_input_new.notify = relay_handle_text_input;
|
||||
wl_signal_add(&server.text_input->events.text_input,
|
||||
wl_signal_add(&server.text_input->events.new_text_input,
|
||||
&relay->text_input_new);
|
||||
relay->text_input_manager_destroy.notify = relay_handle_text_input_manager_destroy;
|
||||
wl_signal_add(&server.text_input->events.destroy,
|
||||
&relay->text_input_manager_destroy);
|
||||
|
||||
relay->input_method_new.notify = relay_handle_input_method;
|
||||
wl_signal_add(
|
||||
&server.input_method->events.input_method,
|
||||
&server.input_method->events.new_input_method,
|
||||
&relay->input_method_new);
|
||||
relay->input_method_manager_destroy.notify = relay_handle_input_method_manager_destroy;
|
||||
wl_signal_add(&server.input_method->events.destroy,
|
||||
&relay->input_method_manager_destroy);
|
||||
}
|
||||
|
||||
void sway_input_method_relay_finish(struct sway_input_method_relay *relay) {
|
||||
wl_list_remove(&relay->input_method_new.link);
|
||||
wl_list_remove(&relay->text_input_new.link);
|
||||
sway_input_method_relay_finish_text_input(relay);
|
||||
sway_input_method_relay_finish_input_method(relay);
|
||||
}
|
||||
|
||||
void sway_input_method_relay_set_focus(struct sway_input_method_relay *relay,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <wlr/config.h>
|
||||
#include <wlr/types/wlr_content_type_v1.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
|
@ -317,6 +318,14 @@ static void ipc_json_describe_wlr_output(struct wlr_output *wlr_output, json_obj
|
|||
json_object_array_add(modes_array, mode_object);
|
||||
}
|
||||
json_object_object_add(object, "modes", modes_array);
|
||||
|
||||
json_object *features_object = json_object_new_object();
|
||||
json_object_object_add(features_object, "adaptive_sync",
|
||||
json_object_new_boolean(wlr_output->adaptive_sync_supported ||
|
||||
wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED));
|
||||
json_object_object_add(features_object, "hdr",
|
||||
json_object_new_boolean(output_supports_hdr(wlr_output, NULL)));
|
||||
json_object_object_add(object, "features", features_object);
|
||||
}
|
||||
|
||||
static void ipc_json_describe_output(struct sway_output *output,
|
||||
|
|
@ -399,8 +408,8 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
|
|||
}
|
||||
|
||||
json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time));
|
||||
|
||||
json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing));
|
||||
json_object_object_add(object, "hdr", json_object_new_boolean(output->hdr));
|
||||
}
|
||||
|
||||
json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
|
||||
|
|
@ -577,6 +586,10 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
|||
json_object_object_add(object, "app_id",
|
||||
app_id ? json_object_new_string(app_id) : NULL);
|
||||
|
||||
json_object_object_add(object, "foreign_toplevel_identifier",
|
||||
c->view->ext_foreign_toplevel ?
|
||||
json_object_new_string(c->view->ext_foreign_toplevel->identifier) : NULL);
|
||||
|
||||
bool visible = view_is_visible(c->view);
|
||||
json_object_object_add(object, "visible", json_object_new_boolean(visible));
|
||||
|
||||
|
|
@ -602,6 +615,21 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
|||
json_object_object_add(object, "inhibit_idle",
|
||||
json_object_new_boolean(view_inhibit_idle(c->view)));
|
||||
|
||||
const char *sandbox_engine = view_get_sandbox_engine(c->view);
|
||||
json_object_object_add(object, "sandbox_engine",
|
||||
sandbox_engine ? json_object_new_string(sandbox_engine) : NULL);
|
||||
|
||||
const char *sandbox_app_id = view_get_sandbox_app_id(c->view);
|
||||
json_object_object_add(object, "sandbox_app_id",
|
||||
sandbox_app_id ? json_object_new_string(sandbox_app_id) : NULL);
|
||||
|
||||
const char *sandbox_instance_id = view_get_sandbox_instance_id(c->view);
|
||||
json_object_object_add(object, "sandbox_instance_id",
|
||||
sandbox_instance_id ? json_object_new_string(sandbox_instance_id) : NULL);
|
||||
|
||||
const char *tag = view_get_tag(c->view);
|
||||
json_object_object_add(object, "tag", tag ? json_object_new_string(tag) : NULL);
|
||||
|
||||
json_object *idle_inhibitors = json_object_new_object();
|
||||
|
||||
struct sway_idle_inhibitor_v1 *user_inhibitor =
|
||||
|
|
@ -931,6 +959,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
|
|||
case LIBINPUT_CONFIG_DRAG_LOCK_DISABLED:
|
||||
drag_lock = "disabled";
|
||||
break;
|
||||
#if HAVE_LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY
|
||||
case LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY:
|
||||
drag_lock = "enabled_sticky";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
json_object_object_add(object, "tap_drag_lock",
|
||||
json_object_new_string(drag_lock));
|
||||
|
|
|
|||
|
|
@ -648,6 +648,12 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt
|
|||
}
|
||||
|
||||
list_t *res_list = execute_command(buf, NULL, NULL);
|
||||
if (modeset_is_pending()) {
|
||||
// IPC expects commands to have taken immediate effect, so we need
|
||||
// to force a modeset after output commands. We do a single modeset
|
||||
// here to avoid modesetting for every output command in sequence.
|
||||
force_modeset();
|
||||
}
|
||||
transaction_commit_dirty();
|
||||
char *json = cmd_results_to_json(res_list);
|
||||
int length = strlen(json);
|
||||
|
|
|
|||
|
|
@ -234,6 +234,9 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
|
|||
struct sway_output *output = root->outputs->items[i];
|
||||
arrange_layers(output);
|
||||
}
|
||||
|
||||
// Views are now visible, so check if we need to activate inhibition again.
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
|
||||
static void handle_abandon(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -297,6 +300,10 @@ static void handle_session_lock(struct wl_listener *listener, void *data) {
|
|||
|
||||
wlr_session_lock_v1_send_locked(lock);
|
||||
server.session_lock.lock = sway_lock;
|
||||
|
||||
// The lock screen covers everything, so check if any active inhibition got
|
||||
// deactivated due to lost visibility.
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
|
||||
static void handle_session_lock_destroy(struct wl_listener *listener, void *data) {
|
||||
|
|
|
|||
81
sway/main.c
81
sway/main.c
|
|
@ -1,5 +1,6 @@
|
|||
#include <getopt.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -44,10 +45,6 @@ void sway_terminate(int exit_code) {
|
|||
}
|
||||
}
|
||||
|
||||
void sig_handler(int signal) {
|
||||
sway_terminate(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void run_as_ipc_client(char *command, char *socket_path) {
|
||||
int socketfd = ipc_open_socket(socket_path);
|
||||
uint32_t len = strlen(command);
|
||||
|
|
@ -111,18 +108,14 @@ static void log_kernel(void) {
|
|||
pclose(f);
|
||||
}
|
||||
|
||||
static bool detect_suid(void) {
|
||||
if (geteuid() != 0 && getegid() != 0) {
|
||||
return false;
|
||||
static void restore_nofile_limit(void) {
|
||||
if (original_nofile_rlimit.rlim_cur == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (getuid() == geteuid() && getgid() == getegid()) {
|
||||
return false;
|
||||
if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
||||
sway_log_errno(SWAY_ERROR, "Failed to restore max open files limit: "
|
||||
"setrlimit(NOFILE) failed");
|
||||
}
|
||||
|
||||
sway_log(SWAY_ERROR, "SUID operation is no longer supported, refusing to start. "
|
||||
"This check will be removed in a future release.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void increase_nofile_limit(void) {
|
||||
|
|
@ -139,17 +132,38 @@ static void increase_nofile_limit(void) {
|
|||
"setrlimit(NOFILE) failed");
|
||||
sway_log(SWAY_INFO, "Running with %d max open files",
|
||||
(int)original_nofile_rlimit.rlim_cur);
|
||||
}
|
||||
}
|
||||
|
||||
void restore_nofile_limit(void) {
|
||||
if (original_nofile_rlimit.rlim_cur == 0) {
|
||||
return;
|
||||
}
|
||||
if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
||||
sway_log_errno(SWAY_ERROR, "Failed to restore max open files limit: "
|
||||
"setrlimit(NOFILE) failed");
|
||||
}
|
||||
|
||||
pthread_atfork(NULL, NULL, restore_nofile_limit);
|
||||
}
|
||||
|
||||
static int term_signal(int signal, void *data) {
|
||||
sway_terminate(EXIT_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void restore_signals(void) {
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
struct sigaction sa_dfl = { .sa_handler = SIG_DFL };
|
||||
sigaction(SIGCHLD, &sa_dfl, NULL);
|
||||
sigaction(SIGPIPE, &sa_dfl, NULL);
|
||||
}
|
||||
|
||||
static void init_signals(void) {
|
||||
wl_event_loop_add_signal(server.wl_event_loop, SIGTERM, term_signal, NULL);
|
||||
wl_event_loop_add_signal(server.wl_event_loop, SIGINT, term_signal, NULL);
|
||||
|
||||
struct sigaction sa_ign = { .sa_handler = SIG_IGN };
|
||||
// avoid need to reap children
|
||||
sigaction(SIGCHLD, &sa_ign, NULL);
|
||||
// prevent ipc write errors from crashing sway
|
||||
sigaction(SIGPIPE, &sa_ign, NULL);
|
||||
|
||||
pthread_atfork(NULL, NULL, restore_signals);
|
||||
}
|
||||
|
||||
void enable_debug_flag(const char *flag) {
|
||||
|
|
@ -159,10 +173,8 @@ void enable_debug_flag(const char *flag) {
|
|||
debug.txn_wait = true;
|
||||
} else if (strcmp(flag, "txn-timings") == 0) {
|
||||
debug.txn_timings = true;
|
||||
} else if (strncmp(flag, "txn-timeout=", 12) == 0) {
|
||||
server.txn_timeout_ms = atoi(&flag[12]);
|
||||
} else if (strcmp(flag, "legacy-wl-drm") == 0) {
|
||||
debug.legacy_wl_drm = true;
|
||||
} else if (has_prefix(flag, "txn-timeout=")) {
|
||||
server.txn_timeout_ms = atoi(&flag[strlen("txn-timeout=")]);
|
||||
} else {
|
||||
sway_log(SWAY_ERROR, "Unknown debug flag: %s", flag);
|
||||
}
|
||||
|
|
@ -266,11 +278,6 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
// SUID operation is deprecated, so block it for now.
|
||||
if (detect_suid()) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Since wayland requires XDG_RUNTIME_DIR to be set, abort with just the
|
||||
// clear error message (when not running as an IPC client).
|
||||
if (!getenv("XDG_RUNTIME_DIR") && optind == argc) {
|
||||
|
|
@ -322,19 +329,14 @@ int main(int argc, char **argv) {
|
|||
|
||||
increase_nofile_limit();
|
||||
|
||||
// handle SIGTERM signals
|
||||
signal(SIGTERM, sig_handler);
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
// prevent ipc from crashing sway
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
sway_log(SWAY_INFO, "Starting sway version " SWAY_VERSION);
|
||||
|
||||
if (!server_init(&server)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
init_signals();
|
||||
|
||||
if (server.linux_dmabuf_v1) {
|
||||
wlr_scene_set_linux_dmabuf_v1(root->root_scene, server.linux_dmabuf_v1);
|
||||
}
|
||||
|
|
@ -361,6 +363,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
config->active = true;
|
||||
force_modeset();
|
||||
load_swaybars();
|
||||
run_deferred_commands();
|
||||
run_deferred_bindings();
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ sway_sources = files(
|
|||
'commands/output/disable.c',
|
||||
'commands/output/dpms.c',
|
||||
'commands/output/enable.c',
|
||||
'commands/output/hdr.c',
|
||||
'commands/output/max_render_time.c',
|
||||
'commands/output/mode.c',
|
||||
'commands/output/position.c',
|
||||
|
|
|
|||
144
sway/server.c
144
sway/server.c
|
|
@ -10,20 +10,25 @@
|
|||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||
#include <wlr/types/wlr_color_management_v1.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_content_type_v1.h>
|
||||
#include <wlr/types/wlr_cursor_shape_v1.h>
|
||||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_ext_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_drm.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
|
||||
#include <wlr/types/wlr_fixes.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_ext_image_capture_source_v1.h>
|
||||
#include <wlr/types/wlr_ext_image_copy_capture_v1.h>
|
||||
#include <wlr/types/wlr_fractional_scale_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
|
|
@ -45,6 +50,7 @@
|
|||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_toplevel_tag_v1.h>
|
||||
#include <xf86drm.h>
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
|
|
@ -69,6 +75,7 @@
|
|||
#define SWAY_XDG_SHELL_VERSION 5
|
||||
#define SWAY_LAYER_SHELL_VERSION 4
|
||||
#define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
||||
#define SWAY_PRESENTATION_VERSION 2
|
||||
|
||||
bool allow_unsupported_gpu = false;
|
||||
|
||||
|
|
@ -104,8 +111,10 @@ static bool is_privileged(const struct wl_global *global) {
|
|||
global == server.input_method->global ||
|
||||
global == server.foreign_toplevel_list->global ||
|
||||
global == server.foreign_toplevel_manager->global ||
|
||||
global == server.data_control_manager_v1->global ||
|
||||
global == server.wlr_data_control_manager_v1->global ||
|
||||
global == server.ext_data_control_manager_v1->global ||
|
||||
global == server.screencopy_manager_v1->global ||
|
||||
global == server.ext_image_copy_capture_manager_v1->global ||
|
||||
global == server.export_dmabuf_manager_v1->global ||
|
||||
global == server.security_context_manager_v1->global ||
|
||||
global == server.gamma_control_manager_v1->global ||
|
||||
|
|
@ -175,11 +184,11 @@ static void detect_proprietary(struct wlr_backend *backend, void *data) {
|
|||
drmFreeVersion(version);
|
||||
}
|
||||
|
||||
static void handle_renderer_lost(struct wl_listener *listener, void *data) {
|
||||
struct sway_server *server = wl_container_of(listener, server, renderer_lost);
|
||||
static void do_renderer_recreate(void *data) {
|
||||
struct sway_server *server = data;
|
||||
server->recreating_renderer = NULL;
|
||||
|
||||
sway_log(SWAY_INFO, "Re-creating renderer after GPU reset");
|
||||
|
||||
struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend);
|
||||
if (renderer == NULL) {
|
||||
sway_log(SWAY_ERROR, "Unable to create renderer");
|
||||
|
|
@ -214,13 +223,42 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) {
|
|||
wlr_renderer_destroy(old_renderer);
|
||||
}
|
||||
|
||||
static void handle_renderer_lost(struct wl_listener *listener, void *data) {
|
||||
struct sway_server *server = wl_container_of(listener, server, renderer_lost);
|
||||
|
||||
if (server->recreating_renderer != NULL) {
|
||||
sway_log(SWAY_DEBUG, "Re-creation of renderer already scheduled");
|
||||
return;
|
||||
}
|
||||
|
||||
sway_log(SWAY_INFO, "Scheduling re-creation of renderer after GPU reset");
|
||||
server->recreating_renderer = wl_event_loop_add_idle(server->wl_event_loop, do_renderer_recreate, server);
|
||||
}
|
||||
|
||||
static void handle_new_foreign_toplevel_capture_request(struct wl_listener *listener, void *data) {
|
||||
struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data;
|
||||
struct sway_view *view = request->toplevel_handle->data;
|
||||
|
||||
if (view->image_capture_source == NULL) {
|
||||
view->image_capture_source = wlr_ext_image_capture_source_v1_create_with_scene_node(
|
||||
&view->image_capture_scene->tree.node, server.wl_event_loop, server.allocator, server.renderer);
|
||||
if (view->image_capture_source == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept(request, view->image_capture_source);
|
||||
}
|
||||
|
||||
bool server_init(struct sway_server *server) {
|
||||
sway_log(SWAY_DEBUG, "Initializing Wayland server");
|
||||
server->wl_display = wl_display_create();
|
||||
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
|
||||
|
||||
wl_display_set_global_filter(server->wl_display, filter_global, NULL);
|
||||
wl_display_set_default_max_buffer_size(server->wl_display, 1024 * 1024);
|
||||
|
||||
wlr_fixes_create(server->wl_display, 1);
|
||||
root = root_create(server->wl_display);
|
||||
|
||||
server->backend = wlr_backend_autocreate(server->wl_event_loop, &server->session);
|
||||
|
|
@ -245,9 +283,12 @@ bool server_init(struct sway_server *server) {
|
|||
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) {
|
||||
server->linux_dmabuf_v1 = wlr_linux_dmabuf_v1_create_with_renderer(
|
||||
server->wl_display, 4, server->renderer);
|
||||
if (debug.legacy_wl_drm) {
|
||||
wlr_drm_create(server->wl_display, server->renderer);
|
||||
}
|
||||
}
|
||||
if (wlr_renderer_get_drm_fd(server->renderer) >= 0 &&
|
||||
server->renderer->features.timeline &&
|
||||
server->backend->features.timeline) {
|
||||
wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1,
|
||||
wlr_renderer_get_drm_fd(server->renderer));
|
||||
}
|
||||
|
||||
server->allocator = wlr_allocator_autocreate(server->backend,
|
||||
|
|
@ -267,9 +308,8 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
server->gamma_control_manager_v1 =
|
||||
wlr_gamma_control_manager_v1_create(server->wl_display);
|
||||
server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma;
|
||||
wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma,
|
||||
&server->gamma_control_set_gamma);
|
||||
wlr_scene_set_gamma_control_manager_v1(root->root_scene,
|
||||
server->gamma_control_manager_v1);
|
||||
|
||||
server->new_output.notify = handle_new_output;
|
||||
wl_signal_add(&server->backend->events.new_output, &server->new_output);
|
||||
|
|
@ -321,7 +361,7 @@ bool server_init(struct sway_server *server) {
|
|||
wl_signal_add(&server->pointer_constraints->events.new_constraint,
|
||||
&server->pointer_constraint);
|
||||
|
||||
wlr_presentation_create(server->wl_display, server->backend);
|
||||
wlr_presentation_create(server->wl_display, server->backend, SWAY_PRESENTATION_VERSION);
|
||||
wlr_alpha_modifier_v1_create(server->wl_display);
|
||||
|
||||
server->output_manager_v1 =
|
||||
|
|
@ -363,7 +403,10 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display);
|
||||
server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display);
|
||||
server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display);
|
||||
server->ext_image_copy_capture_manager_v1 = wlr_ext_image_copy_capture_manager_v1_create(server->wl_display, 1);
|
||||
wlr_ext_output_image_capture_source_manager_v1_create(server->wl_display, 1);
|
||||
server->wlr_data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display);
|
||||
server->ext_data_control_manager_v1 = wlr_ext_data_control_manager_v1_create(server->wl_display, 1);
|
||||
server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display);
|
||||
wlr_viewporter_create(server->wl_display);
|
||||
wlr_single_pixel_buffer_manager_v1_create(server->wl_display);
|
||||
|
|
@ -371,6 +414,12 @@ bool server_init(struct sway_server *server) {
|
|||
wlr_content_type_manager_v1_create(server->wl_display, 1);
|
||||
wlr_fractional_scale_manager_v1_create(server->wl_display, 1);
|
||||
|
||||
server->ext_foreign_toplevel_image_capture_source_manager_v1 =
|
||||
wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(server->wl_display, 1);
|
||||
server->new_foreign_toplevel_capture_request.notify = handle_new_foreign_toplevel_capture_request;
|
||||
wl_signal_add(&server->ext_foreign_toplevel_image_capture_source_manager_v1->events.new_request,
|
||||
&server->new_foreign_toplevel_capture_request);
|
||||
|
||||
server->tearing_control_v1 =
|
||||
wlr_tearing_control_manager_v1_create(server->wl_display, 1);
|
||||
server->tearing_control_new_object.notify = handle_new_tearing_hint;
|
||||
|
|
@ -393,11 +442,49 @@ bool server_init(struct sway_server *server) {
|
|||
wl_signal_add(&server->xdg_activation_v1->events.new_token,
|
||||
&server->xdg_activation_v1_new_token);
|
||||
|
||||
struct wlr_xdg_toplevel_tag_manager_v1 *xdg_toplevel_tag_manager_v1 =
|
||||
wlr_xdg_toplevel_tag_manager_v1_create(server->wl_display, 1);
|
||||
server->xdg_toplevel_tag_manager_v1_set_tag.notify =
|
||||
xdg_toplevel_tag_manager_v1_handle_set_tag;
|
||||
wl_signal_add(&xdg_toplevel_tag_manager_v1->events.set_tag,
|
||||
&server->xdg_toplevel_tag_manager_v1_set_tag);
|
||||
|
||||
struct wlr_cursor_shape_manager_v1 *cursor_shape_manager =
|
||||
wlr_cursor_shape_manager_v1_create(server->wl_display, 1);
|
||||
server->request_set_cursor_shape.notify = handle_request_set_cursor_shape;
|
||||
wl_signal_add(&cursor_shape_manager->events.request_set_shape, &server->request_set_cursor_shape);
|
||||
|
||||
if (server->renderer->features.input_color_transform) {
|
||||
const enum wp_color_manager_v1_render_intent render_intents[] = {
|
||||
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL,
|
||||
};
|
||||
const enum wp_color_manager_v1_transfer_function transfer_functions[] = {
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB,
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ,
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR,
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22,
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886,
|
||||
};
|
||||
const enum wp_color_manager_v1_primaries primaries[] = {
|
||||
WP_COLOR_MANAGER_V1_PRIMARIES_SRGB,
|
||||
WP_COLOR_MANAGER_V1_PRIMARIES_BT2020,
|
||||
};
|
||||
struct wlr_color_manager_v1 *cm = wlr_color_manager_v1_create(
|
||||
server->wl_display, 1, &(struct wlr_color_manager_v1_options){
|
||||
.features = {
|
||||
.parametric = true,
|
||||
.set_mastering_display_primaries = true,
|
||||
},
|
||||
.render_intents = render_intents,
|
||||
.render_intents_len = sizeof(render_intents) / sizeof(render_intents[0]),
|
||||
.transfer_functions = transfer_functions,
|
||||
.transfer_functions_len = sizeof(transfer_functions) / sizeof(transfer_functions[0]),
|
||||
.primaries = primaries,
|
||||
.primaries_len = sizeof(primaries) / sizeof(primaries[0]),
|
||||
});
|
||||
wlr_scene_set_color_manager_v1(root->root_scene, cm);
|
||||
}
|
||||
|
||||
wl_list_init(&server->pending_launcher_ctxs);
|
||||
|
||||
// Avoid using "wayland-0" as display socket
|
||||
|
|
@ -444,14 +531,43 @@ bool server_init(struct sway_server *server) {
|
|||
}
|
||||
|
||||
void server_fini(struct sway_server *server) {
|
||||
// remove listeners
|
||||
wl_list_remove(&server->renderer_lost.link);
|
||||
wl_list_remove(&server->new_output.link);
|
||||
wl_list_remove(&server->layer_shell_surface.link);
|
||||
wl_list_remove(&server->xdg_shell_toplevel.link);
|
||||
wl_list_remove(&server->server_decoration.link);
|
||||
wl_list_remove(&server->xdg_decoration.link);
|
||||
wl_list_remove(&server->pointer_constraint.link);
|
||||
wl_list_remove(&server->output_manager_apply.link);
|
||||
wl_list_remove(&server->output_manager_test.link);
|
||||
wl_list_remove(&server->output_power_manager_set_mode.link);
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
if (server->drm_lease_manager) {
|
||||
wl_list_remove(&server->drm_lease_request.link);
|
||||
}
|
||||
#endif
|
||||
wl_list_remove(&server->tearing_control_new_object.link);
|
||||
wl_list_remove(&server->xdg_activation_v1_request_activate.link);
|
||||
wl_list_remove(&server->xdg_activation_v1_new_token.link);
|
||||
wl_list_remove(&server->xdg_toplevel_tag_manager_v1_set_tag.link);
|
||||
wl_list_remove(&server->request_set_cursor_shape.link);
|
||||
wl_list_remove(&server->new_foreign_toplevel_capture_request.link);
|
||||
input_manager_finish(server->input);
|
||||
|
||||
// TODO: free sway-specific resources
|
||||
#if WLR_HAS_XWAYLAND
|
||||
wlr_xwayland_destroy(server->xwayland.wlr_xwayland);
|
||||
if (server->xwayland.wlr_xwayland != NULL) {
|
||||
wl_list_remove(&server->xwayland_surface.link);
|
||||
wl_list_remove(&server->xwayland_ready.link);
|
||||
wlr_xwayland_destroy(server->xwayland.wlr_xwayland);
|
||||
}
|
||||
#endif
|
||||
wl_display_destroy_clients(server->wl_display);
|
||||
wlr_backend_destroy(server->backend);
|
||||
wl_display_destroy(server->wl_display);
|
||||
list_free(server->dirty_nodes);
|
||||
free(server->socket);
|
||||
}
|
||||
|
||||
bool server_start(struct sway_server *server) {
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ runtime.
|
|||
|
||||
This setting also applies to the current binding mode indicator.
|
||||
|
||||
The following commands may only be used at runtime.
|
||||
|
||||
*mode* toggle [<bar_id>]
|
||||
Toggles the current mode between _hide_ and _dock_. Any other mode
|
||||
is treated as _hide_.
|
||||
|
||||
## TRAY
|
||||
|
||||
Swaybar provides a system tray where third-party applications may place icons.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue