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