mirror of
https://github.com/swaywm/sway.git
synced 2025-10-29 05:40:18 -04:00
Compare commits
75 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 |
81 changed files with 903 additions and 476 deletions
|
|
@ -29,12 +29,12 @@ sources:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ sources:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
28
README.cs.md
28
README.cs.md
|
|
@ -1,23 +1,24 @@
|
|||
# sway
|
||||
|
||||
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:
|
||||
|
||||
|
|
@ -29,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
|
||||
|
||||
|
|
@ -51,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
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ _\*Fordításidejű függőség_
|
|||
|
||||
Futtasd ezeket a parancsokat:
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -35,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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ struct criteria {
|
|||
struct pattern *sandbox_engine;
|
||||
struct pattern *sandbox_app_id;
|
||||
struct pattern *sandbox_instance_id;
|
||||
struct pattern *tag;
|
||||
};
|
||||
|
||||
bool criteria_is_empty(struct criteria *criteria);
|
||||
|
|
|
|||
|
|
@ -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,6 +52,7 @@ struct sway_output {
|
|||
|
||||
bool enabled;
|
||||
list_t *workspaces;
|
||||
struct wl_list layer_surfaces; // sway_layer_surface.link
|
||||
|
||||
struct sway_output_state current;
|
||||
|
||||
|
|
@ -61,17 +62,15 @@ struct sway_output {
|
|||
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 allow_tearing;
|
||||
bool hdr;
|
||||
};
|
||||
|
||||
struct sway_output_non_desktop {
|
||||
|
|
@ -132,6 +131,8 @@ 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -112,12 +112,17 @@ struct sway_server {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -103,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;
|
||||
|
||||
|
|
@ -227,6 +238,8 @@ 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,
|
||||
|
|
@ -351,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
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
project(
|
||||
'sway',
|
||||
'c',
|
||||
version: '1.11-rc2',
|
||||
version: '1.12-dev',
|
||||
license: 'MIT',
|
||||
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.19.0', '<0.20.0']
|
||||
wlroots_version = ['>=0.20.0', '<0.21.0']
|
||||
subproject(
|
||||
'wlroots',
|
||||
default_options: ['examples=false'],
|
||||
required: false,
|
||||
version: wlroots_version,
|
||||
)
|
||||
wlroots = dependency('wlroots-0.19', 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')
|
||||
|
|
|
|||
|
|
@ -9,14 +9,7 @@ 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 / 'staging/content-type/content-type-v1.xml',
|
||||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
wl_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
|
||||
wl_protocol_dir / 'staging/ext-image-capture-source/ext-image-capture-source-v1.xml',
|
||||
wl_protocol_dir / 'staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml',
|
||||
wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'idle.xml',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,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;
|
||||
|
|
@ -79,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;
|
||||
}
|
||||
|
||||
|
|
@ -93,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;
|
||||
|
|
@ -129,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;
|
||||
|
|
@ -144,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
|
||||
|
|
@ -157,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) {
|
||||
|
|
@ -219,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) {
|
||||
|
|
@ -261,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.
|
||||
|
|
@ -331,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) {
|
||||
|
|
@ -405,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;
|
||||
}
|
||||
|
|
@ -475,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;
|
||||
}
|
||||
|
|
@ -527,7 +598,7 @@ 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 {
|
||||
|
|
@ -551,6 +622,7 @@ 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;
|
||||
}
|
||||
|
|
@ -775,10 +847,7 @@ 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, server.allocator->buffer_caps);
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
|
|
@ -933,9 +1002,10 @@ 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
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ bool criteria_is_empty(struct criteria *criteria) {
|
|||
&& !criteria->pid
|
||||
&& !criteria->sandbox_engine
|
||||
&& !criteria->sandbox_app_id
|
||||
&& !criteria->sandbox_instance_id;
|
||||
&& !criteria->sandbox_instance_id
|
||||
&& !criteria->tag;
|
||||
}
|
||||
|
||||
// The error pointer is used for parsing functions, and saves having to pass it
|
||||
|
|
@ -104,6 +105,7 @@ void criteria_destroy(struct criteria *criteria) {
|
|||
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);
|
||||
|
|
@ -314,6 +316,26 @@ static bool criteria_matches_view(struct criteria *criteria,
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -544,6 +566,7 @@ enum criteria_token {
|
|||
T_SANDBOX_ENGINE,
|
||||
T_SANDBOX_APP_ID,
|
||||
T_SANDBOX_INSTANCE_ID,
|
||||
T_TAG,
|
||||
|
||||
T_INVALID,
|
||||
};
|
||||
|
|
@ -589,6 +612,8 @@ static enum criteria_token token_from_name(char *name) {
|
|||
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;
|
||||
}
|
||||
|
|
@ -700,6 +725,9 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_layer_surface_v1_destroy(layer->layer_surface);
|
||||
}
|
||||
|
||||
static void handle_node_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_surface *layer =
|
||||
wl_container_of(listener, layer, node_destroy);
|
||||
|
|
@ -257,10 +249,10 @@ static void handle_node_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&layer->surface_commit.link);
|
||||
wl_list_remove(&layer->node_destroy.link);
|
||||
wl_list_remove(&layer->new_popup.link);
|
||||
wl_list_remove(&layer->output_destroy.link);
|
||||
|
||||
layer->layer_surface->data = NULL;
|
||||
|
||||
wl_list_remove(&layer->link);
|
||||
free(layer);
|
||||
}
|
||||
|
||||
|
|
@ -269,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);
|
||||
|
|
@ -479,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,
|
||||
|
|
@ -496,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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,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;
|
||||
}
|
||||
|
||||
|
|
@ -114,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) {
|
||||
|
|
@ -127,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;
|
||||
|
|
@ -151,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,
|
||||
|
|
@ -173,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -422,13 +429,6 @@ void force_modeset(void) {
|
|||
}
|
||||
|
||||
static void begin_destroy(struct sway_output *output) {
|
||||
if (output->enabled) {
|
||||
output_disable(output);
|
||||
}
|
||||
|
||||
output_begin_destroy(output);
|
||||
|
||||
wl_list_remove(&output->link);
|
||||
|
||||
wl_list_remove(&output->layout_destroy.link);
|
||||
wl_list_remove(&output->destroy.link);
|
||||
|
|
@ -436,8 +436,17 @@ static void begin_destroy(struct sway_output *output) {
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ 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);
|
||||
|
||||
|
|
@ -338,10 +339,11 @@ 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);
|
||||
|
||||
int net_height = height - title_bar_height;
|
||||
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 {
|
||||
|
|
@ -532,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);
|
||||
|
|
@ -584,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 {
|
||||
|
|
@ -605,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);
|
||||
|
|
@ -662,6 +667,13 @@ static void arrange_root(struct sway_root *root) {
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -359,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;
|
||||
}
|
||||
|
|
@ -570,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -497,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;
|
||||
|
|
@ -537,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);
|
||||
|
|
@ -584,6 +578,7 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
|
|||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -980,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;
|
||||
|
|
|
|||
|
|
@ -272,10 +272,6 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
|
|||
}
|
||||
if (ic->drag_lock != INT_MIN) {
|
||||
changed |= set_tap_drag_lock(device, ic->drag_lock);
|
||||
} else {
|
||||
#if HAVE_LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY
|
||||
changed |= set_tap_drag_lock(device, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY);
|
||||
#endif
|
||||
}
|
||||
if (ic->pointer_accel != FLT_MIN) {
|
||||
changed |= set_accel_speed(device, ic->pointer_accel);
|
||||
|
|
@ -358,12 +354,8 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
|
|||
libinput_device_config_tap_get_default_button_map(device));
|
||||
changed |= set_tap_drag(device,
|
||||
libinput_device_config_tap_get_default_drag_enabled(device));
|
||||
#if HAVE_LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY
|
||||
changed |= set_tap_drag_lock(device, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY);
|
||||
#else
|
||||
changed |= set_tap_drag_lock(device,
|
||||
libinput_device_config_tap_get_default_drag_lock_enabled(device));
|
||||
#endif
|
||||
changed |= set_accel_speed(device,
|
||||
libinput_device_config_accel_get_default_speed(device));
|
||||
changed |= set_rotation_angle(device,
|
||||
|
|
@ -399,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;
|
||||
|
|
@ -412,14 +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;
|
||||
}
|
||||
|
||||
if (has_prefix(id_path, "platform-")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return has_prefix(id_path, "pci-") && strstr(id_path, "-platform-");
|
||||
bool is_builtin = sway_udev_device_is_builtin(udev_device);
|
||||
udev_device_unref(udev_device);
|
||||
return is_builtin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -793,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);
|
||||
}
|
||||
|
|
@ -1110,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);
|
||||
}
|
||||
|
|
@ -1148,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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,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);
|
||||
}
|
||||
|
|
@ -66,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);
|
||||
|
||||
|
|
@ -110,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);
|
||||
|
|
@ -248,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;
|
||||
|
|
@ -260,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;
|
||||
|
|
@ -314,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);
|
||||
|
|
@ -632,7 +634,7 @@ 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,
|
||||
|
|
@ -640,7 +642,7 @@ void sway_input_method_relay_init(struct sway_seat *seat,
|
|||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -318,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,
|
||||
|
|
@ -400,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) {
|
||||
|
|
@ -619,6 +627,9 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
|||
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 =
|
||||
|
|
|
|||
19
sway/main.c
19
sway/main.c
|
|
@ -108,20 +108,6 @@ static void log_kernel(void) {
|
|||
pclose(f);
|
||||
}
|
||||
|
||||
static bool detect_suid(void) {
|
||||
if (geteuid() != 0 && getegid() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getuid() == geteuid() && getgid() == getegid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 restore_nofile_limit(void) {
|
||||
if (original_nofile_rlimit.rlim_cur == 0) {
|
||||
return;
|
||||
|
|
@ -292,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) {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#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>
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
#include <wlr/types/wlr_data_device.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>
|
||||
|
|
@ -48,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"
|
||||
|
|
@ -232,6 +235,21 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) {
|
|||
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();
|
||||
|
|
@ -240,6 +258,7 @@ bool server_init(struct sway_server *server) {
|
|||
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);
|
||||
|
|
@ -395,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;
|
||||
|
|
@ -417,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
|
||||
|
|
@ -487,7 +550,9 @@ void server_fini(struct sway_server *server) {
|
|||
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
|
||||
|
|
@ -502,6 +567,7 @@ void server_fini(struct sway_server *server) {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -244,6 +244,9 @@ following properties:
|
|||
|- rect
|
||||
: object
|
||||
: The bounds for the output consisting of _x_, _y_, _width_, and _height_
|
||||
|- hdr
|
||||
: boolean
|
||||
: Whether HDR is enabled
|
||||
|
||||
|
||||
*Example Reply:*
|
||||
|
|
@ -416,6 +419,10 @@ node and will have the following properties:
|
|||
: string
|
||||
: (Only windows) The instance ID provided by the associated sandbox engine (or
|
||||
_null_)
|
||||
|- tag
|
||||
: string
|
||||
: (Only windows) For an xdg-shell window, tag of the toplevel, if set.
|
||||
Otherwise, _null_
|
||||
|- window
|
||||
: integer
|
||||
: (Only xwayland windows) The X11 window ID for the xwayland window
|
||||
|
|
|
|||
|
|
@ -196,9 +196,9 @@ must be separated by one space. For example:
|
|||
screen tearing is allowed.
|
||||
|
||||
With immediate page flips, frames from the client are presented as soon
|
||||
as possible instead of synchronizing with the monitor's vblank interval
|
||||
(VSync).
|
||||
|
||||
as possible instead of synchronizing with the monitor's vblank interval
|
||||
(VSync).
|
||||
|
||||
It is recommended to set *max_render_time* to *off*. In that case a page flip
|
||||
happens as soon as a client updates. Otherwise, tearing will only happen if
|
||||
rendering takes longer than the configured milliseconds before the next
|
||||
|
|
@ -210,6 +210,17 @@ must be separated by one space. For example:
|
|||
|
||||
This setting only has effect when a window is fullscreen on the output.
|
||||
|
||||
*output* <name> hdr on|off|toggle
|
||||
Enables or disables HDR (High Dynamic Range). HDR enables a larger color
|
||||
gamut and brightness range. HDR uses the BT2020 primaries and the PQ
|
||||
transfer function.
|
||||
|
||||
When HDR is enabled, _render_bit_depth_ is implicitly set to 10 unless
|
||||
explicitly configured. Using a lower render bit depth may result in color
|
||||
banding artifacts.
|
||||
|
||||
HDR needs to be supported by the output and renderer to be enabled.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*sway*(5) *sway-input*(5)
|
||||
|
|
|
|||
|
|
@ -228,8 +228,8 @@ set|plus|minus|toggle <amount>
|
|||
regardless of the tearing hints.
|
||||
|
||||
This setting only has an effect if tearing is allowed on the output through
|
||||
the per-output *allow_tearing* setting. See *sway-output*(5)
|
||||
for further details.
|
||||
the per-output *allow_tearing* setting. See *sway-output*(5) for further
|
||||
details.
|
||||
|
||||
*move* left|right|up|down [<px> px]
|
||||
Moves the focused container in the direction specified. The optional _px_
|
||||
|
|
@ -302,28 +302,34 @@ set|plus|minus|toggle <amount>
|
|||
*rename* workspace [<old_name>] to <new_name>
|
||||
Rename either <old_name> or the focused workspace to the <new_name>
|
||||
|
||||
*resize* shrink|grow width|height [<amount> [px|ppt]]
|
||||
*resize* shrink|grow up|right|down|left|width|height [<amount> [px|ppt]]
|
||||
Resizes the currently focused container by _amount_, specified in pixels or
|
||||
percentage points. If the units are omitted, floating containers are resized
|
||||
in px and tiled containers by ppt. _amount_ will default to 10 if omitted.
|
||||
For tiling containers, space is taken/given from the container in the
|
||||
specified direction. If _width_ or _height_ is specified, space will be
|
||||
taken/given from all other containers.
|
||||
|
||||
*resize* set height <height> [px|ppt]
|
||||
Sets the height of the container to _height_, specified in pixels or
|
||||
percentage points. If the units are omitted, floating containers are
|
||||
resized in px and tiled containers by ppt. If _height_ is 0, the container
|
||||
will not be resized.
|
||||
will not be resized. For tiling containers, space is taken/given from all
|
||||
other containers.
|
||||
|
||||
*resize* set [width] <width> [px|ppt]
|
||||
Sets the width of the container to _width_, specified in pixels or
|
||||
percentage points. If the units are omitted, floating containers are
|
||||
resized in px and tiled containers by ppt. If _width_ is 0, the container
|
||||
will not be resized.
|
||||
will not be resized. For tiling containers, space is taken/given from all
|
||||
other containers.
|
||||
|
||||
*resize* set [width] <width> [px|ppt] [height] <height> [px|ppt]
|
||||
Sets the width and height of the container to _width_ and _height_,
|
||||
specified in pixels or percentage points. If the units are omitted,
|
||||
floating containers are resized in px and tiled containers by ppt. If
|
||||
_width_ or _height_ is 0, the container will not be resized on that axis.
|
||||
For tiling containers, space is taken/given from all other containers.
|
||||
|
||||
*scratchpad* show
|
||||
Shows a window from the scratchpad. Repeatedly using this command will
|
||||
|
|
@ -1055,6 +1061,9 @@ The following attributes may be matched with:
|
|||
Can be a regular expression. If value is \_\_focused\_\_, then the shell
|
||||
must be the same as that of the currently focused window.
|
||||
|
||||
*tag*
|
||||
Compare value against the tag. _tag_ is specific to Wayland applications.
|
||||
|
||||
*tiling*
|
||||
Matches tiling windows.
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include "linux-dmabuf-unstable-v1-protocol.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
|
@ -547,8 +546,8 @@ void container_begin_destroy(struct sway_container *con) {
|
|||
|
||||
container_end_mouse_operation(con);
|
||||
|
||||
con->node.destroying = true;
|
||||
node_set_dirty(&con->node);
|
||||
con->node.destroying = true;
|
||||
|
||||
if (con->scratchpad) {
|
||||
root_scratchpad_remove_container(con);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const char *node_type_to_str(enum sway_node_type type) {
|
|||
}
|
||||
|
||||
void node_set_dirty(struct sway_node *node) {
|
||||
if (node->dirty) {
|
||||
if (node->dirty || node->destroying) {
|
||||
return;
|
||||
}
|
||||
node->dirty = true;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static void restore_workspaces(struct sway_output *output) {
|
|||
for (int j = 0; j < other->workspaces->length; j++) {
|
||||
struct sway_workspace *ws = other->workspaces->items[j];
|
||||
struct sway_output *highest =
|
||||
workspace_output_get_highest_available(ws, NULL);
|
||||
workspace_output_get_highest_available(ws);
|
||||
if (highest == output) {
|
||||
workspace_detach(ws);
|
||||
output_add_workspace(output, ws);
|
||||
|
|
@ -136,12 +136,11 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
|
|||
output->detected_subpixel = wlr_output->subpixel;
|
||||
output->scale_filter = SCALE_FILTER_NEAREST;
|
||||
|
||||
wl_signal_init(&output->events.disable);
|
||||
|
||||
wl_list_insert(&root->all_outputs, &output->link);
|
||||
|
||||
output->workspaces = create_list();
|
||||
output->current.workspaces = create_list();
|
||||
wl_list_init(&output->layer_surfaces);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
@ -205,11 +204,8 @@ static void output_evacuate(struct sway_output *output) {
|
|||
return;
|
||||
}
|
||||
struct sway_output *fallback_output = NULL;
|
||||
if (root->outputs->length > 1) {
|
||||
if (root->outputs->length > 0) {
|
||||
fallback_output = root->outputs->items[0];
|
||||
if (fallback_output == output) {
|
||||
fallback_output = root->outputs->items[1];
|
||||
}
|
||||
}
|
||||
|
||||
while (output->workspaces->length) {
|
||||
|
|
@ -218,7 +214,7 @@ static void output_evacuate(struct sway_output *output) {
|
|||
workspace_detach(workspace);
|
||||
|
||||
struct sway_output *new_output =
|
||||
workspace_output_get_highest_available(workspace, output);
|
||||
workspace_output_get_highest_available(workspace);
|
||||
if (!new_output) {
|
||||
new_output = fallback_output;
|
||||
}
|
||||
|
|
@ -287,13 +283,15 @@ void output_disable(struct sway_output *output) {
|
|||
}
|
||||
|
||||
sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name);
|
||||
wl_signal_emit_mutable(&output->events.disable, output);
|
||||
|
||||
output_evacuate(output);
|
||||
|
||||
// Remove the output now to avoid interacting with it during e.g.,
|
||||
// transactions, as the output might be physically removed with the scene
|
||||
// output destroyed.
|
||||
list_del(root->outputs, index);
|
||||
|
||||
output->enabled = false;
|
||||
|
||||
destroy_layers(output);
|
||||
output_evacuate(output);
|
||||
}
|
||||
|
||||
void output_begin_destroy(struct sway_output *output) {
|
||||
|
|
@ -303,8 +301,8 @@ void output_begin_destroy(struct sway_output *output) {
|
|||
sway_log(SWAY_DEBUG, "Destroying output '%s'", output->wlr_output->name);
|
||||
wl_signal_emit_mutable(&output->node.events.destroy, &output->node);
|
||||
|
||||
output->node.destroying = true;
|
||||
node_set_dirty(&output->node);
|
||||
output->node.destroying = true;
|
||||
}
|
||||
|
||||
struct sway_output *output_from_wlr_output(struct wlr_output *output) {
|
||||
|
|
|
|||
|
|
@ -199,6 +199,8 @@ void root_scratchpad_show(struct sway_container *con) {
|
|||
if (old_ws) {
|
||||
workspace_consider_destroy(old_ws);
|
||||
}
|
||||
|
||||
container_raise_floating(con);
|
||||
}
|
||||
|
||||
static void disable_fullscreen(struct sway_container *con, void *data) {
|
||||
|
|
@ -212,9 +214,7 @@ void root_scratchpad_hide(struct sway_container *con) {
|
|||
struct sway_node *focus = seat_get_focus_inactive(seat, &root->node);
|
||||
struct sway_workspace *ws = con->pending.workspace;
|
||||
|
||||
if (con->pending.fullscreen_mode == FULLSCREEN_GLOBAL && !con->pending.workspace) {
|
||||
// If the container was made fullscreen global while in the scratchpad,
|
||||
// it should be shown until fullscreen has been disabled
|
||||
if (!con->pending.workspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
|
|||
failed = true;
|
||||
}
|
||||
|
||||
view->image_capture_scene = wlr_scene_create();
|
||||
if (view->image_capture_scene == NULL) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
wlr_scene_node_destroy(&view->scene_tree->node);
|
||||
return false;
|
||||
|
|
@ -81,6 +86,7 @@ void view_destroy(struct sway_view *view) {
|
|||
list_free(view->executed_criteria);
|
||||
|
||||
view_assign_ctx(view, NULL);
|
||||
wlr_scene_node_destroy(&view->image_capture_scene->tree.node);
|
||||
wlr_scene_node_destroy(&view->scene_tree->node);
|
||||
if (view->impl->destroy) {
|
||||
view->impl->destroy(view);
|
||||
|
|
@ -184,6 +190,13 @@ const char *view_get_sandbox_instance_id(struct sway_view *view) {
|
|||
return security_context ? security_context->instance_id : NULL;
|
||||
}
|
||||
|
||||
const char *view_get_tag(struct sway_view *view) {
|
||||
if (view->impl->get_string_prop) {
|
||||
return view->impl->get_string_prop(view, VIEW_PROP_TAG);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *view_get_shell(struct sway_view *view) {
|
||||
switch(view->type) {
|
||||
case SWAY_VIEW_XDG_SHELL:
|
||||
|
|
@ -517,10 +530,12 @@ void view_execute_criteria(struct sway_view *view) {
|
|||
sway_log(SWAY_DEBUG, "for_window '%s' matches view %p, cmd: '%s'",
|
||||
criteria->raw, view, criteria->cmdlist);
|
||||
list_add(view->executed_criteria, criteria);
|
||||
list_t *res_list = execute_command(
|
||||
criteria->cmdlist, NULL, view->container);
|
||||
list_t *res_list = execute_command(criteria->cmdlist, NULL, view->container);
|
||||
while (res_list->length) {
|
||||
struct cmd_results *res = res_list->items[0];
|
||||
if (res->status != CMD_SUCCESS) {
|
||||
sway_log(SWAY_ERROR, "for_window '%s' failed: %s", criteria->raw, res->error);
|
||||
}
|
||||
free_cmd_results(res);
|
||||
list_del(res_list, 0);
|
||||
}
|
||||
|
|
@ -813,6 +828,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||
};
|
||||
view->ext_foreign_toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_create(server.foreign_toplevel_list, &foreign_toplevel_state);
|
||||
view->ext_foreign_toplevel->data = view;
|
||||
|
||||
view->foreign_toplevel =
|
||||
wlr_foreign_toplevel_handle_v1_create(server.foreign_toplevel_manager);
|
||||
|
|
@ -1190,6 +1206,10 @@ static void view_save_buffer_iterator(struct wlr_scene_buffer *buffer,
|
|||
wlr_scene_buffer_set_dest_size(sbuf,
|
||||
buffer->dst_width, buffer->dst_height);
|
||||
wlr_scene_buffer_set_opaque_region(sbuf, &buffer->opaque_region);
|
||||
wlr_scene_buffer_set_opacity(sbuf, buffer->opacity);
|
||||
wlr_scene_buffer_set_filter_mode(sbuf, buffer->filter_mode);
|
||||
wlr_scene_buffer_set_transfer_function(sbuf, buffer->transfer_function);
|
||||
wlr_scene_buffer_set_primaries(sbuf, buffer->primaries);
|
||||
wlr_scene_buffer_set_source_box(sbuf, &buffer->src_box);
|
||||
wlr_scene_node_set_position(&sbuf->node, sx, sy);
|
||||
wlr_scene_buffer_set_transform(sbuf, buffer->transform);
|
||||
|
|
@ -1240,7 +1260,11 @@ bool view_can_tear(struct sway_view *view) {
|
|||
static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer,
|
||||
int x, int y, void *data) {
|
||||
struct timespec *when = data;
|
||||
wl_signal_emit_mutable(&scene_buffer->events.frame_done, when);
|
||||
struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer);
|
||||
if (scene_surface == NULL) {
|
||||
return;
|
||||
}
|
||||
wlr_surface_send_frame_done(scene_surface->surface, when);
|
||||
}
|
||||
|
||||
void view_send_frame_done(struct sway_view *view) {
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ void workspace_begin_destroy(struct sway_workspace *workspace) {
|
|||
if (workspace->output) {
|
||||
workspace_detach(workspace);
|
||||
}
|
||||
workspace->node.destroying = true;
|
||||
node_set_dirty(&workspace->node);
|
||||
workspace->node.destroying = true;
|
||||
}
|
||||
|
||||
void workspace_consider_destroy(struct sway_workspace *ws) {
|
||||
|
|
@ -659,13 +659,9 @@ void workspace_output_add_priority(struct sway_workspace *workspace,
|
|||
}
|
||||
|
||||
struct sway_output *workspace_output_get_highest_available(
|
||||
struct sway_workspace *ws, struct sway_output *exclude) {
|
||||
struct sway_workspace *ws) {
|
||||
for (int i = 0; i < ws->output_priority->length; i++) {
|
||||
const char *name = ws->output_priority->items[i];
|
||||
if (exclude && output_match_name_or_id(exclude, name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct sway_output *output = output_by_name_or_id(name);
|
||||
if (output) {
|
||||
return output;
|
||||
|
|
|
|||
169
swaybar/render.c
169
swaybar/render.c
|
|
@ -13,7 +13,6 @@
|
|||
#include "swaybar/ipc.h"
|
||||
#include "swaybar/render.h"
|
||||
#include "swaybar/status_line.h"
|
||||
#include "log.h"
|
||||
#if HAVE_TRAY
|
||||
#include "swaybar/tray/tray.h"
|
||||
#endif
|
||||
|
|
@ -21,7 +20,7 @@
|
|||
|
||||
static const int WS_HORIZONTAL_PADDING = 5;
|
||||
static const double WS_VERTICAL_PADDING = 1.5;
|
||||
static const double BORDER_WIDTH = 1;
|
||||
static const int BORDER_WIDTH = 1;
|
||||
|
||||
struct render_context {
|
||||
cairo_t *cairo;
|
||||
|
|
@ -541,6 +540,63 @@ static uint32_t render_status_line(struct render_context *ctx, double *x) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct box_size render_box(struct render_context *ctx, double x,
|
||||
struct box_colors colors, const char *label, bool pango_markup) {
|
||||
struct swaybar_output *output = ctx->output;
|
||||
struct swaybar_config *config = output->bar->config;
|
||||
cairo_t *cairo = ctx->cairo;
|
||||
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
|
||||
1, pango_markup, "%s", label);
|
||||
|
||||
uint32_t width = text_width + WS_HORIZONTAL_PADDING * 2 + BORDER_WIDTH * 2;
|
||||
if (width < config->workspace_min_width) {
|
||||
width = config->workspace_min_width;
|
||||
}
|
||||
|
||||
uint32_t ideal_height = text_height + WS_VERTICAL_PADDING * 2
|
||||
+ BORDER_WIDTH * 2;
|
||||
uint32_t ideal_surface_height = ideal_height;
|
||||
if (!output->bar->config->height &&
|
||||
output->height < ideal_surface_height) {
|
||||
return (struct box_size) {
|
||||
.width = width,
|
||||
.height = ideal_surface_height,
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t height = output->height;
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_u32(cairo, colors.background);
|
||||
ctx->background_color = colors.background;
|
||||
ctx->has_transparency |= (colors.background & 0xFF) != 0xFF;
|
||||
cairo_rectangle(cairo, x, 0, width, height);
|
||||
cairo_fill(cairo);
|
||||
|
||||
cairo_set_source_u32(cairo, colors.border);
|
||||
cairo_rectangle(cairo, x, 0, width, BORDER_WIDTH);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x, 0, BORDER_WIDTH, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x + width - BORDER_WIDTH, 0, BORDER_WIDTH, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x, height - BORDER_WIDTH, width, BORDER_WIDTH);
|
||||
cairo_fill(cairo);
|
||||
|
||||
double text_y = height / 2.0 - text_height / 2.0;
|
||||
cairo_set_source_u32(cairo, colors.text);
|
||||
cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
|
||||
choose_text_aa_mode(ctx, colors.text);
|
||||
render_text(cairo, config->font_description, 1, pango_markup,
|
||||
"%s", label);
|
||||
|
||||
return (struct box_size) {
|
||||
.width = width,
|
||||
.height = output->height,
|
||||
};
|
||||
}
|
||||
|
||||
static uint32_t render_binding_mode_indicator(struct render_context *ctx,
|
||||
double x) {
|
||||
struct swaybar_output *output = ctx->output;
|
||||
|
|
@ -549,54 +605,9 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
cairo_t *cairo = ctx->cairo;
|
||||
struct swaybar_config *config = output->bar->config;
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
|
||||
1, output->bar->mode_pango_markup,
|
||||
"%s", mode);
|
||||
|
||||
int ws_vertical_padding = WS_VERTICAL_PADDING;
|
||||
int ws_horizontal_padding = WS_HORIZONTAL_PADDING;
|
||||
int border_width = BORDER_WIDTH;
|
||||
|
||||
uint32_t ideal_height = text_height + ws_vertical_padding * 2
|
||||
+ border_width * 2;
|
||||
uint32_t ideal_surface_height = ideal_height;
|
||||
if (!output->bar->config->height &&
|
||||
output->height < ideal_surface_height) {
|
||||
return ideal_surface_height;
|
||||
}
|
||||
uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2;
|
||||
if (width < config->workspace_min_width) {
|
||||
width = config->workspace_min_width;
|
||||
}
|
||||
|
||||
uint32_t height = output->height;
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_u32(cairo, config->colors.binding_mode.background);
|
||||
ctx->background_color = config->colors.binding_mode.background;
|
||||
ctx->has_transparency |= (config->colors.binding_mode.background & 0xFF) != 0xFF;
|
||||
cairo_rectangle(cairo, x, 0, width, height);
|
||||
cairo_fill(cairo);
|
||||
|
||||
cairo_set_source_u32(cairo, config->colors.binding_mode.border);
|
||||
cairo_rectangle(cairo, x, 0, width, border_width);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x, 0, border_width, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x + width - border_width, 0, border_width, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, x, height - border_width, width, border_width);
|
||||
cairo_fill(cairo);
|
||||
|
||||
double text_y = height / 2.0 - text_height / 2.0;
|
||||
cairo_set_source_u32(cairo, config->colors.binding_mode.text);
|
||||
cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
|
||||
choose_text_aa_mode(ctx, config->colors.binding_mode.text);
|
||||
render_text(cairo, config->font_description, 1, output->bar->mode_pango_markup,
|
||||
"%s", mode);
|
||||
return output->height;
|
||||
struct box_size size = render_box(ctx, x, output->bar->config->colors.binding_mode,
|
||||
mode, output->bar->mode_pango_markup);
|
||||
return size.height;
|
||||
}
|
||||
|
||||
static enum hotspot_event_handling workspace_hotspot_callback(
|
||||
|
|
@ -618,6 +629,7 @@ static uint32_t render_workspace_button(struct render_context *ctx,
|
|||
struct swaybar_workspace *ws, double *x) {
|
||||
struct swaybar_output *output = ctx->output;
|
||||
struct swaybar_config *config = output->bar->config;
|
||||
|
||||
struct box_colors box_colors;
|
||||
if (ws->urgent) {
|
||||
box_colors = config->colors.urgent_workspace;
|
||||
|
|
@ -629,66 +641,21 @@ static uint32_t render_workspace_button(struct render_context *ctx,
|
|||
box_colors = config->colors.inactive_workspace;
|
||||
}
|
||||
|
||||
uint32_t height = output->height;
|
||||
|
||||
cairo_t *cairo = ctx->cairo;
|
||||
int text_width, text_height;
|
||||
get_text_size(cairo, config->font_description, &text_width, &text_height, NULL,
|
||||
1, config->pango_markup, "%s", ws->label);
|
||||
|
||||
int ws_vertical_padding = WS_VERTICAL_PADDING;
|
||||
int ws_horizontal_padding = WS_HORIZONTAL_PADDING;
|
||||
int border_width = BORDER_WIDTH;
|
||||
|
||||
uint32_t ideal_height = ws_vertical_padding * 2 + text_height
|
||||
+ border_width * 2;
|
||||
uint32_t ideal_surface_height = ideal_height;
|
||||
if (!output->bar->config->height &&
|
||||
output->height < ideal_surface_height) {
|
||||
return ideal_surface_height;
|
||||
}
|
||||
|
||||
uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2;
|
||||
if (width < config->workspace_min_width) {
|
||||
width = config->workspace_min_width;
|
||||
}
|
||||
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_u32(cairo, box_colors.background);
|
||||
ctx->background_color = box_colors.background;
|
||||
ctx->has_transparency |= (box_colors.background & 0xFF) != 0xFF;
|
||||
cairo_rectangle(cairo, *x, 0, width, height);
|
||||
cairo_fill(cairo);
|
||||
|
||||
cairo_set_source_u32(cairo, box_colors.border);
|
||||
cairo_rectangle(cairo, *x, 0, width, border_width);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, *x, 0, border_width, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, *x + width - border_width, 0, border_width, height);
|
||||
cairo_fill(cairo);
|
||||
cairo_rectangle(cairo, *x, height - border_width, width, border_width);
|
||||
cairo_fill(cairo);
|
||||
|
||||
double text_y = height / 2.0 - text_height / 2.0;
|
||||
cairo_set_source_u32(cairo, box_colors.text);
|
||||
cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y));
|
||||
choose_text_aa_mode(ctx, box_colors.text);
|
||||
render_text(cairo, config->font_description, 1, config->pango_markup,
|
||||
"%s", ws->label);
|
||||
struct box_size size = render_box(ctx, *x, box_colors,
|
||||
ws->label, config->pango_markup);
|
||||
|
||||
struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
|
||||
hotspot->x = *x;
|
||||
hotspot->y = 0;
|
||||
hotspot->width = width;
|
||||
hotspot->height = height;
|
||||
hotspot->width = size.width;
|
||||
hotspot->height = size.height;
|
||||
hotspot->callback = workspace_hotspot_callback;
|
||||
hotspot->destroy = free;
|
||||
hotspot->data = strdup(ws->name);
|
||||
wl_list_insert(&output->hotspots, &hotspot->link);
|
||||
|
||||
*x += width;
|
||||
return output->height;
|
||||
*x += size.width;
|
||||
return size.height;
|
||||
}
|
||||
|
||||
static uint32_t render_to_cairo(struct render_context *ctx) {
|
||||
|
|
|
|||
|
|
@ -189,7 +189,8 @@ static void pretty_print_output(json_object *o) {
|
|||
json_object_object_get_ex(o, "current_workspace", &ws);
|
||||
json_object_object_get_ex(o, "non_desktop", &non_desktop);
|
||||
json_object *make, *model, *serial, *scale, *scale_filter, *subpixel,
|
||||
*transform, *max_render_time, *adaptive_sync_status, *allow_tearing;
|
||||
*transform, *max_render_time, *adaptive_sync_status, *allow_tearing,
|
||||
*hdr;
|
||||
json_object_object_get_ex(o, "make", &make);
|
||||
json_object_object_get_ex(o, "model", &model);
|
||||
json_object_object_get_ex(o, "serial", &serial);
|
||||
|
|
@ -200,6 +201,7 @@ static void pretty_print_output(json_object *o) {
|
|||
json_object_object_get_ex(o, "max_render_time", &max_render_time);
|
||||
json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status);
|
||||
json_object_object_get_ex(o, "allow_tearing", &allow_tearing);
|
||||
json_object_object_get_ex(o, "hdr", &hdr);
|
||||
json_object *x, *y;
|
||||
json_object_object_get_ex(rect, "x", &x);
|
||||
json_object_object_get_ex(rect, "y", &y);
|
||||
|
|
@ -210,6 +212,10 @@ static void pretty_print_output(json_object *o) {
|
|||
json_object_object_get_ex(current_mode, "width", &width);
|
||||
json_object_object_get_ex(current_mode, "height", &height);
|
||||
json_object_object_get_ex(current_mode, "refresh", &refresh);
|
||||
json_object *features, *features_adaptive_sync, *features_hdr;
|
||||
json_object_object_get_ex(o, "features", &features);
|
||||
json_object_object_get_ex(features, "adaptive_sync", &features_adaptive_sync);
|
||||
json_object_object_get_ex(features, "hdr", &features_hdr);
|
||||
|
||||
if (json_object_get_boolean(non_desktop)) {
|
||||
printf(
|
||||
|
|
@ -252,10 +258,18 @@ static void pretty_print_output(json_object *o) {
|
|||
printf(max_render_time_int == 0 ? "off\n" : "%d ms\n", max_render_time_int);
|
||||
|
||||
printf(" Adaptive sync: %s\n",
|
||||
json_object_get_string(adaptive_sync_status));
|
||||
json_object_get_boolean(features_adaptive_sync) ?
|
||||
json_object_get_string(adaptive_sync_status) :
|
||||
"unsupported");
|
||||
|
||||
printf(" Allow tearing: %s\n",
|
||||
json_object_get_boolean(allow_tearing) ? "yes" : "no");
|
||||
|
||||
const char *hdr_str = "unsupported";
|
||||
if (json_object_get_boolean(features_hdr)) {
|
||||
hdr_str = json_object_get_boolean(hdr) ? "on" : "off";
|
||||
}
|
||||
printf(" HDR: %s\n", hdr_str);
|
||||
} else {
|
||||
printf(
|
||||
"Output %s '%s %s %s' (disabled)\n",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue