├── .github └── workflows │ ├── build.yml │ └── lint.yml ├── .gitignore ├── LICENSE ├── README.md ├── biome.jsonc ├── justfile ├── package-lock.json ├── package.json ├── po ├── ar.po ├── cs.po ├── de.po ├── eo.po ├── es.po ├── et.po ├── fi.po ├── fr.po ├── hu.po ├── id.po ├── it.po ├── ja.po ├── nb_NO.po ├── nl.po ├── pl.po ├── pt.po ├── pt_BR.po ├── rounded-window-corners@fxgn.pot ├── ru.po ├── tr.po ├── uk.po └── zh_CN.po ├── resources ├── metadata.json ├── schemas │ └── org.gnome.shell.extensions.rounded-window-corners-reborn.gschema.xml ├── stylesheet-prefs.css └── stylesheet.css ├── src ├── effect │ ├── README.md │ ├── clip_shadow_effect.ts │ ├── linear_filter_effect.ts │ ├── rounded_corners_effect.ts │ └── shader │ │ ├── clip_shadow.frag │ │ └── rounded_corners.frag ├── extension.ts ├── global.d.ts ├── manager │ ├── README.md │ ├── event_handlers.ts │ ├── event_manager.ts │ └── utils.ts ├── patch │ ├── README.md │ ├── add_shadow_in_overview.ts │ └── workspace_switch.ts ├── preferences │ ├── README.md │ ├── index.ts │ ├── pages │ │ ├── blacklist.ts │ │ ├── blacklist.ui │ │ ├── custom.ts │ │ ├── custom.ui │ │ ├── edit-shadow.ui │ │ ├── edit_shadow.ts │ │ ├── general.ts │ │ ├── general.ui │ │ ├── reset.ts │ │ └── reset.ui │ └── widgets │ │ ├── app_row.ts │ │ ├── custom_settings_row.ts │ │ ├── paddings-row.ui │ │ └── paddings_row.ts ├── prefs.ts ├── utils │ ├── README.md │ ├── background_menu.ts │ ├── box_shadow.ts │ ├── constants.ts │ ├── file.ts │ ├── log.ts │ ├── settings.ts │ └── types.ts └── window_picker │ ├── README.md │ ├── client.ts │ ├── iface.xml │ └── service.ts └── tsconfig.json /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build the extension 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - README.md 7 | pull_request: 8 | paths-ignore: 9 | - README.md 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | name: Build the extension 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout the repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Set up node.js 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: latest 24 | cache: 'npm' 25 | 26 | - name: Set up just 27 | uses: extractions/setup-just@v2 28 | 29 | - name: Install gettext 30 | run: sudo apt install gettext 31 | 32 | - name: Build the extension 33 | run: just build 34 | 35 | - name: Upload artifacts 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: rounded-window-corners@fxgn.shell-extension 39 | path: _build/ 40 | compression-level: 9 41 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint the code 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'src/**' 7 | - '**/*.json' 8 | pull_request: 9 | paths: 10 | - 'src/**' 11 | - '**/*.json' 12 | 13 | jobs: 14 | lint: 15 | name: Lint the code 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout the repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Set up Biome 22 | uses: biomejs/setup-biome@v2 23 | with: 24 | version: latest 25 | 26 | - name: Run Biome 27 | run: biome ci . 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | *.zip 3 | node_modules 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![2022-07-29 23-49-57][6] 2 | 3 |
A GNOME extension that adds rounded corners to all windows
6 | 7 |",
6 | "license": "GPL-3.0-or-later",
7 | "main": "src/extension.ts",
8 | "devDependencies": {
9 | "@biomejs/biome": "^1.9.4",
10 | "@girs/gnome-shell": "^47.0.2",
11 | "typescript": "^5.7.2"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/po/ar.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: 12\n"
4 | "Report-Msgid-Bugs-To: \n"
5 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
6 | "PO-Revision-Date: 2023-12-10 10:05+0000\n"
7 | "Last-Translator: Nadjib Chergui \n"
8 | "Language-Team: Arabic \n"
10 | "Language: ar\n"
11 | "Content-Type: text/plain; charset=UTF-8\n"
12 | "Content-Transfer-Encoding: 8bit\n"
13 | "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
14 | "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
15 | "X-Generator: Weblate 5.3-dev\n"
16 |
17 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
18 | msgid "Blacklist"
19 | msgstr "اللائحة السوداء"
20 |
21 | #: src/preferences/pages/blacklist.ui:11
22 | #, fuzzy
23 | msgid ""
24 | "Not all application can works well with rounded corners effects, add them to "
25 | "this list to disable effects."
26 | msgstr ""
27 | "ليست كل التطبيقات تعمل مع تأثير الزوايا المدورة، أضفهم لإيقاف التأثيرات لهم."
28 |
29 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
30 | #, fuzzy
31 | msgid "Add window"
32 | msgstr "إضافة نافذة"
33 |
34 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
35 | msgid "Custom"
36 | msgstr "خاص"
37 |
38 | #: src/preferences/pages/custom.ui:11
39 | #, fuzzy
40 | msgid "Set custom effect setting for each window class"
41 | msgstr "تفعيل الإعدادات الخاصة بهذه النافذة"
42 |
43 | #: src/preferences/pages/edit-shadow.ui:6
44 | msgid "Edit shadows"
45 | msgstr ""
46 |
47 | #: src/preferences/pages/edit-shadow.ui:28
48 | #, fuzzy
49 | msgid "Focused window"
50 | msgstr "التركيز على النافذة"
51 |
52 | #: src/preferences/pages/edit-shadow.ui:43
53 | #, fuzzy
54 | msgid "Unfocused window"
55 | msgstr "النافذة الغير المختارة"
56 |
57 | #: src/preferences/pages/edit-shadow.ui:66
58 | msgid "Focused shadow prefrences"
59 | msgstr ""
60 |
61 | #: src/preferences/pages/edit-shadow.ui:69
62 | #: src/preferences/pages/edit-shadow.ui:209
63 | #, fuzzy
64 | msgid "Horizontal offset"
65 | msgstr "الميلان الأفقي"
66 |
67 | #: src/preferences/pages/edit-shadow.ui:96
68 | #: src/preferences/pages/edit-shadow.ui:236
69 | #, fuzzy
70 | msgid "Vertical offset"
71 | msgstr "الميلان العمودي"
72 |
73 | #: src/preferences/pages/edit-shadow.ui:123
74 | #: src/preferences/pages/edit-shadow.ui:263
75 | #, fuzzy
76 | msgid "Blur radius"
77 | msgstr "درجة تدوير زوايا الحدود"
78 |
79 | #: src/preferences/pages/edit-shadow.ui:150
80 | #: src/preferences/pages/edit-shadow.ui:290
81 | #, fuzzy
82 | msgid "Spread radius"
83 | msgstr "درجة تدوير زوايا الحدود"
84 |
85 | #: src/preferences/pages/edit-shadow.ui:177
86 | #: src/preferences/pages/edit-shadow.ui:317
87 | msgid "Opacity"
88 | msgstr ""
89 |
90 | #: src/preferences/pages/edit-shadow.ui:206
91 | msgid "Unfocused shadow prefrences"
92 | msgstr ""
93 |
94 | #: src/preferences/pages/general.ui:6
95 | msgid "General"
96 | msgstr "عام"
97 |
98 | #: src/preferences/pages/general.ui:10
99 | msgid "Applications"
100 | msgstr "تطبيقات"
101 |
102 | #: src/preferences/pages/general.ui:11
103 | #, fuzzy
104 | msgid ""
105 | "Some applications created with LibAdwaita or LibHandy already have rounded "
106 | "corners. You can enable those settings to avoid rounding their corners an "
107 | "extra time."
108 | msgstr ""
109 | "بعض التطبيقات التي تستخدم (LibAdwaita) أو (LibHandy) لديها زوايا دائرية "
110 | "فعلًا، إذن يمكن تجنبها بواسطة هذه الإعدادات"
111 |
112 | #: src/preferences/pages/general.ui:14
113 | #, fuzzy
114 | msgid "Skip LibAdwaita applications"
115 | msgstr "تجنب تطبيقات (LibAdwaita)"
116 |
117 | #: src/preferences/pages/general.ui:19
118 | #, fuzzy
119 | msgid "Skip LibHandy applications"
120 | msgstr "تجنب تطبيقات (LibHandy)"
121 |
122 | #: src/preferences/pages/general.ui:26
123 | #, fuzzy
124 | msgid "Global settings"
125 | msgstr "الإعدادات الشاملة"
126 |
127 | #: src/preferences/pages/general.ui:27
128 | #, fuzzy
129 | msgid "These settings will have an effect on all windows"
130 | msgstr "هذه الإعدادات ستحاول في التأثير على كل النوافذ"
131 |
132 | #: src/preferences/pages/general.ui:30
133 | #, fuzzy
134 | msgid "Border width"
135 | msgstr "عرض الحدود"
136 |
137 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
138 | #: src/preferences/widgets/custom_settings_row.ts:19
139 | #, fuzzy
140 | msgid "Border color"
141 | msgstr "لون الحدود"
142 |
143 | #: src/preferences/pages/general.ui:74
144 | #: src/preferences/widgets/custom_settings_row.ts:27
145 | #, fuzzy
146 | msgid "Corner radius"
147 | msgstr "درجة تدوير زوايا الحدود"
148 |
149 | #: src/preferences/pages/general.ui:101
150 | #: src/preferences/widgets/custom_settings_row.ts:37
151 | #, fuzzy
152 | msgid "Corner smoothing"
153 | msgstr "تمليس الزاوية"
154 |
155 | #: src/preferences/pages/general.ui:127
156 | #, fuzzy
157 | msgid "Window shadow"
158 | msgstr "ظل النافذة"
159 |
160 | #: src/preferences/pages/general.ui:128
161 | msgid "Customize the shadow of the rounded corner window"
162 | msgstr "تخصيص نمط ظل النافذة ذات الزوايا المدورة"
163 |
164 | #: src/preferences/pages/general.ui:140
165 | #, fuzzy
166 | msgid "Keep rounded corners for maximized windows"
167 | msgstr "إبقاء الزوايا المدورة في وضع التكبير"
168 |
169 | #: src/preferences/pages/general.ui:145
170 | #, fuzzy
171 | msgid "Keep rounded corners for fullscreen windows"
172 | msgstr "إبقاء الزوايا المدورة في وضع ملء الشاشة"
173 |
174 | #: src/preferences/pages/general.ui:155
175 | msgid "Tweaks"
176 | msgstr "تعديلات"
177 |
178 | #: src/preferences/pages/general.ui:158
179 | #, fuzzy
180 | msgid "Add rounded corners to Kitty Terminal on Wayland"
181 | msgstr "حاول إضافة الزوايا المدورة لطرفية كيتي (Kitty) في وايلاند (Wayland)"
182 |
183 | #: src/preferences/pages/general.ui:159
184 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
185 | msgstr ""
186 |
187 | #: src/preferences/pages/general.ui:164
188 | #, fuzzy
189 | msgid "Add a settings entry in right-click menu of the desktop"
190 | msgstr "أضف بند الإعدادات في قائمة النقرة اليمنى للخلفية"
191 |
192 | #: src/preferences/pages/general.ui:171
193 | msgid "Debug"
194 | msgstr "تصحيح الأخطاء"
195 |
196 | #: src/preferences/pages/general.ui:174
197 | #, fuzzy
198 | msgid "Enable debug logs"
199 | msgstr "تفعيل التسجيلات التقنية"
200 |
201 | #: src/preferences/pages/general.ui:175
202 | #, fuzzy
203 | msgid ""
204 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
205 | msgstr ""
206 | "شغل journalctl -o cat -f /usr/bin/gnome-shell في الطرفية لتظهر "
207 | "التسجيلات"
208 |
209 | #: src/preferences/pages/general.ui:184
210 | #, fuzzy
211 | msgid "Reset preferences"
212 | msgstr "إعادة ضبط الإعدادات"
213 |
214 | #: src/preferences/pages/reset.ui:6
215 | msgid "Reset settings"
216 | msgstr ""
217 |
218 | #: src/preferences/pages/reset.ui:16
219 | #, fuzzy
220 | msgid "Settings to reset"
221 | msgstr "اختر الأشياء لإعادة ضبطها"
222 |
223 | #: src/preferences/pages/reset.ui:22
224 | #, fuzzy
225 | msgid "Select all"
226 | msgstr "اختر الكل"
227 |
228 | #: src/preferences/pages/reset.ui:39
229 | msgid "Reset"
230 | msgstr ""
231 |
232 | #: src/preferences/pages/reset.ui:55
233 | msgid "Reset these settings?"
234 | msgstr ""
235 |
236 | #: src/preferences/pages/reset.ui:60
237 | msgid "_Cancel"
238 | msgstr ""
239 |
240 | #: src/preferences/pages/reset.ui:61
241 | msgid "_Reset"
242 | msgstr ""
243 |
244 | #: src/preferences/widgets/paddings-row.ui:12
245 | msgid "Paddings"
246 | msgstr "تباعدات"
247 |
248 | #: src/preferences/widgets/paddings-row.ui:25
249 | msgid "Top"
250 | msgstr "أعلى"
251 |
252 | #: src/preferences/widgets/paddings-row.ui:40
253 | msgid "Bottom"
254 | msgstr "أسفل"
255 |
256 | #: src/preferences/widgets/paddings-row.ui:55
257 | msgid "Left"
258 | msgstr "يسار"
259 |
260 | #: src/preferences/widgets/paddings-row.ui:70
261 | msgid "Right"
262 | msgstr "يمين"
263 |
264 | #: src/preferences/widgets/app_row.ts:33
265 | #, fuzzy
266 | msgid "Window class"
267 | msgstr "ظل النافذة"
268 |
269 | #: src/preferences/widgets/app_row.ts:54
270 | #, fuzzy
271 | msgid "Expand this row, to pick a window"
272 | msgstr "كبر الصف لاختيار نافذة."
273 |
274 | #: src/preferences/widgets/app_row.ts:94
275 | #, fuzzy
276 | msgid "Can't pick window from this position"
277 | msgstr "لا يمكن اختيار النافذة من هذا المكان"
278 |
279 | #: src/preferences/widgets/custom_settings_row.ts:15
280 | #, fuzzy
281 | msgid "Enabled"
282 | msgstr "تفعيل"
283 |
284 | #: src/preferences/widgets/custom_settings_row.ts:47
285 | #, fuzzy
286 | msgid "Keep rounded corners when maximized"
287 | msgstr "إبقاء الزوايا المدورة في وضع التكبير"
288 |
289 | #: src/preferences/widgets/custom_settings_row.ts:49
290 | #, fuzzy
291 | msgid "Always clip rounded corners even if window is maximized or tiled"
292 | msgstr "إبقاء زوايا النافذة مدورة في وضع التكبير أو التحجيم."
293 |
294 | #: src/preferences/widgets/custom_settings_row.ts:53
295 | #, fuzzy
296 | msgid "Keep rounded corners when in fullscreen"
297 | msgstr "إبقاء الزوايا المدورة في وضع ملء الشاشة"
298 |
299 | #: src/preferences/widgets/custom_settings_row.ts:54
300 | #, fuzzy
301 | msgid "Always clip rounded corners even for fullscreen window"
302 | msgstr "إبقاء الزوايا المدورة في حال النافذة في وضع ملء الشاشة."
303 |
304 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
305 | msgid "Rounded Corners Settings..."
306 | msgstr "إعدادات الزوايا المدورة..."
307 |
308 | #, fuzzy
309 | #~ msgid "Open prefereces reset page"
310 | #~ msgstr "فتح نافذة إعادة الضبط"
311 |
312 | #~ msgid "Skip LibAdwaita Applications"
313 | #~ msgstr "تجنب تطبيقات (LibAdwaita)"
314 |
315 | #~ msgid "Skip LibHandy Applications"
316 | #~ msgstr "تجنب تطبيقات (LibHandy)"
317 |
318 | #~ msgid "Focus Window Shadow Style"
319 | #~ msgstr "نمط ظل النافذة المختارة"
320 |
321 | #~ msgid "Unfocus Window Shadow Style"
322 | #~ msgstr "نمط ظل النافذة الغير المختارة"
323 |
324 | #, fuzzy
325 | #~ msgid "Border Width"
326 | #~ msgstr "عرض الحدود"
327 |
328 | #~ msgid "Border Color"
329 | #~ msgstr "لون الحدود"
330 |
331 | #~ msgid "Border Radius"
332 | #~ msgstr "درجة تدوير زوايا الحدود"
333 |
334 | #~ msgid "Padding"
335 | #~ msgstr "تباعد"
336 |
337 | #~ msgid "Keep Rounded Corners when Maximized or Fullscreen"
338 | #~ msgstr "إبقاء الزوايا المدورة في وضع التكبير أو ملء الشاشة"
339 |
340 | #~ msgid "Corner Smoothing"
341 | #~ msgstr "تمليس الزاوية"
342 |
343 | #~ msgid "Expand this row to pick a window."
344 | #~ msgstr "كبر الصف لاختيار نافذة."
345 |
346 | #~ msgid "Remove Window from this List"
347 | #~ msgstr "إزالة النافذة من القائمة"
348 |
349 | #~ msgid "Pick Window to add into list"
350 | #~ msgstr "اختر نافذةً لإضافتها إلى القائمة"
351 |
352 | #~ msgid "Apply"
353 | #~ msgstr "تطبيق"
354 |
355 | #~ msgid "Blur Offset"
356 | #~ msgstr "توازن الضبابية"
357 |
358 | #, fuzzy
359 | #~ msgid "Clip paddings of window"
360 | #~ msgstr "تصغير حواف النافذة"
361 |
362 | #~ msgid "Can't add to list, because it has exists"
363 | #~ msgstr "لا يمكن إضافته للقائمة، لأنه موجودة فيها"
364 |
365 | #~ msgid "Edit Shadow for Rounded Corners Windows"
366 | #~ msgstr "تعديل ظل النوافذ ذات الزوايا المدورة"
367 |
--------------------------------------------------------------------------------
/po/eo.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Report-Msgid-Bugs-To: \n"
4 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
5 | "PO-Revision-Date: 2023-01-04 20:51+0000\n"
6 | "Last-Translator: phlostically \n"
7 | "Language-Team: Esperanto \n"
9 | "Language: eo\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "Plural-Forms: nplurals=2; plural=n != 1;\n"
13 | "X-Generator: Weblate 4.15.1-dev\n"
14 |
15 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
16 | msgid "Blacklist"
17 | msgstr ""
18 |
19 | #: src/preferences/pages/blacklist.ui:11
20 | msgid ""
21 | "Not all application can works well with rounded corners effects, add them to "
22 | "this list to disable effects."
23 | msgstr ""
24 |
25 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
26 | msgid "Add window"
27 | msgstr ""
28 |
29 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
30 | msgid "Custom"
31 | msgstr "Propra"
32 |
33 | #: src/preferences/pages/custom.ui:11
34 | msgid "Set custom effect setting for each window class"
35 | msgstr ""
36 |
37 | #: src/preferences/pages/edit-shadow.ui:6
38 | msgid "Edit shadows"
39 | msgstr ""
40 |
41 | #: src/preferences/pages/edit-shadow.ui:28
42 | #, fuzzy
43 | msgid "Focused window"
44 | msgstr "Enfokusa fenestro"
45 |
46 | #: src/preferences/pages/edit-shadow.ui:43
47 | #, fuzzy
48 | msgid "Unfocused window"
49 | msgstr "Eksterfokusa fenestro"
50 |
51 | #: src/preferences/pages/edit-shadow.ui:66
52 | msgid "Focused shadow prefrences"
53 | msgstr ""
54 |
55 | #: src/preferences/pages/edit-shadow.ui:69
56 | #: src/preferences/pages/edit-shadow.ui:209
57 | msgid "Horizontal offset"
58 | msgstr ""
59 |
60 | #: src/preferences/pages/edit-shadow.ui:96
61 | #: src/preferences/pages/edit-shadow.ui:236
62 | msgid "Vertical offset"
63 | msgstr ""
64 |
65 | #: src/preferences/pages/edit-shadow.ui:123
66 | #: src/preferences/pages/edit-shadow.ui:263
67 | #, fuzzy
68 | msgid "Blur radius"
69 | msgstr "Randa radiuso"
70 |
71 | #: src/preferences/pages/edit-shadow.ui:150
72 | #: src/preferences/pages/edit-shadow.ui:290
73 | #, fuzzy
74 | msgid "Spread radius"
75 | msgstr "Randa radiuso"
76 |
77 | #: src/preferences/pages/edit-shadow.ui:177
78 | #: src/preferences/pages/edit-shadow.ui:317
79 | msgid "Opacity"
80 | msgstr "Opako"
81 |
82 | #: src/preferences/pages/edit-shadow.ui:206
83 | msgid "Unfocused shadow prefrences"
84 | msgstr ""
85 |
86 | #: src/preferences/pages/general.ui:6
87 | msgid "General"
88 | msgstr "Ĝenerala"
89 |
90 | #: src/preferences/pages/general.ui:10
91 | msgid "Applications"
92 | msgstr "Programoj"
93 |
94 | #: src/preferences/pages/general.ui:11
95 | msgid ""
96 | "Some applications created with LibAdwaita or LibHandy already have rounded "
97 | "corners. You can enable those settings to avoid rounding their corners an "
98 | "extra time."
99 | msgstr ""
100 |
101 | #: src/preferences/pages/general.ui:14
102 | #, fuzzy
103 | msgid "Skip LibAdwaita applications"
104 | msgstr "Preterpasi libadwaita-programojn"
105 |
106 | #: src/preferences/pages/general.ui:19
107 | #, fuzzy
108 | msgid "Skip LibHandy applications"
109 | msgstr "Preterpasi libhandy-programojn"
110 |
111 | #: src/preferences/pages/general.ui:26
112 | msgid "Global settings"
113 | msgstr ""
114 |
115 | #: src/preferences/pages/general.ui:27
116 | msgid "These settings will have an effect on all windows"
117 | msgstr ""
118 |
119 | #: src/preferences/pages/general.ui:30
120 | #, fuzzy
121 | msgid "Border width"
122 | msgstr "Randa larĝo"
123 |
124 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
125 | #: src/preferences/widgets/custom_settings_row.ts:19
126 | #, fuzzy
127 | msgid "Border color"
128 | msgstr "Randa koloro"
129 |
130 | #: src/preferences/pages/general.ui:74
131 | #: src/preferences/widgets/custom_settings_row.ts:27
132 | #, fuzzy
133 | msgid "Corner radius"
134 | msgstr "Randa radiuso"
135 |
136 | #: src/preferences/pages/general.ui:101
137 | #: src/preferences/widgets/custom_settings_row.ts:37
138 | msgid "Corner smoothing"
139 | msgstr ""
140 |
141 | #: src/preferences/pages/general.ui:127
142 | msgid "Window shadow"
143 | msgstr ""
144 |
145 | #: src/preferences/pages/general.ui:128
146 | msgid "Customize the shadow of the rounded corner window"
147 | msgstr ""
148 |
149 | #: src/preferences/pages/general.ui:140
150 | msgid "Keep rounded corners for maximized windows"
151 | msgstr ""
152 |
153 | #: src/preferences/pages/general.ui:145
154 | msgid "Keep rounded corners for fullscreen windows"
155 | msgstr ""
156 |
157 | #: src/preferences/pages/general.ui:155
158 | msgid "Tweaks"
159 | msgstr ""
160 |
161 | #: src/preferences/pages/general.ui:158
162 | msgid "Add rounded corners to Kitty Terminal on Wayland"
163 | msgstr ""
164 |
165 | #: src/preferences/pages/general.ui:159
166 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
167 | msgstr ""
168 |
169 | #: src/preferences/pages/general.ui:164
170 | msgid "Add a settings entry in right-click menu of the desktop"
171 | msgstr ""
172 |
173 | #: src/preferences/pages/general.ui:171
174 | msgid "Debug"
175 | msgstr ""
176 |
177 | #: src/preferences/pages/general.ui:174
178 | msgid "Enable debug logs"
179 | msgstr ""
180 |
181 | #: src/preferences/pages/general.ui:175
182 | msgid ""
183 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
184 | msgstr ""
185 |
186 | #: src/preferences/pages/general.ui:184
187 | msgid "Reset preferences"
188 | msgstr ""
189 |
190 | #: src/preferences/pages/reset.ui:6
191 | msgid "Reset settings"
192 | msgstr ""
193 |
194 | #: src/preferences/pages/reset.ui:16
195 | msgid "Settings to reset"
196 | msgstr ""
197 |
198 | #: src/preferences/pages/reset.ui:22
199 | #, fuzzy
200 | msgid "Select all"
201 | msgstr "Elekti ĉion"
202 |
203 | #: src/preferences/pages/reset.ui:39
204 | msgid "Reset"
205 | msgstr ""
206 |
207 | #: src/preferences/pages/reset.ui:55
208 | msgid "Reset these settings?"
209 | msgstr ""
210 |
211 | #: src/preferences/pages/reset.ui:60
212 | msgid "_Cancel"
213 | msgstr ""
214 |
215 | #: src/preferences/pages/reset.ui:61
216 | msgid "_Reset"
217 | msgstr ""
218 |
219 | #: src/preferences/widgets/paddings-row.ui:12
220 | msgid "Paddings"
221 | msgstr ""
222 |
223 | #: src/preferences/widgets/paddings-row.ui:25
224 | msgid "Top"
225 | msgstr "Supro"
226 |
227 | #: src/preferences/widgets/paddings-row.ui:40
228 | msgid "Bottom"
229 | msgstr "Malsupro"
230 |
231 | #: src/preferences/widgets/paddings-row.ui:55
232 | msgid "Left"
233 | msgstr "Maldekstro"
234 |
235 | #: src/preferences/widgets/paddings-row.ui:70
236 | msgid "Right"
237 | msgstr "Dekstro"
238 |
239 | #: src/preferences/widgets/app_row.ts:33
240 | msgid "Window class"
241 | msgstr ""
242 |
243 | #: src/preferences/widgets/app_row.ts:54
244 | msgid "Expand this row, to pick a window"
245 | msgstr ""
246 |
247 | #: src/preferences/widgets/app_row.ts:94
248 | msgid "Can't pick window from this position"
249 | msgstr ""
250 |
251 | #: src/preferences/widgets/custom_settings_row.ts:15
252 | #, fuzzy
253 | msgid "Enabled"
254 | msgstr "Ŝalti"
255 |
256 | #: src/preferences/widgets/custom_settings_row.ts:47
257 | msgid "Keep rounded corners when maximized"
258 | msgstr ""
259 |
260 | #: src/preferences/widgets/custom_settings_row.ts:49
261 | msgid "Always clip rounded corners even if window is maximized or tiled"
262 | msgstr ""
263 |
264 | #: src/preferences/widgets/custom_settings_row.ts:53
265 | msgid "Keep rounded corners when in fullscreen"
266 | msgstr ""
267 |
268 | #: src/preferences/widgets/custom_settings_row.ts:54
269 | msgid "Always clip rounded corners even for fullscreen window"
270 | msgstr ""
271 |
272 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
273 | msgid "Rounded Corners Settings..."
274 | msgstr ""
275 |
276 | #~ msgid "Skip LibAdwaita Applications"
277 | #~ msgstr "Preterpasi libadwaita-programojn"
278 |
279 | #~ msgid "Skip LibHandy Applications"
280 | #~ msgstr "Preterpasi libhandy-programojn"
281 |
282 | #~ msgid "Border Width"
283 | #~ msgstr "Randa larĝo"
284 |
285 | #~ msgid "Border Color"
286 | #~ msgstr "Randa koloro"
287 |
288 | #~ msgid "Border Radius"
289 | #~ msgstr "Randa radiuso"
290 |
291 | #~ msgid "Apply"
292 | #~ msgstr "Efektivigi"
293 |
--------------------------------------------------------------------------------
/po/et.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Report-Msgid-Bugs-To: \n"
4 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
5 | "Language: et\n"
6 | "Content-Type: text/plain; charset=UTF-8\n"
7 | "Content-Transfer-Encoding: 8bit\n"
8 |
9 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
10 | msgid "Blacklist"
11 | msgstr ""
12 |
13 | #: src/preferences/pages/blacklist.ui:11
14 | msgid ""
15 | "Not all application can works well with rounded corners effects, add them to "
16 | "this list to disable effects."
17 | msgstr ""
18 |
19 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
20 | msgid "Add window"
21 | msgstr ""
22 |
23 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
24 | msgid "Custom"
25 | msgstr ""
26 |
27 | #: src/preferences/pages/custom.ui:11
28 | msgid "Set custom effect setting for each window class"
29 | msgstr ""
30 |
31 | #: src/preferences/pages/edit-shadow.ui:6
32 | msgid "Edit shadows"
33 | msgstr ""
34 |
35 | #: src/preferences/pages/edit-shadow.ui:28
36 | msgid "Focused window"
37 | msgstr ""
38 |
39 | #: src/preferences/pages/edit-shadow.ui:43
40 | msgid "Unfocused window"
41 | msgstr ""
42 |
43 | #: src/preferences/pages/edit-shadow.ui:66
44 | msgid "Focused shadow prefrences"
45 | msgstr ""
46 |
47 | #: src/preferences/pages/edit-shadow.ui:69
48 | #: src/preferences/pages/edit-shadow.ui:209
49 | msgid "Horizontal offset"
50 | msgstr ""
51 |
52 | #: src/preferences/pages/edit-shadow.ui:96
53 | #: src/preferences/pages/edit-shadow.ui:236
54 | msgid "Vertical offset"
55 | msgstr ""
56 |
57 | #: src/preferences/pages/edit-shadow.ui:123
58 | #: src/preferences/pages/edit-shadow.ui:263
59 | msgid "Blur radius"
60 | msgstr ""
61 |
62 | #: src/preferences/pages/edit-shadow.ui:150
63 | #: src/preferences/pages/edit-shadow.ui:290
64 | msgid "Spread radius"
65 | msgstr ""
66 |
67 | #: src/preferences/pages/edit-shadow.ui:177
68 | #: src/preferences/pages/edit-shadow.ui:317
69 | msgid "Opacity"
70 | msgstr ""
71 |
72 | #: src/preferences/pages/edit-shadow.ui:206
73 | msgid "Unfocused shadow prefrences"
74 | msgstr ""
75 |
76 | #: src/preferences/pages/general.ui:6
77 | msgid "General"
78 | msgstr ""
79 |
80 | #: src/preferences/pages/general.ui:10
81 | msgid "Applications"
82 | msgstr ""
83 |
84 | #: src/preferences/pages/general.ui:11
85 | msgid ""
86 | "Some applications created with LibAdwaita or LibHandy already have rounded "
87 | "corners. You can enable those settings to avoid rounding their corners an "
88 | "extra time."
89 | msgstr ""
90 |
91 | #: src/preferences/pages/general.ui:14
92 | msgid "Skip LibAdwaita applications"
93 | msgstr ""
94 |
95 | #: src/preferences/pages/general.ui:19
96 | msgid "Skip LibHandy applications"
97 | msgstr ""
98 |
99 | #: src/preferences/pages/general.ui:26
100 | msgid "Global settings"
101 | msgstr ""
102 |
103 | #: src/preferences/pages/general.ui:27
104 | msgid "These settings will have an effect on all windows"
105 | msgstr ""
106 |
107 | #: src/preferences/pages/general.ui:30
108 | msgid "Border width"
109 | msgstr ""
110 |
111 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
112 | #: src/preferences/widgets/custom_settings_row.ts:19
113 | msgid "Border color"
114 | msgstr ""
115 |
116 | #: src/preferences/pages/general.ui:74
117 | #: src/preferences/widgets/custom_settings_row.ts:27
118 | msgid "Corner radius"
119 | msgstr ""
120 |
121 | #: src/preferences/pages/general.ui:101
122 | #: src/preferences/widgets/custom_settings_row.ts:37
123 | msgid "Corner smoothing"
124 | msgstr ""
125 |
126 | #: src/preferences/pages/general.ui:127
127 | msgid "Window shadow"
128 | msgstr ""
129 |
130 | #: src/preferences/pages/general.ui:128
131 | msgid "Customize the shadow of the rounded corner window"
132 | msgstr ""
133 |
134 | #: src/preferences/pages/general.ui:140
135 | msgid "Keep rounded corners for maximized windows"
136 | msgstr ""
137 |
138 | #: src/preferences/pages/general.ui:145
139 | msgid "Keep rounded corners for fullscreen windows"
140 | msgstr ""
141 |
142 | #: src/preferences/pages/general.ui:155
143 | msgid "Tweaks"
144 | msgstr ""
145 |
146 | #: src/preferences/pages/general.ui:158
147 | msgid "Add rounded corners to Kitty Terminal on Wayland"
148 | msgstr ""
149 |
150 | #: src/preferences/pages/general.ui:159
151 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
152 | msgstr ""
153 |
154 | #: src/preferences/pages/general.ui:164
155 | msgid "Add a settings entry in right-click menu of the desktop"
156 | msgstr ""
157 |
158 | #: src/preferences/pages/general.ui:171
159 | msgid "Debug"
160 | msgstr ""
161 |
162 | #: src/preferences/pages/general.ui:174
163 | msgid "Enable debug logs"
164 | msgstr ""
165 |
166 | #: src/preferences/pages/general.ui:175
167 | msgid ""
168 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
169 | msgstr ""
170 |
171 | #: src/preferences/pages/general.ui:184
172 | msgid "Reset preferences"
173 | msgstr ""
174 |
175 | #: src/preferences/pages/reset.ui:6
176 | msgid "Reset settings"
177 | msgstr ""
178 |
179 | #: src/preferences/pages/reset.ui:16
180 | msgid "Settings to reset"
181 | msgstr ""
182 |
183 | #: src/preferences/pages/reset.ui:22
184 | msgid "Select all"
185 | msgstr ""
186 |
187 | #: src/preferences/pages/reset.ui:39
188 | msgid "Reset"
189 | msgstr ""
190 |
191 | #: src/preferences/pages/reset.ui:55
192 | msgid "Reset these settings?"
193 | msgstr ""
194 |
195 | #: src/preferences/pages/reset.ui:60
196 | msgid "_Cancel"
197 | msgstr ""
198 |
199 | #: src/preferences/pages/reset.ui:61
200 | msgid "_Reset"
201 | msgstr ""
202 |
203 | #: src/preferences/widgets/paddings-row.ui:12
204 | msgid "Paddings"
205 | msgstr ""
206 |
207 | #: src/preferences/widgets/paddings-row.ui:25
208 | msgid "Top"
209 | msgstr ""
210 |
211 | #: src/preferences/widgets/paddings-row.ui:40
212 | msgid "Bottom"
213 | msgstr ""
214 |
215 | #: src/preferences/widgets/paddings-row.ui:55
216 | msgid "Left"
217 | msgstr ""
218 |
219 | #: src/preferences/widgets/paddings-row.ui:70
220 | msgid "Right"
221 | msgstr ""
222 |
223 | #: src/preferences/widgets/app_row.ts:33
224 | msgid "Window class"
225 | msgstr ""
226 |
227 | #: src/preferences/widgets/app_row.ts:54
228 | msgid "Expand this row, to pick a window"
229 | msgstr ""
230 |
231 | #: src/preferences/widgets/app_row.ts:94
232 | msgid "Can't pick window from this position"
233 | msgstr ""
234 |
235 | #: src/preferences/widgets/custom_settings_row.ts:15
236 | msgid "Enabled"
237 | msgstr ""
238 |
239 | #: src/preferences/widgets/custom_settings_row.ts:47
240 | msgid "Keep rounded corners when maximized"
241 | msgstr ""
242 |
243 | #: src/preferences/widgets/custom_settings_row.ts:49
244 | msgid "Always clip rounded corners even if window is maximized or tiled"
245 | msgstr ""
246 |
247 | #: src/preferences/widgets/custom_settings_row.ts:53
248 | msgid "Keep rounded corners when in fullscreen"
249 | msgstr ""
250 |
251 | #: src/preferences/widgets/custom_settings_row.ts:54
252 | msgid "Always clip rounded corners even for fullscreen window"
253 | msgstr ""
254 |
255 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
256 | msgid "Rounded Corners Settings..."
257 | msgstr ""
258 |
--------------------------------------------------------------------------------
/po/hu.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: 10\n"
4 | "Report-Msgid-Bugs-To: \n"
5 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
6 | "PO-Revision-Date: 2023-10-01 14:00+0000\n"
7 | "Last-Translator: olevo \n"
8 | "Language-Team: Hungarian \n"
10 | "Language: hu\n"
11 | "Content-Type: text/plain; charset=UTF-8\n"
12 | "Content-Transfer-Encoding: 8bit\n"
13 | "Plural-Forms: nplurals=2; plural=n != 1;\n"
14 | "X-Generator: Weblate 5.1-dev\n"
15 |
16 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
17 | msgid "Blacklist"
18 | msgstr ""
19 |
20 | #: src/preferences/pages/blacklist.ui:11
21 | msgid ""
22 | "Not all application can works well with rounded corners effects, add them to "
23 | "this list to disable effects."
24 | msgstr ""
25 |
26 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
27 | msgid "Add window"
28 | msgstr ""
29 |
30 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
31 | msgid "Custom"
32 | msgstr "Egyéni"
33 |
34 | #: src/preferences/pages/custom.ui:11
35 | msgid "Set custom effect setting for each window class"
36 | msgstr ""
37 |
38 | #: src/preferences/pages/edit-shadow.ui:6
39 | msgid "Edit shadows"
40 | msgstr ""
41 |
42 | #: src/preferences/pages/edit-shadow.ui:28
43 | #, fuzzy
44 | msgid "Focused window"
45 | msgstr "Ablak előtérbe helyezése"
46 |
47 | #: src/preferences/pages/edit-shadow.ui:43
48 | #, fuzzy
49 | msgid "Unfocused window"
50 | msgstr "Ablak előtérbe helyezése"
51 |
52 | #: src/preferences/pages/edit-shadow.ui:66
53 | msgid "Focused shadow prefrences"
54 | msgstr ""
55 |
56 | #: src/preferences/pages/edit-shadow.ui:69
57 | #: src/preferences/pages/edit-shadow.ui:209
58 | msgid "Horizontal offset"
59 | msgstr ""
60 |
61 | #: src/preferences/pages/edit-shadow.ui:96
62 | #: src/preferences/pages/edit-shadow.ui:236
63 | msgid "Vertical offset"
64 | msgstr ""
65 |
66 | #: src/preferences/pages/edit-shadow.ui:123
67 | #: src/preferences/pages/edit-shadow.ui:263
68 | #, fuzzy
69 | msgid "Blur radius"
70 | msgstr "A border radius vastagsága"
71 |
72 | #: src/preferences/pages/edit-shadow.ui:150
73 | #: src/preferences/pages/edit-shadow.ui:290
74 | #, fuzzy
75 | msgid "Spread radius"
76 | msgstr "A border radius vastagsága"
77 |
78 | #: src/preferences/pages/edit-shadow.ui:177
79 | #: src/preferences/pages/edit-shadow.ui:317
80 | msgid "Opacity"
81 | msgstr "Áttettszőség"
82 |
83 | #: src/preferences/pages/edit-shadow.ui:206
84 | msgid "Unfocused shadow prefrences"
85 | msgstr ""
86 |
87 | #: src/preferences/pages/general.ui:6
88 | msgid "General"
89 | msgstr "Általános"
90 |
91 | #: src/preferences/pages/general.ui:10
92 | msgid "Applications"
93 | msgstr ""
94 |
95 | #: src/preferences/pages/general.ui:11
96 | msgid ""
97 | "Some applications created with LibAdwaita or LibHandy already have rounded "
98 | "corners. You can enable those settings to avoid rounding their corners an "
99 | "extra time."
100 | msgstr ""
101 |
102 | #: src/preferences/pages/general.ui:14
103 | msgid "Skip LibAdwaita applications"
104 | msgstr ""
105 |
106 | #: src/preferences/pages/general.ui:19
107 | msgid "Skip LibHandy applications"
108 | msgstr ""
109 |
110 | #: src/preferences/pages/general.ui:26
111 | #, fuzzy
112 | msgid "Global settings"
113 | msgstr "Globál beállítások"
114 |
115 | #: src/preferences/pages/general.ui:27
116 | msgid "These settings will have an effect on all windows"
117 | msgstr ""
118 |
119 | #: src/preferences/pages/general.ui:30
120 | #, fuzzy
121 | msgid "Border width"
122 | msgstr "A border szélessége"
123 |
124 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
125 | #: src/preferences/widgets/custom_settings_row.ts:19
126 | #, fuzzy
127 | msgid "Border color"
128 | msgstr "A border széle"
129 |
130 | #: src/preferences/pages/general.ui:74
131 | #: src/preferences/widgets/custom_settings_row.ts:27
132 | #, fuzzy
133 | msgid "Corner radius"
134 | msgstr "A border radius vastagsága"
135 |
136 | #: src/preferences/pages/general.ui:101
137 | #: src/preferences/widgets/custom_settings_row.ts:37
138 | #, fuzzy
139 | msgid "Corner smoothing"
140 | msgstr "A sarkok simítása/simasága"
141 |
142 | #: src/preferences/pages/general.ui:127
143 | msgid "Window shadow"
144 | msgstr ""
145 |
146 | #: src/preferences/pages/general.ui:128
147 | msgid "Customize the shadow of the rounded corner window"
148 | msgstr ""
149 |
150 | #: src/preferences/pages/general.ui:140
151 | msgid "Keep rounded corners for maximized windows"
152 | msgstr ""
153 |
154 | #: src/preferences/pages/general.ui:145
155 | msgid "Keep rounded corners for fullscreen windows"
156 | msgstr ""
157 |
158 | #: src/preferences/pages/general.ui:155
159 | msgid "Tweaks"
160 | msgstr ""
161 |
162 | #: src/preferences/pages/general.ui:158
163 | msgid "Add rounded corners to Kitty Terminal on Wayland"
164 | msgstr ""
165 |
166 | #: src/preferences/pages/general.ui:159
167 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
168 | msgstr ""
169 |
170 | #: src/preferences/pages/general.ui:164
171 | msgid "Add a settings entry in right-click menu of the desktop"
172 | msgstr ""
173 |
174 | #: src/preferences/pages/general.ui:171
175 | msgid "Debug"
176 | msgstr "Debug"
177 |
178 | #: src/preferences/pages/general.ui:174
179 | #, fuzzy
180 | msgid "Enable debug logs"
181 | msgstr "Napló bekapcsolása"
182 |
183 | #: src/preferences/pages/general.ui:175
184 | msgid ""
185 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
186 | msgstr ""
187 |
188 | #: src/preferences/pages/general.ui:184
189 | msgid "Reset preferences"
190 | msgstr ""
191 |
192 | #: src/preferences/pages/reset.ui:6
193 | msgid "Reset settings"
194 | msgstr ""
195 |
196 | #: src/preferences/pages/reset.ui:16
197 | msgid "Settings to reset"
198 | msgstr ""
199 |
200 | #: src/preferences/pages/reset.ui:22
201 | msgid "Select all"
202 | msgstr ""
203 |
204 | #: src/preferences/pages/reset.ui:39
205 | msgid "Reset"
206 | msgstr ""
207 |
208 | #: src/preferences/pages/reset.ui:55
209 | msgid "Reset these settings?"
210 | msgstr ""
211 |
212 | #: src/preferences/pages/reset.ui:60
213 | msgid "_Cancel"
214 | msgstr ""
215 |
216 | #: src/preferences/pages/reset.ui:61
217 | msgid "_Reset"
218 | msgstr ""
219 |
220 | #: src/preferences/widgets/paddings-row.ui:12
221 | msgid "Paddings"
222 | msgstr ""
223 |
224 | #: src/preferences/widgets/paddings-row.ui:25
225 | msgid "Top"
226 | msgstr ""
227 |
228 | #: src/preferences/widgets/paddings-row.ui:40
229 | msgid "Bottom"
230 | msgstr "Alja"
231 |
232 | #: src/preferences/widgets/paddings-row.ui:55
233 | msgid "Left"
234 | msgstr "Bal"
235 |
236 | #: src/preferences/widgets/paddings-row.ui:70
237 | msgid "Right"
238 | msgstr "Jobb"
239 |
240 | #: src/preferences/widgets/app_row.ts:33
241 | msgid "Window class"
242 | msgstr ""
243 |
244 | #: src/preferences/widgets/app_row.ts:54
245 | msgid "Expand this row, to pick a window"
246 | msgstr ""
247 |
248 | #: src/preferences/widgets/app_row.ts:94
249 | msgid "Can't pick window from this position"
250 | msgstr ""
251 |
252 | #: src/preferences/widgets/custom_settings_row.ts:15
253 | #, fuzzy
254 | msgid "Enabled"
255 | msgstr "Bekapcsolás"
256 |
257 | #: src/preferences/widgets/custom_settings_row.ts:47
258 | msgid "Keep rounded corners when maximized"
259 | msgstr ""
260 |
261 | #: src/preferences/widgets/custom_settings_row.ts:49
262 | msgid "Always clip rounded corners even if window is maximized or tiled"
263 | msgstr ""
264 |
265 | #: src/preferences/widgets/custom_settings_row.ts:53
266 | msgid "Keep rounded corners when in fullscreen"
267 | msgstr ""
268 |
269 | #: src/preferences/widgets/custom_settings_row.ts:54
270 | msgid "Always clip rounded corners even for fullscreen window"
271 | msgstr ""
272 |
273 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
274 | msgid "Rounded Corners Settings..."
275 | msgstr ""
276 |
277 | #~ msgid "Border Width"
278 | #~ msgstr "A border szélessége"
279 |
280 | #, fuzzy
281 | #~ msgid "Border Color"
282 | #~ msgstr "A border széle"
283 |
284 | #~ msgid "Border Radius"
285 | #~ msgstr "A border radius vastagsága"
286 |
287 | #~ msgid "Corner Smoothing"
288 | #~ msgstr "A sarkok simítása/simasága"
289 |
290 | #~ msgid "Can't add to list, because it has exists"
291 | #~ msgstr "Sikertelen hozzáadás, ez már létezik"
292 |
--------------------------------------------------------------------------------
/po/ja.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Report-Msgid-Bugs-To: \n"
4 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
5 | "PO-Revision-Date: 2023-03-21 15:37+0000\n"
6 | "Last-Translator: maboroshin \n"
7 | "Language-Team: Japanese \n"
9 | "Language: ja\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "Plural-Forms: nplurals=1; plural=0;\n"
13 | "X-Generator: Weblate 4.16.2-dev\n"
14 |
15 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
16 | msgid "Blacklist"
17 | msgstr "ブラックリスト"
18 |
19 | #: src/preferences/pages/blacklist.ui:11
20 | #, fuzzy
21 | msgid ""
22 | "Not all application can works well with rounded corners effects, add them to "
23 | "this list to disable effects."
24 | msgstr ""
25 | "すべてのアプリで角丸の効果がうまく効くわけではないため、この一覧に追加して無"
26 | "効にしてください。\n"
27 | "\n"
28 | "一覧の項目は、ウィンドウの WM_CLASS プロパティのインスタンス部分です。一覧に"
29 | "これを追加するウィンドウを選択できます。"
30 |
31 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
32 | #, fuzzy
33 | msgid "Add window"
34 | msgstr "ウィンドウ追加"
35 |
36 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
37 | msgid "Custom"
38 | msgstr "カスタマイズ"
39 |
40 | #: src/preferences/pages/custom.ui:11
41 | #, fuzzy
42 | msgid "Set custom effect setting for each window class"
43 | msgstr "このウィンドウの独自設定を有効化"
44 |
45 | #: src/preferences/pages/edit-shadow.ui:6
46 | msgid "Edit shadows"
47 | msgstr ""
48 |
49 | #: src/preferences/pages/edit-shadow.ui:28
50 | msgid "Focused window"
51 | msgstr ""
52 |
53 | #: src/preferences/pages/edit-shadow.ui:43
54 | msgid "Unfocused window"
55 | msgstr ""
56 |
57 | #: src/preferences/pages/edit-shadow.ui:66
58 | msgid "Focused shadow prefrences"
59 | msgstr ""
60 |
61 | #: src/preferences/pages/edit-shadow.ui:69
62 | #: src/preferences/pages/edit-shadow.ui:209
63 | #, fuzzy
64 | msgid "Horizontal offset"
65 | msgstr "水平 補正"
66 |
67 | #: src/preferences/pages/edit-shadow.ui:96
68 | #: src/preferences/pages/edit-shadow.ui:236
69 | #, fuzzy
70 | msgid "Vertical offset"
71 | msgstr "垂直 補正"
72 |
73 | #: src/preferences/pages/edit-shadow.ui:123
74 | #: src/preferences/pages/edit-shadow.ui:263
75 | #, fuzzy
76 | msgid "Blur radius"
77 | msgstr "境界線の角丸サイズ"
78 |
79 | #: src/preferences/pages/edit-shadow.ui:150
80 | #: src/preferences/pages/edit-shadow.ui:290
81 | #, fuzzy
82 | msgid "Spread radius"
83 | msgstr "境界線の角丸サイズ"
84 |
85 | #: src/preferences/pages/edit-shadow.ui:177
86 | #: src/preferences/pages/edit-shadow.ui:317
87 | msgid "Opacity"
88 | msgstr "不透明度"
89 |
90 | #: src/preferences/pages/edit-shadow.ui:206
91 | msgid "Unfocused shadow prefrences"
92 | msgstr ""
93 |
94 | #: src/preferences/pages/general.ui:6
95 | msgid "General"
96 | msgstr "一般"
97 |
98 | #: src/preferences/pages/general.ui:10
99 | msgid "Applications"
100 | msgstr "アプリケーション"
101 |
102 | #: src/preferences/pages/general.ui:11
103 | #, fuzzy
104 | msgid ""
105 | "Some applications created with LibAdwaita or LibHandy already have rounded "
106 | "corners. You can enable those settings to avoid rounding their corners an "
107 | "extra time."
108 | msgstr ""
109 | "LibAdwaita や LibHandy を使ったアプリには、すでに角丸なものがあるので、この設"
110 | "定で無視することができます"
111 |
112 | #: src/preferences/pages/general.ui:14
113 | #, fuzzy
114 | msgid "Skip LibAdwaita applications"
115 | msgstr "LibAdwaita のアプリは無視"
116 |
117 | #: src/preferences/pages/general.ui:19
118 | #, fuzzy
119 | msgid "Skip LibHandy applications"
120 | msgstr "LibHandy のアプリは無視"
121 |
122 | #: src/preferences/pages/general.ui:26
123 | #, fuzzy
124 | msgid "Global settings"
125 | msgstr "全般設定"
126 |
127 | #: src/preferences/pages/general.ui:27
128 | #, fuzzy
129 | msgid "These settings will have an effect on all windows"
130 | msgstr "この設定はすべてのウィンドウへの効果を試みます"
131 |
132 | #: src/preferences/pages/general.ui:30
133 | #, fuzzy
134 | msgid "Border width"
135 | msgstr "境界線の幅"
136 |
137 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
138 | #: src/preferences/widgets/custom_settings_row.ts:19
139 | #, fuzzy
140 | msgid "Border color"
141 | msgstr "境界線の色"
142 |
143 | #: src/preferences/pages/general.ui:74
144 | #: src/preferences/widgets/custom_settings_row.ts:27
145 | #, fuzzy
146 | msgid "Corner radius"
147 | msgstr "境界線の角丸サイズ"
148 |
149 | #: src/preferences/pages/general.ui:101
150 | #: src/preferences/widgets/custom_settings_row.ts:37
151 | #, fuzzy
152 | msgid "Corner smoothing"
153 | msgstr "角を滑らかに"
154 |
155 | #: src/preferences/pages/general.ui:127
156 | #, fuzzy
157 | msgid "Window shadow"
158 | msgstr "ウィンドウの影"
159 |
160 | #: src/preferences/pages/general.ui:128
161 | msgid "Customize the shadow of the rounded corner window"
162 | msgstr "角丸ウィンドウの影を指定"
163 |
164 | #: src/preferences/pages/general.ui:140
165 | #, fuzzy
166 | msgid "Keep rounded corners for maximized windows"
167 | msgstr "最大化時に角丸を維持"
168 |
169 | #: src/preferences/pages/general.ui:145
170 | #, fuzzy
171 | msgid "Keep rounded corners for fullscreen windows"
172 | msgstr "全画面時に角丸を維持"
173 |
174 | #: src/preferences/pages/general.ui:155
175 | msgid "Tweaks"
176 | msgstr ""
177 |
178 | #: src/preferences/pages/general.ui:158
179 | msgid "Add rounded corners to Kitty Terminal on Wayland"
180 | msgstr ""
181 |
182 | #: src/preferences/pages/general.ui:159
183 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
184 | msgstr ""
185 |
186 | #: src/preferences/pages/general.ui:164
187 | #, fuzzy
188 | msgid "Add a settings entry in right-click menu of the desktop"
189 | msgstr "背景の右クリックメニューに設定項目を追加"
190 |
191 | #: src/preferences/pages/general.ui:171
192 | msgid "Debug"
193 | msgstr "デバッグ"
194 |
195 | #: src/preferences/pages/general.ui:174
196 | #, fuzzy
197 | msgid "Enable debug logs"
198 | msgstr "ログを有効化"
199 |
200 | #: src/preferences/pages/general.ui:175
201 | #, fuzzy
202 | msgid ""
203 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
204 | msgstr ""
205 | "ログ閲覧にはターミナルで journalctl -o cat -f /usr/bin/gnome-shell を"
206 | "実行"
207 |
208 | #: src/preferences/pages/general.ui:184
209 | #, fuzzy
210 | msgid "Reset preferences"
211 | msgstr "設定を初期化"
212 |
213 | #: src/preferences/pages/reset.ui:6
214 | msgid "Reset settings"
215 | msgstr ""
216 |
217 | #: src/preferences/pages/reset.ui:16
218 | #, fuzzy
219 | msgid "Settings to reset"
220 | msgstr "初期化する項目を選択"
221 |
222 | #: src/preferences/pages/reset.ui:22
223 | #, fuzzy
224 | msgid "Select all"
225 | msgstr "すべて選択"
226 |
227 | #: src/preferences/pages/reset.ui:39
228 | msgid "Reset"
229 | msgstr ""
230 |
231 | #: src/preferences/pages/reset.ui:55
232 | msgid "Reset these settings?"
233 | msgstr ""
234 |
235 | #: src/preferences/pages/reset.ui:60
236 | msgid "_Cancel"
237 | msgstr ""
238 |
239 | #: src/preferences/pages/reset.ui:61
240 | msgid "_Reset"
241 | msgstr ""
242 |
243 | #: src/preferences/widgets/paddings-row.ui:12
244 | msgid "Paddings"
245 | msgstr ""
246 |
247 | #: src/preferences/widgets/paddings-row.ui:25
248 | msgid "Top"
249 | msgstr "上"
250 |
251 | #: src/preferences/widgets/paddings-row.ui:40
252 | msgid "Bottom"
253 | msgstr "下"
254 |
255 | #: src/preferences/widgets/paddings-row.ui:55
256 | msgid "Left"
257 | msgstr "左"
258 |
259 | #: src/preferences/widgets/paddings-row.ui:70
260 | msgid "Right"
261 | msgstr "右"
262 |
263 | #: src/preferences/widgets/app_row.ts:33
264 | #, fuzzy
265 | msgid "Window class"
266 | msgstr "ウィンドウの影"
267 |
268 | #: src/preferences/widgets/app_row.ts:54
269 | #, fuzzy
270 | msgid "Expand this row, to pick a window"
271 | msgstr "この行を展開しウィンドウを選択。"
272 |
273 | #: src/preferences/widgets/app_row.ts:94
274 | #, fuzzy
275 | msgid "Can't pick window from this position"
276 | msgstr "この位置からウィンドウを選択できません"
277 |
278 | #: src/preferences/widgets/custom_settings_row.ts:15
279 | #, fuzzy
280 | msgid "Enabled"
281 | msgstr "有効化"
282 |
283 | #: src/preferences/widgets/custom_settings_row.ts:47
284 | #, fuzzy
285 | msgid "Keep rounded corners when maximized"
286 | msgstr "最大化時に角丸を維持"
287 |
288 | #: src/preferences/widgets/custom_settings_row.ts:49
289 | #, fuzzy
290 | msgid "Always clip rounded corners even if window is maximized or tiled"
291 | msgstr "ウィンドウの最大化や並べて表示でも角丸を維持。"
292 |
293 | #: src/preferences/widgets/custom_settings_row.ts:53
294 | #, fuzzy
295 | msgid "Keep rounded corners when in fullscreen"
296 | msgstr "全画面時に角丸を維持"
297 |
298 | #: src/preferences/widgets/custom_settings_row.ts:54
299 | #, fuzzy
300 | msgid "Always clip rounded corners even for fullscreen window"
301 | msgstr "全画面時でも角丸を維持。"
302 |
303 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
304 | msgid "Rounded Corners Settings..."
305 | msgstr "角丸の設定..."
306 |
307 | #, fuzzy
308 | #~ msgid "Open prefereces reset page"
309 | #~ msgstr "設定初期化のダイアログを開く"
310 |
311 | #~ msgid "Skip LibAdwaita Applications"
312 | #~ msgstr "LibAdwaita のアプリは無視"
313 |
314 | #~ msgid "Skip LibHandy Applications"
315 | #~ msgstr "LibHandy のアプリは無視"
316 |
317 | #~ msgid "Border Width"
318 | #~ msgstr "境界線の幅"
319 |
320 | #~ msgid "Border Color"
321 | #~ msgstr "境界線の色"
322 |
323 | #~ msgid "Border Radius"
324 | #~ msgstr "境界線の角丸サイズ"
325 |
326 | #~ msgid "Keep Rounded Corners when Maximized or Fullscreen"
327 | #~ msgstr "最大化や全画面時に角丸を維持"
328 |
329 | #~ msgid "Corner Smoothing"
330 | #~ msgstr "角を滑らかに"
331 |
332 | #~ msgid "Expand this row to pick a window."
333 | #~ msgstr "この行を展開しウィンドウを選択。"
334 |
335 | #~ msgid ""
336 | #~ "Setup different clip padding by add window into this list.\n"
337 | #~ "\n"
338 | #~ "The item of list is instance part of WM_CLASS property with window. You "
339 | #~ "can pick a window to add it into this list."
340 | #~ msgstr ""
341 | #~ "この一覧にウィンドウを追加してそれぞれの clip padding を設定できます。\n"
342 | #~ "\n"
343 | #~ "一覧の項目は、ウィンドウの WM_CLASS プロパティのインスタンス部分です。一覧"
344 | #~ "にこれを追加するウィンドウを選択できます。"
345 |
346 | #~ msgid "Remove Window from this List"
347 | #~ msgstr "この一覧からウィドウを除去"
348 |
349 | #~ msgid "Pick Window to add into list"
350 | #~ msgstr "一覧に追加するウィンドウを選択"
351 |
352 | #~ msgid "Apply"
353 | #~ msgstr "適用"
354 |
355 | #~ msgid "Blur Offset"
356 | #~ msgstr "ぼかし補正"
357 |
358 | #~ msgid "Can't add to list, because it has exists"
359 | #~ msgstr "既に存在するため、一覧に追加できません"
360 |
361 | #~ msgid "Edit Shadow for Rounded Corners Windows"
362 | #~ msgstr "角丸ウィンドウの影を編集"
363 |
--------------------------------------------------------------------------------
/po/nb_NO.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Report-Msgid-Bugs-To: \n"
4 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
5 | "PO-Revision-Date: 2022-09-15 06:16+0000\n"
6 | "Last-Translator: Allan Nordhøy \n"
7 | "Language-Team: Norwegian Bokmål \n"
9 | "Language: nb_NO\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "Plural-Forms: nplurals=2; plural=n != 1;\n"
13 | "X-Generator: Weblate 4.14.1-dev\n"
14 |
15 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
16 | msgid "Blacklist"
17 | msgstr "Svarteliste"
18 |
19 | #: src/preferences/pages/blacklist.ui:11
20 | msgid ""
21 | "Not all application can works well with rounded corners effects, add them to "
22 | "this list to disable effects."
23 | msgstr ""
24 |
25 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
26 | #, fuzzy
27 | msgid "Add window"
28 | msgstr "Legg til vindu"
29 |
30 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
31 | msgid "Custom"
32 | msgstr ""
33 |
34 | #: src/preferences/pages/custom.ui:11
35 | msgid "Set custom effect setting for each window class"
36 | msgstr ""
37 |
38 | #: src/preferences/pages/edit-shadow.ui:6
39 | msgid "Edit shadows"
40 | msgstr ""
41 |
42 | #: src/preferences/pages/edit-shadow.ui:28
43 | msgid "Focused window"
44 | msgstr ""
45 |
46 | #: src/preferences/pages/edit-shadow.ui:43
47 | msgid "Unfocused window"
48 | msgstr ""
49 |
50 | #: src/preferences/pages/edit-shadow.ui:66
51 | msgid "Focused shadow prefrences"
52 | msgstr ""
53 |
54 | #: src/preferences/pages/edit-shadow.ui:69
55 | #: src/preferences/pages/edit-shadow.ui:209
56 | msgid "Horizontal offset"
57 | msgstr ""
58 |
59 | #: src/preferences/pages/edit-shadow.ui:96
60 | #: src/preferences/pages/edit-shadow.ui:236
61 | msgid "Vertical offset"
62 | msgstr ""
63 |
64 | #: src/preferences/pages/edit-shadow.ui:123
65 | #: src/preferences/pages/edit-shadow.ui:263
66 | msgid "Blur radius"
67 | msgstr ""
68 |
69 | #: src/preferences/pages/edit-shadow.ui:150
70 | #: src/preferences/pages/edit-shadow.ui:290
71 | msgid "Spread radius"
72 | msgstr ""
73 |
74 | #: src/preferences/pages/edit-shadow.ui:177
75 | #: src/preferences/pages/edit-shadow.ui:317
76 | msgid "Opacity"
77 | msgstr ""
78 |
79 | #: src/preferences/pages/edit-shadow.ui:206
80 | msgid "Unfocused shadow prefrences"
81 | msgstr ""
82 |
83 | #: src/preferences/pages/general.ui:6
84 | msgid "General"
85 | msgstr ""
86 |
87 | #: src/preferences/pages/general.ui:10
88 | msgid "Applications"
89 | msgstr "Programmer"
90 |
91 | #: src/preferences/pages/general.ui:11
92 | msgid ""
93 | "Some applications created with LibAdwaita or LibHandy already have rounded "
94 | "corners. You can enable those settings to avoid rounding their corners an "
95 | "extra time."
96 | msgstr ""
97 |
98 | #: src/preferences/pages/general.ui:14
99 | #, fuzzy
100 | msgid "Skip LibAdwaita applications"
101 | msgstr "Programmer"
102 |
103 | #: src/preferences/pages/general.ui:19
104 | msgid "Skip LibHandy applications"
105 | msgstr ""
106 |
107 | #: src/preferences/pages/general.ui:26
108 | msgid "Global settings"
109 | msgstr ""
110 |
111 | #: src/preferences/pages/general.ui:27
112 | msgid "These settings will have an effect on all windows"
113 | msgstr ""
114 |
115 | #: src/preferences/pages/general.ui:30
116 | msgid "Border width"
117 | msgstr ""
118 |
119 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
120 | #: src/preferences/widgets/custom_settings_row.ts:19
121 | msgid "Border color"
122 | msgstr ""
123 |
124 | #: src/preferences/pages/general.ui:74
125 | #: src/preferences/widgets/custom_settings_row.ts:27
126 | msgid "Corner radius"
127 | msgstr ""
128 |
129 | #: src/preferences/pages/general.ui:101
130 | #: src/preferences/widgets/custom_settings_row.ts:37
131 | msgid "Corner smoothing"
132 | msgstr ""
133 |
134 | #: src/preferences/pages/general.ui:127
135 | msgid "Window shadow"
136 | msgstr ""
137 |
138 | #: src/preferences/pages/general.ui:128
139 | msgid "Customize the shadow of the rounded corner window"
140 | msgstr ""
141 |
142 | #: src/preferences/pages/general.ui:140
143 | #, fuzzy
144 | msgid "Keep rounded corners for maximized windows"
145 | msgstr "Behold avrundede hjørner når vinduet er maksimert eller flislagt."
146 |
147 | #: src/preferences/pages/general.ui:145
148 | #, fuzzy
149 | msgid "Keep rounded corners for fullscreen windows"
150 | msgstr "Behold avrundede vinduer når vindu er i fullskjermsvisning."
151 |
152 | #: src/preferences/pages/general.ui:155
153 | msgid "Tweaks"
154 | msgstr ""
155 |
156 | #: src/preferences/pages/general.ui:158
157 | msgid "Add rounded corners to Kitty Terminal on Wayland"
158 | msgstr ""
159 |
160 | #: src/preferences/pages/general.ui:159
161 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
162 | msgstr ""
163 |
164 | #: src/preferences/pages/general.ui:164
165 | #, fuzzy
166 | msgid "Add a settings entry in right-click menu of the desktop"
167 | msgstr "Legg til innstillingsoppføring i høyreklikksmenyen for bakgrunn"
168 |
169 | #: src/preferences/pages/general.ui:171
170 | msgid "Debug"
171 | msgstr ""
172 |
173 | #: src/preferences/pages/general.ui:174
174 | msgid "Enable debug logs"
175 | msgstr ""
176 |
177 | #: src/preferences/pages/general.ui:175
178 | msgid ""
179 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
180 | msgstr ""
181 |
182 | #: src/preferences/pages/general.ui:184
183 | msgid "Reset preferences"
184 | msgstr ""
185 |
186 | #: src/preferences/pages/reset.ui:6
187 | msgid "Reset settings"
188 | msgstr ""
189 |
190 | #: src/preferences/pages/reset.ui:16
191 | msgid "Settings to reset"
192 | msgstr ""
193 |
194 | #: src/preferences/pages/reset.ui:22
195 | msgid "Select all"
196 | msgstr ""
197 |
198 | #: src/preferences/pages/reset.ui:39
199 | msgid "Reset"
200 | msgstr ""
201 |
202 | #: src/preferences/pages/reset.ui:55
203 | msgid "Reset these settings?"
204 | msgstr ""
205 |
206 | #: src/preferences/pages/reset.ui:60
207 | msgid "_Cancel"
208 | msgstr ""
209 |
210 | #: src/preferences/pages/reset.ui:61
211 | msgid "_Reset"
212 | msgstr ""
213 |
214 | #: src/preferences/widgets/paddings-row.ui:12
215 | msgid "Paddings"
216 | msgstr ""
217 |
218 | #: src/preferences/widgets/paddings-row.ui:25
219 | msgid "Top"
220 | msgstr ""
221 |
222 | #: src/preferences/widgets/paddings-row.ui:40
223 | msgid "Bottom"
224 | msgstr ""
225 |
226 | #: src/preferences/widgets/paddings-row.ui:55
227 | msgid "Left"
228 | msgstr ""
229 |
230 | #: src/preferences/widgets/paddings-row.ui:70
231 | msgid "Right"
232 | msgstr ""
233 |
234 | #: src/preferences/widgets/app_row.ts:33
235 | msgid "Window class"
236 | msgstr ""
237 |
238 | #: src/preferences/widgets/app_row.ts:54
239 | msgid "Expand this row, to pick a window"
240 | msgstr ""
241 |
242 | #: src/preferences/widgets/app_row.ts:94
243 | msgid "Can't pick window from this position"
244 | msgstr ""
245 |
246 | #: src/preferences/widgets/custom_settings_row.ts:15
247 | msgid "Enabled"
248 | msgstr ""
249 |
250 | #: src/preferences/widgets/custom_settings_row.ts:47
251 | #, fuzzy
252 | msgid "Keep rounded corners when maximized"
253 | msgstr "Behold avrundede hjørner når vinduet er maksimert eller flislagt."
254 |
255 | #: src/preferences/widgets/custom_settings_row.ts:49
256 | #, fuzzy
257 | msgid "Always clip rounded corners even if window is maximized or tiled"
258 | msgstr "Behold avrundede hjørner når vinduet er maksimert eller flislagt."
259 |
260 | #: src/preferences/widgets/custom_settings_row.ts:53
261 | #, fuzzy
262 | msgid "Keep rounded corners when in fullscreen"
263 | msgstr "Behold avrundede vinduer når vindu er i fullskjermsvisning."
264 |
265 | #: src/preferences/widgets/custom_settings_row.ts:54
266 | #, fuzzy
267 | msgid "Always clip rounded corners even for fullscreen window"
268 | msgstr "Behold avrundede vinduer når vindu er i fullskjermsvisning."
269 |
270 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
271 | msgid "Rounded Corners Settings..."
272 | msgstr ""
273 |
274 | #~ msgid "Apply"
275 | #~ msgstr "Bruk"
276 |
--------------------------------------------------------------------------------
/po/rounded-window-corners@fxgn.pot:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the PACKAGE package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: PACKAGE VERSION\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2025-01-31 09:07+0100\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=CHARSET\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
21 | msgid "Blacklist"
22 | msgstr ""
23 |
24 | #: src/preferences/pages/blacklist.ui:11
25 | msgid ""
26 | "Not all application can works well with rounded corners effects, add them to "
27 | "this list to disable effects."
28 | msgstr ""
29 |
30 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
31 | msgid "Add window"
32 | msgstr ""
33 |
34 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
35 | msgid "Custom"
36 | msgstr ""
37 |
38 | #: src/preferences/pages/custom.ui:11
39 | msgid "Set custom effect setting for each window class"
40 | msgstr ""
41 |
42 | #: src/preferences/pages/edit-shadow.ui:6
43 | msgid "Edit shadows"
44 | msgstr ""
45 |
46 | #: src/preferences/pages/edit-shadow.ui:28
47 | msgid "Focused window"
48 | msgstr ""
49 |
50 | #: src/preferences/pages/edit-shadow.ui:43
51 | msgid "Unfocused window"
52 | msgstr ""
53 |
54 | #: src/preferences/pages/edit-shadow.ui:66
55 | msgid "Focused shadow prefrences"
56 | msgstr ""
57 |
58 | #: src/preferences/pages/edit-shadow.ui:69
59 | #: src/preferences/pages/edit-shadow.ui:209
60 | msgid "Horizontal offset"
61 | msgstr ""
62 |
63 | #: src/preferences/pages/edit-shadow.ui:96
64 | #: src/preferences/pages/edit-shadow.ui:236
65 | msgid "Vertical offset"
66 | msgstr ""
67 |
68 | #: src/preferences/pages/edit-shadow.ui:123
69 | #: src/preferences/pages/edit-shadow.ui:263
70 | msgid "Blur radius"
71 | msgstr ""
72 |
73 | #: src/preferences/pages/edit-shadow.ui:150
74 | #: src/preferences/pages/edit-shadow.ui:290
75 | msgid "Spread radius"
76 | msgstr ""
77 |
78 | #: src/preferences/pages/edit-shadow.ui:177
79 | #: src/preferences/pages/edit-shadow.ui:317
80 | msgid "Opacity"
81 | msgstr ""
82 |
83 | #: src/preferences/pages/edit-shadow.ui:206
84 | msgid "Unfocused shadow prefrences"
85 | msgstr ""
86 |
87 | #: src/preferences/pages/general.ui:6
88 | msgid "General"
89 | msgstr ""
90 |
91 | #: src/preferences/pages/general.ui:10
92 | msgid "Applications"
93 | msgstr ""
94 |
95 | #: src/preferences/pages/general.ui:11
96 | msgid ""
97 | "Some applications created with LibAdwaita or LibHandy already have rounded "
98 | "corners. You can enable those settings to avoid rounding their corners an "
99 | "extra time."
100 | msgstr ""
101 |
102 | #: src/preferences/pages/general.ui:14
103 | msgid "Skip LibAdwaita applications"
104 | msgstr ""
105 |
106 | #: src/preferences/pages/general.ui:19
107 | msgid "Skip LibHandy applications"
108 | msgstr ""
109 |
110 | #: src/preferences/pages/general.ui:26
111 | msgid "Global settings"
112 | msgstr ""
113 |
114 | #: src/preferences/pages/general.ui:27
115 | msgid "These settings will have an effect on all windows"
116 | msgstr ""
117 |
118 | #: src/preferences/pages/general.ui:30
119 | msgid "Border width"
120 | msgstr ""
121 |
122 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
123 | #: src/preferences/widgets/custom_settings_row.ts:19
124 | msgid "Border color"
125 | msgstr ""
126 |
127 | #: src/preferences/pages/general.ui:74
128 | #: src/preferences/widgets/custom_settings_row.ts:27
129 | msgid "Corner radius"
130 | msgstr ""
131 |
132 | #: src/preferences/pages/general.ui:101
133 | #: src/preferences/widgets/custom_settings_row.ts:37
134 | msgid "Corner smoothing"
135 | msgstr ""
136 |
137 | #: src/preferences/pages/general.ui:127
138 | msgid "Window shadow"
139 | msgstr ""
140 |
141 | #: src/preferences/pages/general.ui:128
142 | msgid "Customize the shadow of the rounded corner window"
143 | msgstr ""
144 |
145 | #: src/preferences/pages/general.ui:140
146 | msgid "Keep rounded corners for maximized windows"
147 | msgstr ""
148 |
149 | #: src/preferences/pages/general.ui:145
150 | msgid "Keep rounded corners for fullscreen windows"
151 | msgstr ""
152 |
153 | #: src/preferences/pages/general.ui:155
154 | msgid "Tweaks"
155 | msgstr ""
156 |
157 | #: src/preferences/pages/general.ui:158
158 | msgid "Add rounded corners to Kitty Terminal on Wayland"
159 | msgstr ""
160 |
161 | #: src/preferences/pages/general.ui:159
162 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
163 | msgstr ""
164 |
165 | #: src/preferences/pages/general.ui:164
166 | msgid "Add a settings entry in right-click menu of the desktop"
167 | msgstr ""
168 |
169 | #: src/preferences/pages/general.ui:171
170 | msgid "Debug"
171 | msgstr ""
172 |
173 | #: src/preferences/pages/general.ui:174
174 | msgid "Enable debug logs"
175 | msgstr ""
176 |
177 | #: src/preferences/pages/general.ui:175
178 | msgid ""
179 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
180 | msgstr ""
181 |
182 | #: src/preferences/pages/general.ui:184
183 | msgid "Reset preferences"
184 | msgstr ""
185 |
186 | #: src/preferences/pages/reset.ui:6
187 | msgid "Reset settings"
188 | msgstr ""
189 |
190 | #: src/preferences/pages/reset.ui:16
191 | msgid "Settings to reset"
192 | msgstr ""
193 |
194 | #: src/preferences/pages/reset.ui:22
195 | msgid "Select all"
196 | msgstr ""
197 |
198 | #: src/preferences/pages/reset.ui:39
199 | msgid "Reset"
200 | msgstr ""
201 |
202 | #: src/preferences/pages/reset.ui:55
203 | msgid "Reset these settings?"
204 | msgstr ""
205 |
206 | #: src/preferences/pages/reset.ui:60
207 | msgid "_Cancel"
208 | msgstr ""
209 |
210 | #: src/preferences/pages/reset.ui:61
211 | msgid "_Reset"
212 | msgstr ""
213 |
214 | #: src/preferences/widgets/paddings-row.ui:12
215 | msgid "Paddings"
216 | msgstr ""
217 |
218 | #: src/preferences/widgets/paddings-row.ui:25
219 | msgid "Top"
220 | msgstr ""
221 |
222 | #: src/preferences/widgets/paddings-row.ui:40
223 | msgid "Bottom"
224 | msgstr ""
225 |
226 | #: src/preferences/widgets/paddings-row.ui:55
227 | msgid "Left"
228 | msgstr ""
229 |
230 | #: src/preferences/widgets/paddings-row.ui:70
231 | msgid "Right"
232 | msgstr ""
233 |
234 | #: src/preferences/widgets/app_row.ts:33
235 | msgid "Window class"
236 | msgstr ""
237 |
238 | #: src/preferences/widgets/app_row.ts:54
239 | msgid "Expand this row, to pick a window"
240 | msgstr ""
241 |
242 | #: src/preferences/widgets/app_row.ts:94
243 | msgid "Can't pick window from this position"
244 | msgstr ""
245 |
246 | #: src/preferences/widgets/custom_settings_row.ts:15
247 | msgid "Enabled"
248 | msgstr ""
249 |
250 | #: src/preferences/widgets/custom_settings_row.ts:47
251 | msgid "Keep rounded corners when maximized"
252 | msgstr ""
253 |
254 | #: src/preferences/widgets/custom_settings_row.ts:49
255 | msgid "Always clip rounded corners even if window is maximized or tiled"
256 | msgstr ""
257 |
258 | #: src/preferences/widgets/custom_settings_row.ts:53
259 | msgid "Keep rounded corners when in fullscreen"
260 | msgstr ""
261 |
262 | #: src/preferences/widgets/custom_settings_row.ts:54
263 | msgid "Always clip rounded corners even for fullscreen window"
264 | msgstr ""
265 |
266 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
267 | msgid "Rounded Corners Settings..."
268 | msgstr ""
269 |
--------------------------------------------------------------------------------
/po/zh_CN.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Report-Msgid-Bugs-To: \n"
4 | "POT-Creation-Date: 2025-01-14 10:38+0100\n"
5 | "PO-Revision-Date: 2023-03-02 12:35+0000\n"
6 | "Last-Translator: Yi \n"
7 | "Language-Team: Chinese (Simplified) \n"
9 | "Language: zh_CN\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "Plural-Forms: nplurals=1; plural=0;\n"
13 | "X-Generator: Weblate 4.16.2-dev\n"
14 |
15 | #: src/preferences/pages/blacklist.ui:6 src/preferences/pages/blacklist.ui:10
16 | msgid "Blacklist"
17 | msgstr "黑名单"
18 |
19 | #: src/preferences/pages/blacklist.ui:11
20 | #, fuzzy
21 | msgid ""
22 | "Not all application can works well with rounded corners effects, add them to "
23 | "this list to disable effects."
24 | msgstr ""
25 | "并非所有应用程序在使用圆角效果时都能够良好运行,可以将其添加到黑名单中以关闭"
26 | "圆角。\n"
27 | "\n"
28 | "每一项代表窗口的 WM_CLASS 属性,可以在添加窗口后选取窗口。"
29 |
30 | #: src/preferences/pages/blacklist.ui:19 src/preferences/pages/custom.ui:19
31 | #, fuzzy
32 | msgid "Add window"
33 | msgstr "添加窗口"
34 |
35 | #: src/preferences/pages/custom.ui:6 src/preferences/pages/custom.ui:10
36 | msgid "Custom"
37 | msgstr "自定义"
38 |
39 | #: src/preferences/pages/custom.ui:11
40 | #, fuzzy
41 | msgid "Set custom effect setting for each window class"
42 | msgstr "为窗口启用自定义的配置"
43 |
44 | #: src/preferences/pages/edit-shadow.ui:6
45 | msgid "Edit shadows"
46 | msgstr ""
47 |
48 | #: src/preferences/pages/edit-shadow.ui:28
49 | #, fuzzy
50 | msgid "Focused window"
51 | msgstr "已获取焦点的窗口"
52 |
53 | #: src/preferences/pages/edit-shadow.ui:43
54 | #, fuzzy
55 | msgid "Unfocused window"
56 | msgstr "未获取焦点的窗口"
57 |
58 | #: src/preferences/pages/edit-shadow.ui:66
59 | msgid "Focused shadow prefrences"
60 | msgstr ""
61 |
62 | #: src/preferences/pages/edit-shadow.ui:69
63 | #: src/preferences/pages/edit-shadow.ui:209
64 | #, fuzzy
65 | msgid "Horizontal offset"
66 | msgstr "水平偏移"
67 |
68 | #: src/preferences/pages/edit-shadow.ui:96
69 | #: src/preferences/pages/edit-shadow.ui:236
70 | #, fuzzy
71 | msgid "Vertical offset"
72 | msgstr "垂直偏移"
73 |
74 | #: src/preferences/pages/edit-shadow.ui:123
75 | #: src/preferences/pages/edit-shadow.ui:263
76 | #, fuzzy
77 | msgid "Blur radius"
78 | msgstr "圆角半径"
79 |
80 | #: src/preferences/pages/edit-shadow.ui:150
81 | #: src/preferences/pages/edit-shadow.ui:290
82 | #, fuzzy
83 | msgid "Spread radius"
84 | msgstr "扩散半径"
85 |
86 | #: src/preferences/pages/edit-shadow.ui:177
87 | #: src/preferences/pages/edit-shadow.ui:317
88 | msgid "Opacity"
89 | msgstr "透明度"
90 |
91 | #: src/preferences/pages/edit-shadow.ui:206
92 | msgid "Unfocused shadow prefrences"
93 | msgstr ""
94 |
95 | #: src/preferences/pages/general.ui:6
96 | msgid "General"
97 | msgstr "通用"
98 |
99 | #: src/preferences/pages/general.ui:10
100 | msgid "Applications"
101 | msgstr "应用设置"
102 |
103 | #: src/preferences/pages/general.ui:11
104 | #, fuzzy
105 | msgid ""
106 | "Some applications created with LibAdwaita or LibHandy already have rounded "
107 | "corners. You can enable those settings to avoid rounding their corners an "
108 | "extra time."
109 | msgstr ""
110 | "一些使用 LibAdwaita 与 LibHandy 编写的应用已经自带圆角,因此可以通过此选项跳"
111 | "过"
112 |
113 | #: src/preferences/pages/general.ui:14
114 | #, fuzzy
115 | msgid "Skip LibAdwaita applications"
116 | msgstr "跳过 LibAdwaita 应用"
117 |
118 | #: src/preferences/pages/general.ui:19
119 | #, fuzzy
120 | msgid "Skip LibHandy applications"
121 | msgstr "跳过 LibHandy 应用"
122 |
123 | #: src/preferences/pages/general.ui:26
124 | #, fuzzy
125 | msgid "Global settings"
126 | msgstr "全局设置"
127 |
128 | #: src/preferences/pages/general.ui:27
129 | #, fuzzy
130 | msgid "These settings will have an effect on all windows"
131 | msgstr "这里的设置将影响所有窗口"
132 |
133 | #: src/preferences/pages/general.ui:30
134 | #, fuzzy
135 | msgid "Border width"
136 | msgstr "边框大小"
137 |
138 | #: src/preferences/pages/general.ui:57 src/preferences/pages/general.ui:65
139 | #: src/preferences/widgets/custom_settings_row.ts:19
140 | #, fuzzy
141 | msgid "Border color"
142 | msgstr "边框颜色"
143 |
144 | #: src/preferences/pages/general.ui:74
145 | #: src/preferences/widgets/custom_settings_row.ts:27
146 | #, fuzzy
147 | msgid "Corner radius"
148 | msgstr "圆角半径"
149 |
150 | #: src/preferences/pages/general.ui:101
151 | #: src/preferences/widgets/custom_settings_row.ts:37
152 | #, fuzzy
153 | msgid "Corner smoothing"
154 | msgstr "圆角平滑程度"
155 |
156 | #: src/preferences/pages/general.ui:127
157 | #, fuzzy
158 | msgid "Window shadow"
159 | msgstr "窗口阴影"
160 |
161 | #: src/preferences/pages/general.ui:128
162 | msgid "Customize the shadow of the rounded corner window"
163 | msgstr "设置圆角窗口的阴影"
164 |
165 | #: src/preferences/pages/general.ui:140
166 | #, fuzzy
167 | msgid "Keep rounded corners for maximized windows"
168 | msgstr "最大化时保留圆角"
169 |
170 | #: src/preferences/pages/general.ui:145
171 | #, fuzzy
172 | msgid "Keep rounded corners for fullscreen windows"
173 | msgstr "窗口全屏时保留圆角"
174 |
175 | #: src/preferences/pages/general.ui:155
176 | msgid "Tweaks"
177 | msgstr "调整"
178 |
179 | #: src/preferences/pages/general.ui:158
180 | #, fuzzy
181 | msgid "Add rounded corners to Kitty Terminal on Wayland"
182 | msgstr "在 Wayland 下为 Kitty 终端添加圆角效果"
183 |
184 | #: src/preferences/pages/general.ui:159
185 | msgid "Adjust paddings for Kitty Terminal to correctly round its corners"
186 | msgstr ""
187 |
188 | #: src/preferences/pages/general.ui:164
189 | #, fuzzy
190 | msgid "Add a settings entry in right-click menu of the desktop"
191 | msgstr "将首选项入口添加到桌面背景的右键菜单"
192 |
193 | #: src/preferences/pages/general.ui:171
194 | msgid "Debug"
195 | msgstr "调试"
196 |
197 | #: src/preferences/pages/general.ui:174
198 | #, fuzzy
199 | msgid "Enable debug logs"
200 | msgstr "启用日志"
201 |
202 | #: src/preferences/pages/general.ui:175
203 | #, fuzzy
204 | msgid ""
205 | "Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log"
206 | msgstr ""
207 | "可以在终端里运行 journalctl -o cat -f /usr/bin/gnome-shell 来查看日志"
208 |
209 | #: src/preferences/pages/general.ui:184
210 | #, fuzzy
211 | msgid "Reset preferences"
212 | msgstr "重置设置"
213 |
214 | #: src/preferences/pages/reset.ui:6
215 | msgid "Reset settings"
216 | msgstr ""
217 |
218 | #: src/preferences/pages/reset.ui:16
219 | #, fuzzy
220 | msgid "Settings to reset"
221 | msgstr "选择要重置的设置"
222 |
223 | #: src/preferences/pages/reset.ui:22
224 | #, fuzzy
225 | msgid "Select all"
226 | msgstr "全选"
227 |
228 | #: src/preferences/pages/reset.ui:39
229 | msgid "Reset"
230 | msgstr ""
231 |
232 | #: src/preferences/pages/reset.ui:55
233 | msgid "Reset these settings?"
234 | msgstr ""
235 |
236 | #: src/preferences/pages/reset.ui:60
237 | msgid "_Cancel"
238 | msgstr ""
239 |
240 | #: src/preferences/pages/reset.ui:61
241 | msgid "_Reset"
242 | msgstr ""
243 |
244 | #: src/preferences/widgets/paddings-row.ui:12
245 | msgid "Paddings"
246 | msgstr "剪裁距离"
247 |
248 | #: src/preferences/widgets/paddings-row.ui:25
249 | msgid "Top"
250 | msgstr "上边距"
251 |
252 | #: src/preferences/widgets/paddings-row.ui:40
253 | msgid "Bottom"
254 | msgstr "下边距"
255 |
256 | #: src/preferences/widgets/paddings-row.ui:55
257 | msgid "Left"
258 | msgstr "左边距"
259 |
260 | #: src/preferences/widgets/paddings-row.ui:70
261 | msgid "Right"
262 | msgstr "右边距"
263 |
264 | #: src/preferences/widgets/app_row.ts:33
265 | #, fuzzy
266 | msgid "Window class"
267 | msgstr "窗口阴影"
268 |
269 | #: src/preferences/widgets/app_row.ts:54
270 | #, fuzzy
271 | msgid "Expand this row, to pick a window"
272 | msgstr "展开此控件以选取窗口。"
273 |
274 | #: src/preferences/widgets/app_row.ts:94
275 | #, fuzzy
276 | msgid "Can't pick window from this position"
277 | msgstr "无法从此位置选取窗口"
278 |
279 | #: src/preferences/widgets/custom_settings_row.ts:15
280 | #, fuzzy
281 | msgid "Enabled"
282 | msgstr "启用"
283 |
284 | #: src/preferences/widgets/custom_settings_row.ts:47
285 | #, fuzzy
286 | msgid "Keep rounded corners when maximized"
287 | msgstr "最大化时保留圆角"
288 |
289 | #: src/preferences/widgets/custom_settings_row.ts:49
290 | #, fuzzy
291 | msgid "Always clip rounded corners even if window is maximized or tiled"
292 | msgstr "窗口最大化或垂直平铺时保留圆角。"
293 |
294 | #: src/preferences/widgets/custom_settings_row.ts:53
295 | #, fuzzy
296 | msgid "Keep rounded corners when in fullscreen"
297 | msgstr "窗口全屏时保留圆角"
298 |
299 | #: src/preferences/widgets/custom_settings_row.ts:54
300 | #, fuzzy
301 | msgid "Always clip rounded corners even for fullscreen window"
302 | msgstr "当窗口全屏时保留圆角效果。"
303 |
304 | #: src/utils/background_menu.ts:49 src/utils/background_menu.ts:74
305 | msgid "Rounded Corners Settings..."
306 | msgstr "圆角设置…"
307 |
308 | #~ msgid "Tweak clip paddings for Kitty Terminal"
309 | #~ msgstr "调整 Kitty 终端的剪裁半径"
310 |
311 | #, fuzzy
312 | #~ msgid "Open prefereces reset page"
313 | #~ msgstr "打开重置对话框"
314 |
315 | #~ msgid "Skip LibAdwaita Applications"
316 | #~ msgstr "跳过 LibAdwaita 应用"
317 |
318 | #~ msgid "Skip LibHandy Applications"
319 | #~ msgstr "跳过 LibHandy 应用"
320 |
321 | #~ msgid "Focus Window Shadow Style"
322 | #~ msgstr "已获取焦点窗口阴影"
323 |
324 | #~ msgid "Unfocus Window Shadow Style"
325 | #~ msgstr "未获取焦点窗口阴影"
326 |
327 | #~ msgid "Border Width"
328 | #~ msgstr "边框大小"
329 |
330 | #~ msgid "Border Color"
331 | #~ msgstr "边框颜色"
332 |
333 | #~ msgid "Border Radius"
334 | #~ msgstr "圆角半径"
335 |
336 | #~ msgid "Padding"
337 | #~ msgstr "剪裁边距"
338 |
339 | #~ msgid "Keep Rounded Corners when Maximized or Fullscreen"
340 | #~ msgstr "在窗口最大化或全屏时保留圆角"
341 |
342 | #~ msgid "Corner Smoothing"
343 | #~ msgstr "圆角平滑程度"
344 |
345 | #~ msgid "Expand this row to pick a window."
346 | #~ msgstr "展开此控件以选取窗口。"
347 |
348 | #~ msgid ""
349 | #~ "Setup different clip padding by add window into this list.\n"
350 | #~ "\n"
351 | #~ "The item of list is instance part of WM_CLASS property with window. You "
352 | #~ "can pick a window to add it into this list."
353 | #~ msgstr ""
354 | #~ "将窗口添加到此列表可以自定义圆角的裁剪距离。\n"
355 | #~ "\n"
356 | #~ "每一项代表窗口的 WM_CLASS 属性,可以在添加窗口后选取窗口。"
357 |
358 | #~ msgid "Remove Window from this List"
359 | #~ msgstr "从列表移除"
360 |
361 | #~ msgid "Pick Window to add into list"
362 | #~ msgstr "选取窗口"
363 |
364 | #~ msgid "Apply"
365 | #~ msgstr "应用"
366 |
367 | #~ msgid "Blur Offset"
368 | #~ msgstr "模糊半径"
369 |
370 | #~ msgid "Clip paddings of window"
371 | #~ msgstr "设置窗口的剪裁距离"
372 |
373 | #~ msgid "Can't add to list, because it has exists"
374 | #~ msgstr "已在列表中,无法添加"
375 |
376 | #~ msgid "Edit Shadow for Rounded Corners Windows"
377 | #~ msgstr "编辑圆角窗口阴影"
378 |
--------------------------------------------------------------------------------
/resources/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Rounded Window Corners Reborn",
3 | "description": "Add rounded corners to all windows. Fork of the now unmaintained Rounded Window Corners extension.",
4 | "uuid": "rounded-window-corners@fxgn",
5 | "url": "https://github.com/flexagoon/rounded-window-corners",
6 | "gettext-domain": "rounded-window-corners@fxgn",
7 | "settings-schema": "org.gnome.shell.extensions.rounded-window-corners-reborn",
8 | "shell-version": ["46", "47", "48"]
9 | }
10 |
--------------------------------------------------------------------------------
/resources/schemas/org.gnome.shell.extensions.rounded-window-corners-reborn.gschema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 | 0
11 |
12 |
13 |
14 | []
15 | window here will not be rounded
16 |
17 | The contents of the list represent the instance part of the window's
18 | `WM_CLASS`, as same as the output of `xprop WM_CLASS|cut -d \" -f 2`
19 |
20 |
21 |
22 |
23 | Skip Libadwaita applications
24 | true
25 |
26 |
27 |
28 | Skip LibHandy applications
29 | false
30 |
31 |
32 |
33 | Border width for rounded corners window
34 |
35 | 0
36 |
37 |
38 |
39 | Global rounded corners settings for all windows
40 |
41 |
46 | {
47 | 'padding': <{
48 | 'left': <uint32 1>,
49 | 'right': <uint32 1>,
50 | 'top': <uint32 1>,
51 | 'bottom': <uint32 1>
52 | }>,
53 | 'keepRoundedCorners': <{
54 | 'maximized': <false>,
55 | 'fullscreen': <false>
56 | }>,
57 | 'borderRadius': <uint32 12>,
58 | 'smoothing': <0>,
59 | 'borderColor': <[0.5, 0.5, 0.5, 1.0]>,
60 | 'enabled': <true>
61 | }
62 |
63 |
64 |
65 |
66 | A directory to setup custom paddings for special windows
67 | {}
68 |
69 |
70 |
71 |
72 | Shadow for focused window
73 |
74 | {
75 | 'horizontalOffset': 0,
76 | 'verticalOffset': 4,
77 | 'blurOffset': 28,
78 | 'spreadRadius': 4,
79 | 'opacity': 60
80 | }
81 |
82 |
83 |
84 |
85 | Shadow for unfocused window
86 |
87 | {
88 | 'horizontalOffset': 0,
89 | 'verticalOffset': 2,
90 | 'blurOffset': 12,
91 | 'spreadRadius': -1,
92 | 'opacity': 65
93 | }
94 |
95 |
96 |
97 |
98 | If enabled, extension will show debug info into journalctl
99 | false
100 |
101 |
102 |
103 | false
104 |
105 |
106 |
107 | false
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/resources/stylesheet-prefs.css:
--------------------------------------------------------------------------------
1 | .page {
2 | padding: 10px 30px;
3 | }
4 |
5 | .code {
6 | padding: 10px 16px;
7 | }
8 |
9 | .edit-win {
10 | background: #eeeeee;
11 | color: black;
12 | padding: 20px 80px;
13 | }
14 |
15 | .flat {
16 | background: none;
17 | border: none;
18 | }
19 |
20 | .expander_img {
21 | transition: all 100ms;
22 | }
23 |
24 | .rotated {
25 | transform: rotate(90deg);
26 | }
27 |
28 | .dialog-vbox {
29 | padding: 48px;
30 | }
31 |
32 | .dialog-vbox .heading {
33 | padding-bottom: 24px;
34 | }
35 |
36 | .dialog-vbox checkbutton {
37 | padding-right: 12px;
38 | }
39 |
--------------------------------------------------------------------------------
/resources/stylesheet.css:
--------------------------------------------------------------------------------
1 | .shadow {
2 | box-shadow: 0px 0px 0px 0px rgba(83, 83, 83, 0.0);
3 | transition-duration: 300ms;
4 | transition-property: box-shadow;
5 | transition-timing-function: linear;
6 | }
7 |
--------------------------------------------------------------------------------
/src/effect/README.md:
--------------------------------------------------------------------------------
1 | # `effect`
2 |
3 | This directory contains the code for applying GLSL effects to windows.
4 |
5 | ## `clip_shadow_effect.ts`
6 |
7 | Due to a bug in GNOME, window shadows are drawn behind window contents. This
8 | effect loads a simple Fragment shader that clips the shadow behind the window.
9 |
10 | ## `linear_filter_effect.ts`
11 |
12 | This effect applies linear interpolation to the window, which makes windows
13 | in the overview look less blurry.
14 |
15 | ## `rounded_corners_effect.ts`
16 |
17 | This effect loads the actual Fragment shader that rounds the corners and draws
18 | custom borders for the window. The class applies the effect and provides a
19 | function to change uniforms passed to the effect.
20 |
21 | ## `shader`
22 |
23 | This is the directory where the Fragment shaders are stored.
24 |
25 | If you're interested in implementation details of the shader, you can read the
26 | `shader/rounded_corners.frag` file, which is well commented and explains how
27 | it works in great detail.
28 |
--------------------------------------------------------------------------------
/src/effect/clip_shadow_effect.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Clips shadows for windows.
3 | *
4 | * Needed because of this issue:
5 | * https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4474
6 | */
7 |
8 | import Cogl from 'gi://Cogl';
9 | import GObject from 'gi://GObject';
10 | import Shell from 'gi://Shell';
11 |
12 | import {readShader} from '../utils/file.js';
13 |
14 | const [declarations, code] = readShader(
15 | import.meta.url,
16 | 'shader/clip_shadow.frag',
17 | );
18 |
19 | export const ClipShadowEffect = GObject.registerClass(
20 | {},
21 | class extends Shell.GLSLEffect {
22 | vfunc_build_pipeline() {
23 | this.add_glsl_snippet(
24 | Cogl.SnippetHook.FRAGMENT,
25 | declarations,
26 | code,
27 | false,
28 | );
29 | }
30 | },
31 | );
32 |
--------------------------------------------------------------------------------
/src/effect/linear_filter_effect.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Applies linear interpolation to a window. This is used to make windows
3 | * in the overview look better.
4 | */
5 |
6 | import Cogl from 'gi://Cogl';
7 | import GObject from 'gi://GObject';
8 | import Shell from 'gi://Shell';
9 |
10 | import type Clutter from 'gi://Clutter';
11 |
12 | export const LinearFilterEffect = GObject.registerClass(
13 | {},
14 | class extends Shell.GLSLEffect {
15 | vfunc_build_pipeline(): void {
16 | this.add_glsl_snippet(Cogl.SnippetHook.FRAGMENT, '', '', false);
17 | }
18 |
19 | vfunc_paint_target(
20 | node: Clutter.PaintNode,
21 | ctx: Clutter.PaintContext,
22 | ): void {
23 | this.get_pipeline()?.set_layer_filters(
24 | 0,
25 | Cogl.PipelineFilter.LINEAR_MIPMAP_LINEAR,
26 | Cogl.PipelineFilter.LINEAR,
27 | );
28 | super.vfunc_paint_target(node, ctx);
29 | }
30 | },
31 | );
32 |
--------------------------------------------------------------------------------
/src/effect/rounded_corners_effect.ts:
--------------------------------------------------------------------------------
1 | /** @file Binds the actual corner rounding shader to the windows. */
2 |
3 | import Cogl from 'gi://Cogl';
4 | import GObject from 'gi://GObject';
5 | import Shell from 'gi://Shell';
6 |
7 | import {readShader} from '../utils/file.js';
8 | import {getPref} from '../utils/settings.js';
9 |
10 | import type {Bounds, RoundedCornerSettings} from '../utils/types.js';
11 |
12 | const [declarations, code] = readShader(
13 | import.meta.url,
14 | 'shader/rounded_corners.frag',
15 | );
16 |
17 | class Uniforms {
18 | bounds = 0;
19 | clipRadius = 0;
20 | borderWidth = 0;
21 | borderColor = 0;
22 | borderedAreaBounds = 0;
23 | borderedAreaClipRadius = 0;
24 | exponent = 0;
25 | pixelStep = 0;
26 | }
27 |
28 | export const RoundedCornersEffect = GObject.registerClass(
29 | {},
30 | class Effect extends Shell.GLSLEffect {
31 | /**
32 | * To store a uniform value, we need to know its location in the shader,
33 | * which is done by calling `this.get_uniform_location()`. This is
34 | * expensive, so we cache the location of uniforms when the shader is
35 | * created.
36 | */
37 | static uniforms: Uniforms = new Uniforms();
38 |
39 | constructor() {
40 | super();
41 |
42 | for (const k in Effect.uniforms) {
43 | Effect.uniforms[k as keyof Uniforms] =
44 | this.get_uniform_location(k);
45 | }
46 | }
47 |
48 | vfunc_build_pipeline() {
49 | this.add_glsl_snippet(
50 | Cogl.SnippetHook.FRAGMENT,
51 | declarations,
52 | code,
53 | false,
54 | );
55 | }
56 |
57 | /**
58 | * Update uniforms of the shader.
59 | * For more information, see the comments in the shader file.
60 | *
61 | * @param scaleFactor - Desktop scaling factor
62 | * @param config - Rounded corners configuration
63 | * @param windowBounds - Bounds of the window without padding
64 | */
65 | updateUniforms(
66 | scaleFactor: number,
67 | config: RoundedCornerSettings,
68 | windowBounds: Bounds,
69 | ) {
70 | const borderWidth = getPref('border-width') * scaleFactor;
71 | const borderColor = config.borderColor;
72 |
73 | const outerRadius = config.borderRadius * scaleFactor;
74 | const {padding, smoothing} = config;
75 |
76 | const bounds = [
77 | windowBounds.x1 + padding.left * scaleFactor,
78 | windowBounds.y1 + padding.top * scaleFactor,
79 | windowBounds.x2 - padding.right * scaleFactor,
80 | windowBounds.y2 - padding.bottom * scaleFactor,
81 | ];
82 |
83 | const borderedAreaBounds = [
84 | bounds[0] + borderWidth,
85 | bounds[1] + borderWidth,
86 | bounds[2] - borderWidth,
87 | bounds[3] - borderWidth,
88 | ];
89 |
90 | let borderedAreaRadius = outerRadius - borderWidth;
91 | if (borderedAreaRadius < 0.001) {
92 | borderedAreaRadius = 0.0;
93 | }
94 |
95 | const pixelStep = [
96 | 1 / this.actor.get_width(),
97 | 1 / this.actor.get_height(),
98 | ];
99 |
100 | // This is needed for squircle corners
101 | let exponent = smoothing * 10 + 2;
102 | let radius = outerRadius * 0.5 * exponent;
103 | const maxRadius = Math.min(
104 | bounds[3] - bounds[0],
105 | bounds[4] - bounds[1],
106 | );
107 | if (radius > maxRadius) {
108 | exponent *= maxRadius / radius;
109 | radius = maxRadius;
110 | }
111 | borderedAreaRadius *= radius / outerRadius;
112 |
113 | this.#setUniforms(
114 | bounds,
115 | radius,
116 | borderWidth,
117 | borderColor,
118 | borderedAreaBounds,
119 | borderedAreaRadius,
120 | pixelStep,
121 | exponent,
122 | );
123 | }
124 |
125 | #setUniforms(
126 | bounds: number[],
127 | radius: number,
128 | borderWidth: number,
129 | borderColor: [number, number, number, number],
130 | borderedAreaBounds: number[],
131 | borderedAreaRadius: number,
132 | pixelStep: number[],
133 | exponent: number,
134 | ) {
135 | const uniforms = Effect.uniforms;
136 | this.set_uniform_float(uniforms.bounds, 4, bounds);
137 | this.set_uniform_float(uniforms.clipRadius, 1, [radius]);
138 | this.set_uniform_float(uniforms.borderWidth, 1, [borderWidth]);
139 | this.set_uniform_float(uniforms.borderColor, 4, borderColor);
140 | this.set_uniform_float(
141 | uniforms.borderedAreaBounds,
142 | 4,
143 | borderedAreaBounds,
144 | );
145 | this.set_uniform_float(uniforms.borderedAreaClipRadius, 1, [
146 | borderedAreaRadius,
147 | ]);
148 | this.set_uniform_float(uniforms.pixelStep, 2, pixelStep);
149 | this.set_uniform_float(uniforms.exponent, 1, [exponent]);
150 | this.queue_repaint();
151 | }
152 | },
153 | );
154 |
--------------------------------------------------------------------------------
/src/effect/shader/clip_shadow.frag:
--------------------------------------------------------------------------------
1 | // Clip shadows to avoid showing them behind the window contents.
2 | void main() {
3 | vec4 color = cogl_color_out;
4 | float gray = (color.r + color.g + color.b) / 3.0;
5 | cogl_color_out *= (1.0 - smoothstep(0.4, 1.0, gray)) * color.a;
6 | }
7 |
--------------------------------------------------------------------------------
/src/effect/shader/rounded_corners.frag:
--------------------------------------------------------------------------------
1 | // Based on this shader from Mutter:
2 | // https://gitlab.gnome.org/GNOME/mutter/-/blob/main/src/compositor/meta-background-content.c
3 |
4 | // This shader is what actually does the most important part of the extension -
5 | // corner rounding.
6 | //
7 | // The way Fragment shaders work in GNOME is that they receive the information
8 | // about a point on the screen, process it in some way, and set the `cogl_color_out`
9 | // variable which indicates what color should be drawn to the screen at that
10 | // point.
11 | //
12 | // Corner rounding is works by doing a bunch of simple calculations on
13 | // the point coordinates to determine if the point lies within the visible part
14 | // of the window, and making it invisible (multiplying `cogl_color_out` by 0)
15 | // if it's not.
16 |
17 | // First, we declare our uniforms.
18 | // Uniforms are parameters that are passed to the shader from external code.
19 |
20 | // Bounds of the window as {x, y, z, w}:
21 | // x - left
22 | // y - top
23 | // z - right
24 | // w - bottom
25 | uniform vec4 bounds;
26 |
27 | // The border radius of the corner clipping.
28 | uniform float clipRadius;
29 |
30 | // Width and color of the border
31 | uniform float borderWidth;
32 | uniform vec4 borderColor;
33 |
34 | // Bounds and clip radius of the area inside of borders.
35 | // When using inner borders, this is the smaller window area within those borders.
36 | // With outer borders, this is the total area of the window together with them.
37 | uniform vec4 borderedAreaBounds;
38 | uniform float borderedAreaClipRadius;
39 |
40 | // Exponent to use for squircle corners
41 | uniform float exponent;
42 |
43 | // I'm acually not sure what this does, but it's used in the original Mutter code :)
44 | // It seems like this is needed to convert between texture coordinates and pixel
45 | // coordinates, but I'm not sure.
46 | uniform vec2 pixelStep;
47 |
48 | // Calculate whether a point is within the rounded window when using regular
49 | // circular corner rounding.
50 | //
51 | // p | The point
52 | // center | The center of the circle used for border rounding
53 | // clipRadius | Border radius
54 | float circleBounds(vec2 p, vec2 center, float clipRadius) {
55 | // Get the distance from the circle center to the point
56 | vec2 delta = p - center;
57 | float distSquared = dot(delta, delta);
58 |
59 | // If the distance is larger than the border radius, the point is outside
60 | // of the rounded corner, and should be invisible.
61 | float outerRadius = clipRadius + 0.5;
62 | if (distSquared >= (outerRadius * outerRadius))
63 | return 0.0;
64 |
65 | // Likewise, if it is smaller, the point is inside of the window.
66 | float borderedAreaRadius = clipRadius - 0.5;
67 | if (distSquared <= (borderedAreaRadius * borderedAreaRadius))
68 | return 1.0;
69 |
70 | // If the difference between border radius and the distance is less than
71 | // 0.5, the point is located on the edge of the window, and should be
72 | // antialiased.
73 | //
74 | // Taking a square root is computationally expensive, so this is avoided as
75 | // much as possible.
76 | return outerRadius - sqrt(distSquared);
77 | }
78 |
79 | // Calculate whether a point is within the rounded window when using squircle
80 | // corner rounding.
81 | //
82 | // A squircle is what's called a "superellipse", which is defined by this formula:
83 | // (|x|^n + |y|^n)^(1/n)
84 | //
85 | // p | The point
86 | // center | The center of the circle used for border rounding
87 | // clipRadius | Border radius
88 | // exponent | The exponent (n) of the superellipse
89 | float squircleBounds(vec2 p, vec2 center, float clipRadius, float exponent) {
90 | // Get the distances from the circle center to the point (|x|, |y|)
91 | vec2 delta = abs(p - center);
92 |
93 | // Raise the distances to the given power (|x|^n, |y|^n)
94 | float powDx = pow(delta.x, exponent);
95 | float powDy = pow(delta.y, exponent);
96 |
97 | // Calculate the end result of the formula (|x|^n + |y|^n)^(1/n)
98 | float dist = pow(powDx + powDy, 1.0 / exponent);
99 |
100 | // Calculate the opacity for the point and normalize it between 0 and 1
101 | return clamp(clipRadius - dist + 0.5, 0.0, 1.0);
102 | }
103 |
104 | // Calculate the correct opacity for a given point within the window.
105 | //
106 | // p | The point
107 | // bounds | The bounds of the window
108 | // clipRadius | Border radius
109 | // exponent | The exponent (smoothness) of the squircle corners.
110 | // | See `squircleBounds` for more information.
111 | float getPointOpacity(vec2 p, vec4 bounds, float clipRadius, float exponent) {
112 | // If the point is completely outside of the window bounds, it should
113 | // obviously not be visible.
114 | if (p.x < bounds.x || p.x > bounds.z || p.y < bounds.y || p.y > bounds.w)
115 | return 0.0;
116 |
117 | // This is the center of the circle that is used for corner rounding.
118 | vec2 center;
119 |
120 | // First, we find the centers of the circles on the horizontal axis.
121 | // `centerLeft` is for two corners on the left of the window, and
122 | // `centerRight` is for corners on the right.
123 | float centerLeft = bounds.x + clipRadius;
124 | float centerRight = bounds.z - clipRadius;
125 |
126 | // If the point is closer to the window border than the circle center, it
127 | // has a chance of being within the rounded area, so we store the center
128 | // x position and continue. If it's not, then it should always be visible
129 | // and we can return 1.0 early to avoid extra computation (this is the case
130 | // for the vast majority of points).
131 | if (p.x < centerLeft)
132 | center.x = centerLeft;
133 | else if (p.x > centerRight)
134 | center.x = centerRight;
135 | else
136 | return 1.0;
137 |
138 | // Now we do the same, but for the vertical coordinate of the center.
139 | float centerTop = bounds.y + clipRadius;
140 | float centerBottom = bounds.w - clipRadius;
141 |
142 | if (p.y < centerTop)
143 | center.y = centerTop;
144 | else if (p.y > centerBottom)
145 | center.y = centerBottom;
146 | else
147 | return 1.0;
148 |
149 | // If the exponent is set, apply squircle bounds, otherwise use regular
150 | // circular ones.
151 | if (exponent <= 2.0)
152 | return circleBounds(p, center, clipRadius);
153 | else
154 | return squircleBounds(p, center, clipRadius, exponent);
155 | }
156 |
157 | // This is the main function of the shader. It's what is actually being called
158 | // when rendering a point to the screen. It has no return value; as explained
159 | // at the beginning of the file, the `cogl_color_out` variable is used to set
160 | // the point color.
161 | void main() {
162 | vec2 p = cogl_tex_coord0_in.xy / pixelStep;
163 |
164 | float pointAlpha = getPointOpacity(p, bounds, clipRadius, exponent);
165 |
166 | if (borderWidth > 0.9 || borderWidth < -0.9) {
167 | // If there is a border, we have to paint it.
168 |
169 | // Calculate if the point lies within the bordered area (see the
170 | // `borderedAreaBounds` uniform for an explanation of what this means)
171 | float borderedAreaAlpha = getPointOpacity(p, borderedAreaBounds, borderedAreaClipRadius, exponent);
172 |
173 | if (borderWidth > 0.0) {
174 | // Inner borders
175 |
176 | // Clip points that are not inside of the window
177 | cogl_color_out *= pointAlpha;
178 | // Calculate if the point is located on the border itself
179 | float borderAlpha = clamp(abs(pointAlpha - borderedAreaAlpha), 0.0, 1.0);
180 | // Then, mix the window color and the border color
181 | cogl_color_out = mix(cogl_color_out, vec4(borderColor.rgb, 1.0), borderAlpha * borderColor.a);
182 | } else {
183 | // Outer borders
184 |
185 | // If the point is within the bordered area, paint it with the
186 | // border color
187 | vec4 borderRect = vec4(borderColor.rgb, 1.0) * borderedAreaAlpha * borderColor.a;
188 | // Then, if the point is also inside of the actual window
189 | // (pointAlpha = 1), draw the correct window pixel on top
190 | cogl_color_out = mix(borderRect, cogl_color_out, pointAlpha);
191 | }
192 | } else {
193 | // If there's no border, just multiply the output color by the calculated
194 | // alpha value.
195 | cogl_color_out *= pointAlpha;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Extension,
3 | InjectionManager,
4 | } from 'resource:///org/gnome/shell/extensions/extension.js';
5 | import {layoutManager} from 'resource:///org/gnome/shell/ui/main.js';
6 | import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js';
7 | import {WorkspaceAnimationController} from 'resource:///org/gnome/shell/ui/workspaceAnimation.js';
8 | import {disableEffect, enableEffect} from './manager/event_manager.js';
9 | import {addShadowInOverview} from './patch/add_shadow_in_overview.js';
10 | import {
11 | addShadowsInWorkspaceSwitch,
12 | removeShadowsAfterWorkspaceSwitch,
13 | } from './patch/workspace_switch.js';
14 | import {
15 | disableBackgroundMenuItem,
16 | enableBackgroundMenuItem,
17 | } from './utils/background_menu.js';
18 | import {logDebug} from './utils/log.js';
19 | import {getPref, initPrefs, prefs, uninitPrefs} from './utils/settings.js';
20 | import {WindowPicker} from './window_picker/service.js';
21 |
22 | import type GObject from 'gi://GObject';
23 | import type Gio from 'gi://Gio';
24 |
25 | export default class RoundedWindowCornersReborn extends Extension {
26 | // The extension works by overriding (monkey patching) the code of GNOME
27 | // Shell's internal methods. InjectionManager is a convenience class that
28 | // stores references to the original methods and allows to easily restore
29 | // them when the extension is disabled.
30 | #injectionManager: InjectionManager | null = null;
31 |
32 | #windowPicker: WindowPicker | null = null;
33 |
34 | #layoutManagerStartupConnection: number | null = null;
35 | #workspaceSwitchConnections: {object: GObject.Object; id: number}[] | null =
36 | null;
37 |
38 | enable() {
39 | // Initialize extension preferences
40 | initPrefs(this.getSettings());
41 |
42 | this.#injectionManager = new InjectionManager();
43 |
44 | // Export the d-bus interface of the window picker in preferences.
45 | // See the readme in the `window_picker` directory for more information.
46 | this.#windowPicker = new WindowPicker();
47 | this.#windowPicker.export();
48 |
49 | if (layoutManager._startingUp) {
50 | // Wait for GNOME Shell to be ready before enabling rounded corners
51 | this.#layoutManagerStartupConnection = layoutManager.connect(
52 | 'startup-complete',
53 | () => {
54 | enableEffect();
55 |
56 | if (getPref('enable-preferences-entry')) {
57 | enableBackgroundMenuItem();
58 | }
59 |
60 | layoutManager.disconnect(
61 | // Since this happens inside of the connection, there
62 | // is no way for this to be null.
63 | // biome-ignore lint/style/noNonNullAssertion:
64 | this.#layoutManagerStartupConnection!,
65 | );
66 | },
67 | );
68 | } else {
69 | enableEffect();
70 |
71 | if (getPref('enable-preferences-entry')) {
72 | enableBackgroundMenuItem();
73 | }
74 | }
75 |
76 | const self = this;
77 |
78 | // WindowPreview is a widget that shows a window in the overview.
79 | // We need to override its `_addWindow` method to add a shadow actor
80 | // to the preview, otherwise overview windows won't have custom
81 | // shadows.
82 | this.#injectionManager.overrideMethod(
83 | WindowPreview.prototype,
84 | '_addWindow',
85 | addWindow =>
86 | function (window) {
87 | addWindow.call(this, window);
88 | addShadowInOverview(window, this);
89 | },
90 | );
91 |
92 | // The same way we applied a cloned shadow actor to window previews in
93 | // the overview, we also need to apply it to windows during workspace
94 | // switching.
95 | this.#injectionManager.overrideMethod(
96 | WorkspaceAnimationController.prototype,
97 | '_prepareWorkspaceSwitch',
98 | prepareWorkspaceSwitch =>
99 | function (workspaceIndices) {
100 | prepareWorkspaceSwitch.call(this, workspaceIndices);
101 | self.#workspaceSwitchConnections =
102 | addShadowsInWorkspaceSwitch(this);
103 | },
104 | );
105 | this.#injectionManager.overrideMethod(
106 | WorkspaceAnimationController.prototype,
107 | '_finishWorkspaceSwitch',
108 | finishWorkspaceSwitch =>
109 | function (switchData) {
110 | removeShadowsAfterWorkspaceSwitch(this);
111 | finishWorkspaceSwitch.call(this, switchData);
112 | },
113 | );
114 |
115 | // Watch for changes of the `enable-preferences-entry` prefs key.
116 | prefs.connect('changed', (_: Gio.Settings, key: string) => {
117 | if (key === 'enable-preferences-entry') {
118 | getPref('enable-preferences-entry')
119 | ? enableBackgroundMenuItem()
120 | : disableBackgroundMenuItem();
121 | }
122 | });
123 |
124 | logDebug('Enabled');
125 | }
126 |
127 | disable() {
128 | // Restore patched methods
129 | this.#injectionManager?.clear();
130 | this.#injectionManager = null;
131 |
132 | // Remove the item to open preferences page in background menu
133 | disableBackgroundMenuItem();
134 |
135 | this.#windowPicker?.unexport();
136 | disableEffect();
137 |
138 | // Set all props to null
139 | this.#windowPicker = null;
140 |
141 | if (this.#layoutManagerStartupConnection !== null) {
142 | layoutManager.disconnect(this.#layoutManagerStartupConnection);
143 | this.#layoutManagerStartupConnection = null;
144 | }
145 |
146 | for (const connection of this.#workspaceSwitchConnections ?? []) {
147 | connection.object.disconnect(connection.id);
148 | }
149 |
150 | logDebug('Disabled');
151 |
152 | uninitPrefs();
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | import '@girs/gjs';
2 | import '@girs/gjs/dom';
3 | import '@girs/gnome-shell/ambient';
4 | import '@girs/gnome-shell/extensions/global';
5 | import '@girs/cogl-2.0';
6 |
--------------------------------------------------------------------------------
/src/manager/README.md:
--------------------------------------------------------------------------------
1 | # `manager`
2 |
3 | The rounded corners effect has to perform some actions when differen events
4 | happen. For example, when a new window is opened, the effect has to detect
5 | it and add rounded corners to it.
6 |
7 | This directory contains the code that handles these events.
8 |
9 | ## `event_manager.ts`
10 |
11 | Manages connections between gnome shell events and the rounded corners
12 | effect. It attaches the necessary signals to matching handlers on each effect.
13 |
14 | ## `event_handlers.ts`
15 |
16 | Contains the implementation of handlers for all of the events.
17 |
18 | ## `utils.ts`
19 |
20 | Provides various utility functions used withing signal handling code.
21 |
--------------------------------------------------------------------------------
/src/manager/event_handlers.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains the implementation of handlers for various events that need
3 | * to be processed by the extension. Those handlers are bound to event signals
4 | * in effect_manager.ts.
5 | */
6 |
7 | import Clutter from 'gi://Clutter';
8 | import GLib from 'gi://GLib';
9 | import GObject from 'gi://GObject';
10 | import St from 'gi://St';
11 |
12 | import {ClipShadowEffect} from '../effect/clip_shadow_effect.js';
13 | import {RoundedCornersEffect} from '../effect/rounded_corners_effect.js';
14 | import {
15 | CLIP_SHADOW_EFFECT,
16 | ROUNDED_CORNERS_EFFECT,
17 | } from '../utils/constants.js';
18 | import {logDebug} from '../utils/log.js';
19 | import {getPref} from '../utils/settings.js';
20 | import {
21 | computeBounds,
22 | computeShadowActorOffset,
23 | computeWindowContentsOffset,
24 | getRoundedCornersCfg,
25 | getRoundedCornersEffect,
26 | shouldEnableEffect,
27 | unwrapActor,
28 | updateShadowActorStyle,
29 | windowScaleFactor,
30 | } from './utils.js';
31 |
32 | import type Meta from 'gi://Meta';
33 | import type {RoundedWindowActor} from '../utils/types.js';
34 |
35 | export function onAddEffect(actor: RoundedWindowActor) {
36 | logDebug(`Adding effect to ${actor?.metaWindow.title}`);
37 |
38 | const win = actor.metaWindow;
39 |
40 | if (!shouldEnableEffect(win)) {
41 | logDebug(`Skipping ${win.title}`);
42 | return;
43 | }
44 |
45 | unwrapActor(actor)?.add_effect_with_name(
46 | ROUNDED_CORNERS_EFFECT,
47 | new RoundedCornersEffect(),
48 | );
49 |
50 | const shadow = createShadow(actor);
51 |
52 | // Bind properties of the window to the shadow actor.
53 | for (const prop of [
54 | 'pivot-point',
55 | 'translation-x',
56 | 'translation-y',
57 | 'scale-x',
58 | 'scale-y',
59 | 'visible',
60 | ]) {
61 | actor.bind_property(
62 | prop,
63 | shadow,
64 | prop,
65 | GObject.BindingFlags.SYNC_CREATE,
66 | );
67 | }
68 |
69 | // Store shadow, app type, visible binding, so that we can access them later
70 | actor.rwcCustomData = {
71 | shadow,
72 | unminimizedTimeoutId: 0,
73 | };
74 |
75 | // Make sure the effect is applied correctly.
76 | refreshRoundedCorners(actor);
77 | }
78 |
79 | export function onRemoveEffect(actor: RoundedWindowActor): void {
80 | const name = ROUNDED_CORNERS_EFFECT;
81 | unwrapActor(actor)?.remove_effect_by_name(name);
82 |
83 | // Remove shadow actor
84 | const shadow = actor.rwcCustomData?.shadow;
85 | if (shadow) {
86 | global.windowGroup.remove_child(shadow);
87 | shadow.clear_effects();
88 | shadow.destroy();
89 | }
90 |
91 | // Remove all timeout handler
92 | const timeoutId = actor.rwcCustomData?.unminimizedTimeoutId;
93 | if (timeoutId) {
94 | GLib.source_remove(timeoutId);
95 | }
96 | delete actor.rwcCustomData;
97 | }
98 |
99 | export function onMinimize(actor: RoundedWindowActor): void {
100 | // Compatibility with "Compiz alike magic lamp effect".
101 | // When minimizing a window, disable the shadow to make the magic lamp effect
102 | // work.
103 | const magicLampEffect = actor.get_effect('minimize-magic-lamp-effect');
104 | const shadow = actor.rwcCustomData?.shadow;
105 | const roundedCornersEffect = getRoundedCornersEffect(actor);
106 | if (magicLampEffect && shadow && roundedCornersEffect) {
107 | logDebug('Minimizing with magic lamp effect');
108 | shadow.visible = false;
109 | roundedCornersEffect.enabled = false;
110 | }
111 | }
112 |
113 | export function onUnminimize(actor: RoundedWindowActor): void {
114 | // Compatibility with "Compiz alike magic lamp effect".
115 | // When unminimizing a window, wait until the effect is completed before
116 | // showing the shadow.
117 | const magicLampEffect = actor.get_effect('unminimize-magic-lamp-effect');
118 | const shadow = actor.rwcCustomData?.shadow;
119 | const roundedCornersEffect = getRoundedCornersEffect(actor);
120 | if (magicLampEffect && shadow && roundedCornersEffect) {
121 | shadow.visible = false;
122 | type Effect = Clutter.Effect & {timerId: Clutter.Timeline};
123 | const timer = (magicLampEffect as Effect).timerId;
124 |
125 | const id = timer.connect('new-frame', source => {
126 | // Wait until the effect is 98% completed
127 | if (source.get_progress() > 0.98) {
128 | logDebug('Unminimizing with magic lamp effect');
129 | shadow.visible = true;
130 | roundedCornersEffect.enabled = true;
131 | source.disconnect(id);
132 | }
133 | });
134 |
135 | return;
136 | }
137 | }
138 |
139 | export function onRestacked(): void {
140 | for (const actor of global.get_window_actors()) {
141 | const shadow = (actor as RoundedWindowActor).rwcCustomData?.shadow;
142 |
143 | if (!(actor.visible && shadow)) {
144 | continue;
145 | }
146 |
147 | global.windowGroup.set_child_below_sibling(shadow, actor);
148 | }
149 | }
150 |
151 | export const onSizeChanged = refreshRoundedCorners;
152 |
153 | export const onFocusChanged = refreshShadow;
154 |
155 | export const onSettingsChanged = refreshAllRoundedCorners;
156 |
157 | /**
158 | * Create the shadow actor for a window.
159 | *
160 | * @param actor - The window actor to create the shadow actor for.
161 | */
162 | function createShadow(actor: Meta.WindowActor): St.Bin {
163 | const shadow = new St.Bin({
164 | name: 'Shadow Actor',
165 | child: new St.Bin({
166 | xExpand: true,
167 | yExpand: true,
168 | }),
169 | });
170 | (shadow.firstChild as St.Bin).add_style_class_name('shadow');
171 |
172 | refreshShadow(actor);
173 |
174 | // We have to clip the shadow because of this issue:
175 | // https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4474
176 | shadow.add_effect_with_name(CLIP_SHADOW_EFFECT, new ClipShadowEffect());
177 |
178 | // Draw the shadow actor below the window actor.
179 | global.windowGroup.insert_child_below(shadow, actor);
180 |
181 | // Bind position and size between window and shadow
182 | for (let i = 0; i < 4; i++) {
183 | const constraint = new Clutter.BindConstraint({
184 | source: actor,
185 | coordinate: i,
186 | offset: 0,
187 | });
188 | shadow.add_constraint(constraint);
189 | }
190 |
191 | return shadow;
192 | }
193 |
194 | /**
195 | * Refresh the shadow actor for a window.
196 | *
197 | * @param actor - The window actor to refresh the shadow for.
198 | */
199 | function refreshShadow(actor: RoundedWindowActor) {
200 | const win = actor.metaWindow;
201 | const shadow = actor.rwcCustomData?.shadow;
202 | if (!shadow) {
203 | return;
204 | }
205 |
206 | const shadowSettings = win.appears_focused
207 | ? getPref('focused-shadow')
208 | : getPref('unfocused-shadow');
209 |
210 | const {borderRadius, padding} = getRoundedCornersCfg(win);
211 |
212 | updateShadowActorStyle(win, shadow, borderRadius, shadowSettings, padding);
213 | }
214 |
215 | /**
216 | * Refresh rounded corners state and settings for a window.
217 | *
218 | * @param actor - The window actor to refresh the rounded corners settings for.
219 | */
220 | function refreshRoundedCorners(actor: RoundedWindowActor): void {
221 | const win = actor.metaWindow;
222 |
223 | const windowInfo = actor.rwcCustomData;
224 | const effect = getRoundedCornersEffect(actor);
225 |
226 | const hasEffect = effect && windowInfo;
227 | const shouldHaveEffect = shouldEnableEffect(win);
228 |
229 | if (!hasEffect) {
230 | // onAddEffect already skips windows that shouldn't have rounded corners.
231 | onAddEffect(actor);
232 | return;
233 | }
234 |
235 | if (!shouldHaveEffect) {
236 | onRemoveEffect(actor);
237 | return;
238 | }
239 |
240 | if (!effect.enabled) {
241 | effect.enabled = true;
242 | }
243 |
244 | // When window size is changed, update uniforms for corner rounding shader.
245 | const cfg = getRoundedCornersCfg(win);
246 | const windowContentOffset = computeWindowContentsOffset(win);
247 | effect.updateUniforms(
248 | windowScaleFactor(win),
249 | cfg,
250 | computeBounds(actor, windowContentOffset),
251 | );
252 |
253 | // Update BindConstraint for the shadow
254 | const shadow = windowInfo.shadow;
255 | const offsets = computeShadowActorOffset(actor, windowContentOffset);
256 | const constraints = shadow.get_constraints();
257 | constraints.forEach((constraint, i) => {
258 | if (constraint instanceof Clutter.BindConstraint) {
259 | constraint.offset = offsets[i];
260 | }
261 | });
262 |
263 | refreshShadow(actor);
264 | }
265 |
266 | /** Refresh rounded corners settings for all windows. */
267 | function refreshAllRoundedCorners() {
268 | for (const actor of global.get_window_actors()) {
269 | refreshRoundedCorners(actor);
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/src/manager/event_manager.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Manages connections between gnome shell events and the rounded corners
3 | * effect. See {@link enableEffect} for more information.
4 | */
5 |
6 | import {logDebug} from '../utils/log.js';
7 | import {prefs} from '../utils/settings.js';
8 | import * as handlers from './event_handlers.js';
9 |
10 | import type GObject from 'gi://GObject';
11 | import type Meta from 'gi://Meta';
12 | import type Shell from 'gi://Shell';
13 | import type {RoundedWindowActor} from '../utils/types.js';
14 |
15 | /**
16 | * The rounded corners effect has to perform some actions when differen events
17 | * happen. For example, when a new window is opened, the effect has to detect
18 | * it and add rounded corners to it.
19 | *
20 | * The `enableEffect` method handles this by attaching the necessary signals
21 | * to matching handlers on each effect.
22 | */
23 | export function enableEffect() {
24 | // Update the effect when settings are changed.
25 | connect(prefs, 'changed', handlers.onSettingsChanged);
26 |
27 | const wm = global.windowManager;
28 |
29 | // Add the effect to all windows when the extension is enabled.
30 | const windowActors = global.get_window_actors();
31 | logDebug(`Initial window count: ${windowActors.length}`);
32 | for (const actor of windowActors) {
33 | applyEffectTo(actor);
34 | }
35 |
36 | // Add the effect to new windows when they are opened.
37 | connect(
38 | global.display,
39 | 'window-created',
40 | (_: Meta.Display, win: Meta.Window) => {
41 | const actor: Meta.WindowActor = win.get_compositor_private();
42 |
43 | // If wm_class_instance of Meta.Window is null, wait for it to be
44 | // set before applying the effect.
45 | if (win?.get_wm_class_instance() == null) {
46 | const notifyId = win.connect('notify::wm-class', () => {
47 | applyEffectTo(actor);
48 | win.disconnect(notifyId);
49 | });
50 | } else {
51 | applyEffectTo(actor);
52 | }
53 | },
54 | );
55 |
56 | // Window minimized.
57 | connect(wm, 'minimize', (_: Shell.WM, actor: Meta.WindowActor) =>
58 | handlers.onMinimize(actor),
59 | );
60 |
61 | // Window unminimized.
62 | connect(wm, 'unminimize', (_: Shell.WM, actor: Meta.WindowActor) =>
63 | handlers.onUnminimize(actor),
64 | );
65 |
66 | // When closing the window, remove the effect from it.
67 | connect(wm, 'destroy', (_: Shell.WM, actor: Meta.WindowActor) =>
68 | removeEffectFrom(actor),
69 | );
70 |
71 | // When windows are restacked, the order of shadow actors as well.
72 | connect(global.display, 'restacked', handlers.onRestacked);
73 | }
74 |
75 | /** Disable the effect for all windows. */
76 | export function disableEffect() {
77 | for (const actor of global.get_window_actors()) {
78 | removeEffectFrom(actor);
79 | }
80 |
81 | disconnectAll();
82 | }
83 |
84 | const connections: {object: GObject.Object; id: number}[] = [];
85 |
86 | /**
87 | * Connect a callback to an object signal and add it to the list of all
88 | * connections. This allows to easily disconnect all signals when removing
89 | * the effect.
90 | *
91 | * @param object - The object to connect the callback to.
92 | * @param signal - The name of the signal.
93 | * @param callback - The function to connect to the signal.
94 | */
95 | function connect(
96 | object: GObject.Object,
97 | signal: string,
98 | // Signal callbacks can have any return args and return types.
99 | // biome-ignore lint/suspicious/noExplicitAny:
100 | callback: (...args: any[]) => any,
101 | ) {
102 | connections.push({
103 | object: object,
104 | id: object.connect(signal, callback),
105 | });
106 | }
107 |
108 | /**
109 | * Disconnect all connected signals from all actors or a specific object.
110 | *
111 | * @param object - If object is provided, only disconnect signals from it.
112 | */
113 | function disconnectAll(object?: GObject.Object) {
114 | for (const connection of connections) {
115 | if (object === undefined || connection.object === object) {
116 | connection.object.disconnect(connection.id);
117 | }
118 | }
119 | }
120 |
121 | /**
122 | * Apply the effect to a window.
123 | *
124 | * While {@link enableEffect} handles global events such as window creation,
125 | * this function handles events that happen to a specific window, like changing
126 | * its size or workspace.
127 | *
128 | * @param actor - The window actor to apply the effect to.
129 | */
130 | function applyEffectTo(actor: RoundedWindowActor) {
131 | // In wayland sessions, the surface actor of XWayland clients is sometimes
132 | // not ready when the window is created. In this case, we wait until it is
133 | // ready before applying the effect.
134 | if (!actor.firstChild) {
135 | const id = actor.connect('notify::first-child', () => {
136 | applyEffectTo(actor);
137 | actor.disconnect(id);
138 | });
139 |
140 | return;
141 | }
142 |
143 | const texture = actor.get_texture();
144 | if (!texture) {
145 | return;
146 | }
147 |
148 | // Window resized.
149 | //
150 | // The signal has to be connected both to the actor and the texture. Why is
151 | // that? I have no idea. But without that, weird bugs can happen. For
152 | // example, when using Dash to Dock, all opened windows will be invisible
153 | // *unless they are pinned in the dock*. So yeah, GNOME is magic.
154 | connect(actor, 'notify::size', () => handlers.onSizeChanged(actor));
155 | connect(texture, 'size-changed', () => {
156 | handlers.onSizeChanged(actor);
157 | });
158 |
159 | // Window focus changed.
160 | connect(actor.metaWindow, 'notify::appears-focused', () =>
161 | handlers.onFocusChanged(actor),
162 | );
163 |
164 | // Workspace or monitor of the window changed.
165 | connect(actor.metaWindow, 'workspace-changed', () => {
166 | handlers.onFocusChanged(actor);
167 | });
168 |
169 | handlers.onAddEffect(actor);
170 | }
171 |
172 | /**
173 | * Remove the effect from a window.
174 | *
175 | * @param actor - The window actor to remove the effect from.
176 | */
177 | function removeEffectFrom(actor: RoundedWindowActor) {
178 | disconnectAll(actor);
179 | disconnectAll(actor.metaWindow);
180 |
181 | handlers.onRemoveEffect(actor);
182 | }
183 |
--------------------------------------------------------------------------------
/src/patch/README.md:
--------------------------------------------------------------------------------
1 | # `patch`
2 |
3 | This directory contains functions which are used to monkey patch GNOME Shell
4 | methods. See `extension.ts` for more information.
5 |
6 | ## `add_shadow_in_overview.ts`
7 |
8 | Contains a function that adds a shadow actor to a window preview in
9 | the overview. Used to patch the `WindowPreview._addWindow` method.
10 |
11 | ## `workspace_switch.ts`
12 |
13 | Contains functions for handling shadows during workspace switching. Used to
14 | patch the `WorkspaceAnimationController._prepareWorkspaceSwitch` and
15 | `WorkspaceAnimationController._finishWorkspaceSwitch` methods.
16 |
--------------------------------------------------------------------------------
/src/patch/add_shadow_in_overview.ts:
--------------------------------------------------------------------------------
1 | /** @file Provides a function to add a shadow actor to a window preview in the overview. */
2 |
3 | import Clutter from 'gi://Clutter';
4 | import GObject from 'gi://GObject';
5 | import Graphene from 'gi://Graphene';
6 |
7 | import {overview} from 'resource:///org/gnome/shell/ui/main.js';
8 | import {LinearFilterEffect} from '../effect/linear_filter_effect.js';
9 | import {shouldEnableEffect, windowScaleFactor} from '../manager/utils.js';
10 | import {OVERVIEW_SHADOW_ACTOR, SHADOW_PADDING} from '../utils/constants.js';
11 | import {logDebug} from '../utils/log.js';
12 |
13 | import type Meta from 'gi://Meta';
14 | import type {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js';
15 | import type {RoundedWindowActor} from '../utils/types.js';
16 |
17 | /**
18 | * Add a shadow actor to a window preview in the overview.
19 | * @param window - The window that the preview is of.
20 | * @param self - The window preview that the shadow actor is added to.
21 | */
22 | export function addShadowInOverview(window: Meta.Window, self: WindowPreview) {
23 | // Create a new error object and use it to get the call stack of
24 | // the function.
25 | //
26 | // Since the error is not actually being raised, it doesn't need
27 | // an error message.
28 | // biome-ignore lint/suspicious/useErrorMessage:
29 | const stack = new Error().stack?.trim();
30 | if (
31 | stack === undefined ||
32 | stack.indexOf('_updateAttachedDialogs') !== -1 ||
33 | stack.indexOf('addDialog') !== -1
34 | ) {
35 | // If the window is an attached dialog, skip it.
36 | return;
37 | }
38 |
39 | // If the original window doesn't have rounded corners or a shadow,
40 | // we don't need to do anything, so we can skip it.
41 | const hasRoundedCorners = shouldEnableEffect(window);
42 | const windowActor = window.get_compositor_private() as RoundedWindowActor;
43 | const shadow = windowActor.rwcCustomData?.shadow;
44 | if (!(hasRoundedCorners && shadow)) {
45 | return;
46 | }
47 |
48 | logDebug(`Adding shadow for ${window.title} in overview`);
49 |
50 | // windowContainer has the actual contents of the window preview
51 | const windowContainer = self.windowContainer;
52 | let firstChild: Clutter.Actor | null = windowContainer.firstChild;
53 |
54 | // Apply liear interpolation to the window preview to make it look
55 | // better (there's an upstream GNOME bug causing windows to be blurry,
56 | // this makes the effect less noticeable)
57 | firstChild?.add_effect(new LinearFilterEffect());
58 |
59 | // Create a clone of the window's shadow actor and add it to the preview
60 | const shadowActorClone = new OverviewShadowActorClone(shadow, self);
61 | windowContainer.bind_property('scale-x', shadowActorClone, 'scale-x', 1);
62 | windowContainer.bind_property('scale-y', shadowActorClone, 'scale-y', 1);
63 | self.insert_child_below(shadowActorClone, windowContainer);
64 |
65 | // Disconnect all signals when the window preview is destroyed
66 | const connection = self.connect('destroy', () => {
67 | shadowActorClone.destroy();
68 | firstChild?.clear_effects();
69 | firstChild = null;
70 |
71 | self.disconnect(connection);
72 | });
73 | }
74 |
75 | /**
76 | * A clone of a window's shadow actor that is shown in the overview. Binds the
77 | * size of the shadow to the size of the window preview in the overview.
78 | */
79 | const OverviewShadowActorClone = GObject.registerClass(
80 | {},
81 | class extends Clutter.Clone {
82 | windowPreview: WindowPreview;
83 |
84 | /**
85 | * Create the clone of the shadow actor.
86 | * @param source the shadow actor to clone.
87 | * @param windowPreview the window preview that the clone is applied to.
88 | */
89 | constructor(source: Clutter.Actor, windowPreview: WindowPreview) {
90 | super({
91 | source, // the source shadow actor shown in desktop
92 | name: OVERVIEW_SHADOW_ACTOR,
93 | pivotPoint: new Graphene.Point({x: 0.5, y: 0.5}),
94 | });
95 |
96 | this.windowPreview = windowPreview;
97 | }
98 |
99 | /**
100 | * Recompute the position and size of shadow in overview
101 | * This virtual function will be called when we:
102 | * - entering/closing overview
103 | * - dragging window
104 | * - position and size of window preview in overview changed
105 | * @param box The bound box of shadow actor
106 | */
107 | vfunc_allocate(box: Clutter.ActorBox): void {
108 | // The layout box of the window has to be obtained in a different
109 | // way when leaving the overview (eg. by pressing ESC). I have no
110 | // idea why this is the case, but oh well. GNOME.
111 | const leavingOverview =
112 | overview._overview.controls._workspacesDisplay._leavingOverview;
113 | const windowContainerBox = leavingOverview
114 | ? this.windowPreview.windowContainer.get_allocation_box()
115 | : this.windowPreview.get_allocation_box();
116 |
117 | const metaWindow =
118 | this.windowPreview._windowActor.get_meta_window();
119 | if (!metaWindow) {
120 | return;
121 | }
122 |
123 | // Scale the shadow by the same scale factor that the window preview
124 | // is scaled by.
125 | const containerScaleFactor =
126 | windowContainerBox.get_width() /
127 | metaWindow.get_frame_rect().width;
128 | const paddings =
129 | SHADOW_PADDING *
130 | containerScaleFactor *
131 | windowScaleFactor(metaWindow);
132 |
133 | // Setup the bounding box of the shadow actor.
134 | box.set_origin(-paddings, -paddings);
135 | box.set_size(
136 | windowContainerBox.get_width() + 2 * paddings,
137 | windowContainerBox.get_height() + 2 * paddings,
138 | );
139 |
140 | // Apply the bounding box.
141 | super.vfunc_allocate(box);
142 | }
143 | },
144 | );
145 |
--------------------------------------------------------------------------------
/src/patch/workspace_switch.ts:
--------------------------------------------------------------------------------
1 | /** @file Provides functions for handling shadows during workspace switching. */
2 |
3 | import Clutter from 'gi://Clutter';
4 |
5 | import {getRoundedCornersEffect, windowScaleFactor} from '../manager/utils.js';
6 | import {SHADOW_PADDING} from '../utils/constants.js';
7 |
8 | import type GObject from 'gi://GObject';
9 | import type {WorkspaceAnimationController} from 'resource:///org/gnome/shell/ui/workspaceAnimation.js';
10 | import type {RoundedWindowActor} from '../utils/types.js';
11 |
12 | type WsAnimationActor = Clutter.Actor & {shadowClone?: Clutter.Actor};
13 |
14 | /**
15 | * Add shadows to windows when switching workspaces.
16 | * @param self - The workspace animation controller.
17 | * @returns A set of connections to be disconnected on extension disable.
18 | */
19 | export function addShadowsInWorkspaceSwitch(
20 | self: WorkspaceAnimationController,
21 | ) {
22 | const connections: {object: GObject.Object; id: number}[] = [];
23 |
24 | for (const monitor of self._switchData.monitors) {
25 | for (const workspace of monitor._workspaceGroups) {
26 | const windowRecords = workspace._windowRecords;
27 |
28 | // Switching workspaces messes with the window stacking order,
29 | // so the shadows need to be restacked in order to always be
30 | // behind the window.
31 | const restackedConnection = global.display.connect(
32 | 'restacked',
33 | () => {
34 | for (const {clone} of windowRecords) {
35 | const shadow = (clone as WsAnimationActor).shadowClone;
36 | if (shadow) {
37 | workspace.set_child_below_sibling(shadow, clone);
38 | }
39 | }
40 | },
41 | );
42 | const destroyConnection = workspace.connect('destroy', () => {
43 | global.display.disconnect(restackedConnection);
44 | workspace.disconnect(destroyConnection);
45 | });
46 |
47 | connections.push({object: global.display, id: restackedConnection});
48 | connections.push({object: workspace, id: destroyConnection});
49 |
50 | for (const {windowActor: actor, clone} of windowRecords) {
51 | const win = actor.metaWindow;
52 |
53 | // Skip windows that don't have a shadow or an enabled RWC effect.
54 | const shadow = (actor as RoundedWindowActor).rwcCustomData
55 | ?.shadow;
56 | const enabled = getRoundedCornersEffect(actor)?.enabled;
57 | if (!(shadow && enabled)) {
58 | continue;
59 | }
60 |
61 | // Clone the shadow actor and set its dimensions to match the
62 | // window actor size.
63 | const shadowClone = new Clutter.Clone({
64 | source: shadow,
65 | });
66 | const paddings = SHADOW_PADDING * windowScaleFactor(win);
67 |
68 | const frameRect = win.get_frame_rect();
69 |
70 | shadowClone.width = frameRect.width + paddings * 2;
71 | shadowClone.height = frameRect.height + paddings * 2;
72 | shadowClone.x = clone.x + frameRect.x - actor.x - paddings;
73 | shadowClone.y = clone.y + frameRect.y - actor.y - paddings;
74 |
75 | // Compatibility with Desktop Cube
76 | const notifyId = clone.connect('notify::translation-z', () => {
77 | shadowClone.translationZ = clone.translationZ - 0.05;
78 | });
79 | const destroyConnection = clone.connect('destroy', () => {
80 | clone.disconnect(notifyId);
81 | clone.disconnect(destroyConnection);
82 | });
83 |
84 | connections.push({object: clone, id: notifyId});
85 | connections.push({object: clone, id: destroyConnection});
86 |
87 | // Store the reference to the shadow clone. This allows restacking
88 | // them, as you can see at the top of this function.
89 | (clone as WsAnimationActor).shadowClone = shadowClone;
90 | clone.bind_property('visible', shadowClone, 'visible', 0);
91 |
92 | workspace.insert_child_below(shadowClone, clone);
93 | }
94 | }
95 | }
96 |
97 | return connections;
98 | }
99 |
100 | /**
101 | * Delete shadow clones after switching workspaces.
102 | * @param self - The workspace animation controller.
103 | */
104 | export function removeShadowsAfterWorkspaceSwitch(
105 | self: WorkspaceAnimationController,
106 | ) {
107 | for (const monitor of self._switchData.monitors) {
108 | for (const workspace of monitor._workspaceGroups) {
109 | for (const {clone} of workspace._windowRecords) {
110 | (clone as WsAnimationActor).shadowClone?.destroy();
111 | delete (clone as WsAnimationActor).shadowClone;
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/preferences/README.md:
--------------------------------------------------------------------------------
1 | # `preferences`
2 |
3 | This directory contains the code for the preferences page of the extension.
4 |
5 | Note that the actual implementation of the preferences page is in the
6 | `prefs.ts` file, which uses files from this directory.
7 |
8 | ## `index.ts`
9 |
10 | Contains a `prefsTabs` variable that lists all of the tabs to be initialized.
11 |
12 | ## `pages`
13 |
14 | This directory contains the code for each of the tabs, as well as the subpages
15 | for editing the shadow and resetting the settings.
16 |
17 | ## `widgets`
18 |
19 | This directory contains the code for the widgets used on the preferences page.
20 |
--------------------------------------------------------------------------------
/src/preferences/index.ts:
--------------------------------------------------------------------------------
1 | /** @file Contains the list of top-level pages (tabs) in the preferences window. */
2 |
3 | import type Adw from 'gi://Adw';
4 |
5 | import {BlacklistPage} from '../preferences/pages/blacklist.js';
6 | import {CustomPage} from '../preferences/pages/custom.js';
7 | import {GeneralPage} from '../preferences/pages/general.js';
8 |
9 | export const prefsTabs: (typeof Adw.PreferencesPage)[] = [
10 | GeneralPage,
11 | BlacklistPage,
12 | CustomPage,
13 | ];
14 |
--------------------------------------------------------------------------------
/src/preferences/pages/blacklist.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains the implementation of the blacklist page.
3 | * Handles creating blacklist entries and binding them to settings.
4 | */
5 |
6 | import Adw from 'gi://Adw';
7 | import GLib from 'gi://GLib';
8 | import GObject from 'gi://GObject';
9 |
10 | import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
11 | import {getPref, setPref} from '../../utils/settings.js';
12 | import {AppRow, type AppRowClass} from '../widgets/app_row.js';
13 |
14 | import type Gtk from 'gi://Gtk';
15 |
16 | export const BlacklistPage = GObject.registerClass(
17 | {
18 | Template: GLib.uri_resolve_relative(
19 | import.meta.url,
20 | 'blacklist.ui',
21 | GLib.UriFlags.NONE,
22 | ),
23 | GTypeName: 'PrefsBlacklist',
24 | InternalChildren: ['blacklistGroup'],
25 | },
26 | class extends Adw.PreferencesPage {
27 | private declare _blacklistGroup: Adw.PreferencesGroup;
28 |
29 | #blacklist = getPref('blacklist');
30 |
31 | constructor() {
32 | super();
33 |
34 | for (const title of this.#blacklist) {
35 | this.addWindow(undefined, title);
36 | }
37 | }
38 |
39 | /**
40 | * Add a new blacklist entry.
41 | * @param wmClass - The WM_CLASS of the window.
42 | */
43 | addWindow(_?: Gtk.Button, wmClass?: string) {
44 | const row = new AppRow({
45 | onDelete: row => this.#deleteWindow(row),
46 | onWindowChange: (_, oldWmClass, newWmClass) =>
47 | this.#changeWindow(oldWmClass, newWmClass),
48 | });
49 | row.set_subtitle(wmClass ?? '');
50 | this._blacklistGroup.add(row);
51 | }
52 |
53 | /**
54 | * Delete a blacklist entry.
55 | * @param row - The row to delete.
56 | */
57 | #deleteWindow(row: AppRowClass) {
58 | this.#blacklist.splice(this.#blacklist.indexOf(row.title), 1);
59 | setPref('blacklist', this.#blacklist);
60 | this._blacklistGroup.remove(row);
61 | }
62 |
63 | /**
64 | * Change the blacklist entry to a different window.
65 | * @param oldWmClass - Current WM_CLASS of the entry.
66 | * @param newWmClass - New WM_CLASS of the entry.
67 | * @returns Whether the entry was changed successfully.
68 | */
69 | #changeWindow(oldWmClass: string, newWmClass: string): boolean {
70 | if (this.#blacklist.includes(newWmClass)) {
71 | // If the new window is already in the blacklist, show an error.
72 | const win = this.root as unknown as Adw.PreferencesDialog;
73 | win.add_toast(
74 | new Adw.Toast({
75 | title: _(
76 | `Can't add ${newWmClass} to the list, because it already there`,
77 | ),
78 | }),
79 | );
80 | return false;
81 | }
82 |
83 | if (oldWmClass === '') {
84 | // If the old WM_CLASS is empty, the entry was just created,
85 | // so we need to just add the new window to the blacklist.
86 | this.#blacklist.push(newWmClass);
87 | } else {
88 | // Otherwise, replace the old window with the new one.
89 | const oldId = this.#blacklist.indexOf(oldWmClass);
90 | this.#blacklist.splice(oldId, 1, newWmClass);
91 | }
92 |
93 | setPref('blacklist', this.#blacklist);
94 |
95 | return true;
96 | }
97 | },
98 | );
99 |
--------------------------------------------------------------------------------
/src/preferences/pages/blacklist.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Blacklist
7 | action-unavailable-symbolic
8 |
9 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/preferences/pages/custom.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Custom
7 | document-edit-symbolic
8 |
9 |
10 | Custom
11 | Set custom effect setting for each window class
12 |
13 |
14 | start
15 | 4px
16 | 4px
17 |
18 |
19 | Add window
20 | list-add-symbolic
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/preferences/pages/edit_shadow.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains the code for the shadow settings page.
3 | * It implements the dynamic preview widget that uses GTK CSS Provider to
4 | * show what the shadow will look like.
5 | */
6 |
7 | import Adw from 'gi://Adw';
8 | import GLib from 'gi://GLib';
9 | import GObject from 'gi://GObject';
10 | import Gio from 'gi://Gio';
11 | import Gtk from 'gi://Gtk';
12 |
13 | import {boxShadowCss} from '../../utils/box_shadow.js';
14 | import {getPref, setPref} from '../../utils/settings.js';
15 |
16 | import type {BoxShadow} from '../../utils/types.js';
17 |
18 | export const EditShadowPage = GObject.registerClass(
19 | {
20 | Template: GLib.uri_resolve_relative(
21 | import.meta.url,
22 | 'edit-shadow.ui',
23 | GLib.UriFlags.NONE,
24 | ),
25 | GTypeName: 'EditShadowPage',
26 | InternalChildren: [
27 | 'focusedShadowPreview',
28 | 'unfocusedShadowPreview',
29 | 'previewRow',
30 |
31 | 'focusedHorizontalOffset',
32 | 'focusedVerticalOffset',
33 | 'focusedBlurRadius',
34 | 'focusedSpreadRadius',
35 | 'focusedOpacity',
36 |
37 | 'unfocusedHorizontalOffset',
38 | 'unfocusedVerticalOffset',
39 | 'unfocusedBlurRadius',
40 | 'unfocusedSpreadRadius',
41 | 'unfocusedOpacity',
42 | ],
43 | },
44 | class extends Adw.NavigationPage {
45 | private declare _focusedShadowPreview: Gtk.Widget;
46 | private declare _unfocusedShadowPreview: Gtk.Widget;
47 | private declare _previewRow: Gtk.Widget;
48 |
49 | private declare _focusedHorizontalOffset: Gtk.Adjustment;
50 | private declare _focusedVerticalOffset: Gtk.Adjustment;
51 | private declare _focusedBlurRadius: Gtk.Adjustment;
52 | private declare _focusedSpreadRadius: Gtk.Adjustment;
53 | private declare _focusedOpacity: Gtk.Adjustment;
54 |
55 | private declare _unfocusedHorizontalOffset: Gtk.Adjustment;
56 | private declare _unfocusedVerticalOffset: Gtk.Adjustment;
57 | private declare _unfocusedBlurRadius: Gtk.Adjustment;
58 | private declare _unfocusedSpreadRadius: Gtk.Adjustment;
59 | private declare _unfocusedOpacity: Gtk.Adjustment;
60 |
61 | // CSS Providers allow to dynamically apply a CSS style string to
62 | // the preview widgets.
63 | #unfocusCssProvider = new Gtk.CssProvider();
64 | #focusCssProvider = new Gtk.CssProvider();
65 | #backgroundCssProvider = new Gtk.CssProvider();
66 |
67 | #focusedShadowSettings = getPref('focused-shadow');
68 | #unfocusedShadowSettings = getPref('unfocused-shadow');
69 |
70 | #isInitialized = false;
71 |
72 | constructor() {
73 | super();
74 |
75 | // Update the desktop wallpaper in the preview when switching
76 | // between light and dark mode, since the wallpaper can change
77 | // when that happens.
78 | const styleManager = new Adw.StyleManager();
79 | styleManager.connect('notify::dark', manager => {
80 | this.#refreshWallpaper(manager);
81 | });
82 |
83 | // Initialize the styles of preview widgets.
84 | this._focusedShadowPreview
85 | .get_style_context()
86 | .add_provider(
87 | this.#focusCssProvider,
88 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
89 | );
90 | this._unfocusedShadowPreview
91 | .get_style_context()
92 | .add_provider(
93 | this.#unfocusCssProvider,
94 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
95 | );
96 | this._previewRow
97 | .get_style_context()
98 | .add_provider(
99 | this.#backgroundCssProvider,
100 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
101 | );
102 |
103 | this.#refreshWallpaper(styleManager);
104 | this.#syncWidgetState();
105 | this.#updatePreviewStyle();
106 | this.#isInitialized = true;
107 | }
108 |
109 | onValueChanged() {
110 | if (!this.#isInitialized) {
111 | return;
112 | }
113 | this.#setPrefs();
114 | this.#updatePreviewStyle();
115 | }
116 |
117 | /** Synchronize the widget state with actual setting values. */
118 | #syncWidgetState() {
119 | this._focusedHorizontalOffset.set_value(
120 | this.#focusedShadowSettings.horizontalOffset,
121 | );
122 | this._focusedVerticalOffset.set_value(
123 | this.#focusedShadowSettings.verticalOffset,
124 | );
125 | this._focusedBlurRadius.set_value(
126 | this.#focusedShadowSettings.blurOffset,
127 | );
128 | this._focusedSpreadRadius.set_value(
129 | this.#focusedShadowSettings.spreadRadius,
130 | );
131 | this._focusedOpacity.set_value(this.#focusedShadowSettings.opacity);
132 |
133 | this._unfocusedHorizontalOffset.set_value(
134 | this.#unfocusedShadowSettings.horizontalOffset,
135 | );
136 | this._unfocusedVerticalOffset.set_value(
137 | this.#unfocusedShadowSettings.verticalOffset,
138 | );
139 | this._unfocusedBlurRadius.set_value(
140 | this.#unfocusedShadowSettings.blurOffset,
141 | );
142 | this._unfocusedSpreadRadius.set_value(
143 | this.#unfocusedShadowSettings.spreadRadius,
144 | );
145 | this._unfocusedOpacity.set_value(
146 | this.#unfocusedShadowSettings.opacity,
147 | );
148 | }
149 |
150 | /** Update the desktop wallpaper in the preview. */
151 | #refreshWallpaper(manager: Adw.StyleManager) {
152 | const backgrounds = Gio.Settings.new(
153 | 'org.gnome.desktop.background',
154 | );
155 | const path = manager.get_dark()
156 | ? backgrounds.get_string('picture-uri-dark')
157 | : backgrounds.get_string('picture-uri');
158 | this.#backgroundCssProvider.load_from_string(`.desktop-background {
159 | background: url("${path}");
160 | background-size: cover;
161 | }`);
162 | }
163 |
164 | /** Update the CSS style of preview widgets to match shadow settings. */
165 | #updatePreviewStyle() {
166 | this.#unfocusCssProvider.load_from_string(
167 | `.preview {
168 | transition: box-shadow 200ms;
169 | ${boxShadowCss(this.#unfocusedShadowSettings)};
170 | border-radius: 12px;
171 | }
172 | .preview:hover {
173 | ${boxShadowCss(this.#focusedShadowSettings)};
174 | }`,
175 | );
176 | this.#focusCssProvider.load_from_string(
177 | `.preview {
178 | transition: box-shadow 200ms;
179 | ${boxShadowCss(this.#focusedShadowSettings)};
180 | border-radius: 12px;
181 | }
182 | .preview:hover {
183 | ${boxShadowCss(this.#unfocusedShadowSettings)};
184 | }`,
185 | );
186 | }
187 |
188 | /** Update extension preferences based on widget state. */
189 | #setPrefs() {
190 | const focusedShadow: BoxShadow = {
191 | verticalOffset: this._focusedVerticalOffset.get_value(),
192 | horizontalOffset: this._focusedHorizontalOffset.get_value(),
193 | blurOffset: this._focusedBlurRadius.get_value(),
194 | spreadRadius: this._focusedSpreadRadius.get_value(),
195 | opacity: this._focusedOpacity.get_value(),
196 | };
197 | this.#focusedShadowSettings = focusedShadow;
198 | const unfocusedShadow: BoxShadow = {
199 | verticalOffset: this._unfocusedVerticalOffset.get_value(),
200 | horizontalOffset: this._unfocusedHorizontalOffset.get_value(),
201 | blurOffset: this._unfocusedBlurRadius.get_value(),
202 | spreadRadius: this._unfocusedSpreadRadius.get_value(),
203 | opacity: this._unfocusedOpacity.get_value(),
204 | };
205 | this.#unfocusedShadowSettings = unfocusedShadow;
206 |
207 | setPref('unfocused-shadow', this.#unfocusedShadowSettings);
208 | setPref('focused-shadow', this.#focusedShadowSettings);
209 | }
210 | },
211 | );
212 |
--------------------------------------------------------------------------------
/src/preferences/pages/general.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains the implementation of the main preferences page.
3 | * There isn't much logic in this file.
4 | */
5 |
6 | import Adw from 'gi://Adw';
7 | import GLib from 'gi://GLib';
8 | import GObject from 'gi://GObject';
9 | import Gdk from 'gi://Gdk';
10 | import Gio from 'gi://Gio';
11 |
12 | import {bindPref, getPref, setPref} from '../../utils/settings.js';
13 | import {EditShadowPage} from './edit_shadow.js';
14 | import {ResetPage} from './reset.js';
15 |
16 | import type Gtk from 'gi://Gtk';
17 | import type {PaddingsRowClass} from '../widgets/paddings_row.js';
18 |
19 | export const GeneralPage = GObject.registerClass(
20 | {
21 | Template: GLib.uri_resolve_relative(
22 | import.meta.url,
23 | 'general.ui',
24 | GLib.UriFlags.NONE,
25 | ),
26 | GTypeName: 'PrefsGeneral',
27 |
28 | // Those variables are declared inside of the `general.ui` file and
29 | // passed into the JS module prefixed with an underscore.
30 | // (skipLibadwaita -> _skipLibadwaita)
31 | InternalChildren: [
32 | 'skipLibadwaita',
33 | 'skipLibhandy',
34 | 'borderWidth',
35 | 'borderColor',
36 | 'cornerRadius',
37 | 'cornerSmoothing',
38 | 'keepForMaximized',
39 | 'keepForFullscreen',
40 | 'paddings',
41 | 'tweakKitty',
42 | 'rightClickMenu',
43 | 'enableDebugLogs',
44 | ],
45 | },
46 | class extends Adw.PreferencesPage {
47 | private declare _skipLibadwaita: Adw.SwitchRow;
48 | private declare _skipLibhandy: Adw.SwitchRow;
49 | private declare _borderWidth: Gtk.Adjustment;
50 | private declare _borderColor: Gtk.ColorDialogButton;
51 | private declare _cornerRadius: Gtk.Adjustment;
52 | private declare _cornerSmoothing: Gtk.Adjustment;
53 | private declare _keepForMaximized: Adw.SwitchRow;
54 | private declare _keepForFullscreen: Adw.SwitchRow;
55 | private declare _paddings: PaddingsRowClass;
56 | private declare _tweakKitty: Adw.SwitchRow;
57 | private declare _rightClickMenu: Adw.SwitchRow;
58 | private declare _enableDebugLogs: Adw.SwitchRow;
59 |
60 | #settings = getPref('global-rounded-corner-settings');
61 |
62 | // Bind all buttons to respective prefs.
63 | constructor() {
64 | super();
65 |
66 | bindPref(
67 | 'skip-libadwaita-app',
68 | this._skipLibadwaita,
69 | 'active',
70 | Gio.SettingsBindFlags.DEFAULT,
71 | );
72 | bindPref(
73 | 'skip-libhandy-app',
74 | this._skipLibhandy,
75 | 'active',
76 | Gio.SettingsBindFlags.DEFAULT,
77 | );
78 |
79 | bindPref(
80 | 'border-width',
81 | this._borderWidth,
82 | 'value',
83 | Gio.SettingsBindFlags.DEFAULT,
84 | );
85 |
86 | const color = new Gdk.RGBA();
87 | [color.red, color.green, color.blue, color.alpha] =
88 | this.#settings.borderColor;
89 | this._borderColor.set_rgba(color);
90 | this._borderColor.connect(
91 | 'notify::rgba',
92 | (button: Gtk.ColorDialogButton) => {
93 | const color = button.get_rgba();
94 | this.#settings.borderColor = [
95 | color.red,
96 | color.green,
97 | color.blue,
98 | color.alpha,
99 | ];
100 | this.#updateGlobalConfig();
101 | },
102 | );
103 |
104 | this._cornerRadius.set_value(this.#settings.borderRadius);
105 | this._cornerRadius.connect(
106 | 'value-changed',
107 | (adj: Gtk.Adjustment) => {
108 | this.#settings.borderRadius = adj.get_value();
109 | this.#updateGlobalConfig();
110 | },
111 | );
112 |
113 | this._cornerSmoothing.set_value(this.#settings.smoothing);
114 | this._cornerSmoothing.connect(
115 | 'value-changed',
116 | (adj: Gtk.Adjustment) => {
117 | this.#settings.smoothing = adj.get_value();
118 | this.#updateGlobalConfig();
119 | },
120 | );
121 |
122 | this._keepForMaximized.set_active(
123 | this.#settings.keepRoundedCorners.maximized,
124 | );
125 | this._keepForMaximized.connect(
126 | 'notify::active',
127 | (swtch: Adw.SwitchRow) => {
128 | this.#settings.keepRoundedCorners.maximized =
129 | swtch.get_active();
130 | this.#updateGlobalConfig();
131 | },
132 | );
133 |
134 | this._keepForFullscreen.set_active(
135 | this.#settings.keepRoundedCorners.fullscreen,
136 | );
137 | this._keepForFullscreen.connect(
138 | 'notify::active',
139 | (swtch: Adw.SwitchRow) => {
140 | this.#settings.keepRoundedCorners.fullscreen =
141 | swtch.get_active();
142 | this.#updateGlobalConfig();
143 | },
144 | );
145 |
146 | this._paddings.paddingTop = this.#settings.padding.top;
147 | this._paddings.connect(
148 | 'notify::padding-top',
149 | (row: PaddingsRowClass) => {
150 | this.#settings.padding.top = row.paddingTop;
151 | this.#updateGlobalConfig();
152 | },
153 | );
154 |
155 | this._paddings.paddingBottom = this.#settings.padding.bottom;
156 | this._paddings.connect(
157 | 'notify::padding-bottom',
158 | (row: PaddingsRowClass) => {
159 | this.#settings.padding.bottom = row.paddingBottom;
160 | this.#updateGlobalConfig();
161 | },
162 | );
163 |
164 | this._paddings.paddingStart = this.#settings.padding.left;
165 | this._paddings.connect(
166 | 'notify::padding-start',
167 | (row: PaddingsRowClass) => {
168 | this.#settings.padding.left = row.paddingStart;
169 | this.#updateGlobalConfig();
170 | },
171 | );
172 |
173 | this._paddings.paddingEnd = this.#settings.padding.right;
174 | this._paddings.connect(
175 | 'notify::padding-end',
176 | (row: PaddingsRowClass) => {
177 | this.#settings.padding.right = row.paddingEnd;
178 | this.#updateGlobalConfig();
179 | },
180 | );
181 |
182 | bindPref(
183 | 'tweak-kitty-terminal',
184 | this._tweakKitty,
185 | 'active',
186 | Gio.SettingsBindFlags.DEFAULT,
187 | );
188 |
189 | bindPref(
190 | 'enable-preferences-entry',
191 | this._rightClickMenu,
192 | 'active',
193 | Gio.SettingsBindFlags.DEFAULT,
194 | );
195 |
196 | bindPref(
197 | 'debug-mode',
198 | this._enableDebugLogs,
199 | 'active',
200 | Gio.SettingsBindFlags.DEFAULT,
201 | );
202 | }
203 |
204 | showResetPage(_: Gtk.Button) {
205 | const root = this.root as unknown as Adw.PreferencesDialog;
206 | root.push_subpage(new ResetPage());
207 | }
208 |
209 | showShadowPage(_: Adw.ActionRow) {
210 | const root = this.root as unknown as Adw.PreferencesDialog;
211 | root.push_subpage(new EditShadowPage());
212 | }
213 |
214 | #updateGlobalConfig() {
215 | setPref('global-rounded-corner-settings', this.#settings);
216 | }
217 | },
218 | );
219 |
--------------------------------------------------------------------------------
/src/preferences/pages/general.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | General
7 | emblem-system-symbolic
8 |
9 |
10 | Applications
11 | Some applications created with LibAdwaita or LibHandy already have rounded corners. You can enable those settings to avoid rounding their corners an extra time.
12 |
13 |
14 | Skip LibAdwaita applications
15 |
16 |
17 |
18 |
19 | Skip LibHandy applications
20 |
21 |
22 |
23 |
24 |
25 |
26 | Global settings
27 | These settings will have an effect on all windows
28 |
29 |
30 | Border width
31 |
32 |
33 | center
34 | true
35 | true
36 | 0
37 | 0
38 | horizontal
39 | left
40 |
41 | 0
42 |
43 |
44 |
45 | -20
46 | 20
47 | 1
48 | 1
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Border color
58 | true
59 | borderColor
60 |
61 |
62 | center
63 |
64 |
65 | Border color
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Corner radius
75 |
76 |
77 | center
78 | true
79 | true
80 | 0
81 | 0
82 | horizontal
83 | left
84 |
85 | 12
86 |
87 |
88 |
89 | 0
90 | 40
91 | 1
92 | 1
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | Corner smoothing
102 |
103 |
104 | center
105 | true
106 | true
107 | 1
108 | horizontal
109 | left
110 |
111 | 0
112 |
113 |
114 |
115 | 0
116 | 1
117 | 0.1
118 | 0.1
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | Window shadow
128 | Customize the shadow of the rounded corner window
129 | true
130 |
131 |
132 | go-next-symbolic
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | Keep rounded corners for maximized windows
141 |
142 |
143 |
144 |
145 | Keep rounded corners for fullscreen windows
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | Tweaks
156 |
157 |
158 | Add rounded corners to Kitty Terminal on Wayland
159 | Adjust paddings for Kitty Terminal to correctly round its corners
160 |
161 |
162 |
163 |
164 | Add a settings entry in right-click menu of the desktop
165 |
166 |
167 |
168 |
169 |
170 |
171 | Debug
172 |
173 |
174 | Enable debug logs
175 | Run journalctl -o cat -f /usr/bin/gnome-shell in your terminal to see the log
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | Reset preferences
185 | center
186 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/src/preferences/pages/reset.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains the implementation of the reset page.
3 | * The list of prefs that can be reset is stored in the `#resetPrefs` variable,
4 | * and the UI is automatically generated from that.
5 | */
6 |
7 | import Adw from 'gi://Adw';
8 | import GLib from 'gi://GLib';
9 | import GObject from 'gi://GObject';
10 |
11 | import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
12 | import {
13 | Schema,
14 | type SchemaKey,
15 | getPref,
16 | prefs,
17 | setPref,
18 | } from '../../utils/settings.js';
19 |
20 | import type Gtk from 'gi://Gtk';
21 | import type {RoundedCornerSettings} from '../../utils/types.js';
22 |
23 | type RoundedCorerSettingsKey = keyof RoundedCornerSettings;
24 | type ResetKey = SchemaKey | RoundedCorerSettingsKey;
25 |
26 | export const ResetPage = GObject.registerClass(
27 | {
28 | Template: GLib.uri_resolve_relative(
29 | import.meta.url,
30 | 'reset.ui',
31 | GLib.UriFlags.NONE,
32 | ),
33 | GTypeName: 'ResetPage',
34 | InternalChildren: ['resetGroup', 'resetButton', 'dialog'],
35 | },
36 | class extends Adw.NavigationPage {
37 | private declare _resetGroup: Adw.PreferencesGroup;
38 | private declare _resetButton: Gtk.Button;
39 | private declare _dialog: Adw.AlertDialog;
40 |
41 | // Store all switches in a list to enable the "select all" button.
42 | #rows: Adw.SwitchRow[] = [];
43 |
44 | // List of prefs that should be reset.
45 | #resetPrefs: ResetKey[] = [];
46 |
47 | // Map prefs to their labels in the UI.
48 | #resetLabels: {[Key in ResetKey]?: string} = {
49 | 'skip-libadwaita-app': 'Skip LibAdwaita Applications',
50 | 'skip-libhandy-app': 'Skip LibHandy Applications',
51 | 'focused-shadow': 'Focus Window Shadow Style',
52 | 'unfocused-shadow': 'Unfocus Window Shadow Style',
53 | 'border-width': 'Border Width',
54 | 'debug-mode': 'Enable Log',
55 |
56 | borderRadius: 'Border Radius',
57 | borderColor: 'Border Color',
58 | padding: 'Padding',
59 | keepRoundedCorners:
60 | 'Keep Rounded Corners when Maximized or Fullscreen',
61 | smoothing: 'Corner Smoothing',
62 | };
63 |
64 | constructor() {
65 | super();
66 |
67 | this.#buildUi();
68 | }
69 |
70 | selectAll() {
71 | for (const row of this.#rows) {
72 | row.set_active(true);
73 | }
74 | }
75 |
76 | askForReset() {
77 | this._dialog.choose(this, null, null);
78 | }
79 |
80 | reset(_: Adw.MessageDialog, response: string) {
81 | if (response === 'cancel') {
82 | return;
83 | }
84 |
85 | const defaultRoundedCornerSettings = prefs
86 | .get_default_value('global-rounded-corner-settings')
87 | ?.recursiveUnpack() as RoundedCornerSettings;
88 |
89 | const currentRoundedCornerSettings = getPref(
90 | 'global-rounded-corner-settings',
91 | );
92 |
93 | for (const key of this.#resetPrefs) {
94 | if (key in Schema) {
95 | // If the key is a top-level prefs schema key, reset it directly.
96 | prefs.reset(key);
97 | } else {
98 | // Otherwise, it's a key inside of `global-rounded-corner-settings`,
99 | // and should be reset accordingly.
100 | const settingsKey = key as RoundedCorerSettingsKey;
101 | currentRoundedCornerSettings[settingsKey] =
102 | defaultRoundedCornerSettings[settingsKey] as never;
103 | }
104 | }
105 |
106 | setPref(
107 | 'global-rounded-corner-settings',
108 | currentRoundedCornerSettings,
109 | );
110 |
111 | const root = this.root as unknown as Adw.PreferencesDialog;
112 | root.pop_subpage();
113 | }
114 |
115 | /** Generate the UI from {@link #resetLabels}. */
116 | #buildUi() {
117 | for (const [key, label] of Object.entries(this.#resetLabels)) {
118 | const row = new Adw.SwitchRow({
119 | active: false,
120 | name: key,
121 | title: _(label),
122 | });
123 | row.connect('notify::active', source =>
124 | this.#onToggled(source),
125 | );
126 | this._resetGroup.add(row);
127 | this.#rows.push(row);
128 | }
129 | }
130 |
131 | /** Callback to add or remove a pref from the list of prefs to reset. */
132 | #onToggled(source: Adw.SwitchRow): void {
133 | if (source.active) {
134 | this.#resetPrefs.push(source.name as ResetKey);
135 | } else {
136 | this.#resetPrefs = this.#resetPrefs.filter(
137 | k => k !== (source.name as ResetKey),
138 | );
139 | }
140 | }
141 | },
142 | );
143 |
--------------------------------------------------------------------------------
/src/preferences/pages/reset.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Reset settings
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Settings to reset
17 |
18 |
19 |
22 | Select all
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
37 |
38 | view-refresh-symbolic
39 | Reset
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Reset these settings?
56 | reset
57 | cancel
58 |
59 |
60 | _Cancel
61 | _Reset
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/preferences/widgets/app_row.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Generic widget for choosing a window via a picker or a text entry.
3 | * Used in the blacklist and custom settings pages.
4 | */
5 |
6 | import Adw from 'gi://Adw';
7 | import GObject from 'gi://GObject';
8 | import Gtk from 'gi://Gtk';
9 |
10 | import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
11 | import {onPicked, pick} from '../../window_picker/client.js';
12 |
13 | export class AppRowClass extends Adw.ExpanderRow {
14 | #callbacks: AppRowCallbacks;
15 |
16 | #removeButton = new Gtk.Button({
17 | icon_name: 'window-close-symbolic',
18 | css_classes: ['flat', 'circular'],
19 | valign: Gtk.Align.CENTER,
20 | });
21 | #applyButton = new Gtk.Button({
22 | icon_name: 'object-select-symbolic',
23 | css_classes: ['flat', 'circular'],
24 | valign: Gtk.Align.CENTER,
25 | });
26 | #pickButton = new Gtk.Button({
27 | icon_name: 'find-location-symbolic',
28 | css_classes: ['flat', 'circular'],
29 | valign: Gtk.Align.CENTER,
30 | });
31 |
32 | #wmClassEntry = new Adw.EntryRow({
33 | title: _('Window class'),
34 | });
35 |
36 | constructor(cb: AppRowCallbacks) {
37 | super();
38 |
39 | this.#callbacks = cb;
40 |
41 | this.#wmClassEntry.add_prefix(this.#applyButton);
42 | this.#wmClassEntry.add_prefix(this.#pickButton);
43 | this.add_row(this.#wmClassEntry);
44 | this.add_suffix(this.#removeButton);
45 |
46 | this.bind_property(
47 | 'subtitle',
48 | this.#wmClassEntry,
49 | 'text',
50 | GObject.BindingFlags.DEFAULT,
51 | );
52 |
53 | this.add_css_class('property');
54 | this.set_title(_('Expand this row, to pick a window'));
55 |
56 | this.#removeButton.connect('clicked', () => {
57 | this.onDelete();
58 | });
59 | this.#pickButton.connect('clicked', () => {
60 | this.pickWindow(this.#wmClassEntry);
61 | });
62 | this.#applyButton.connect('clicked', () => {
63 | this.onTitleChange(this.#wmClassEntry);
64 | });
65 | }
66 |
67 | onTitleChange(entry: Adw.EntryRow) {
68 | // Skip if the title hasn't changed
69 | if (this.subtitle === entry.text || entry.text === '') {
70 | return;
71 | }
72 |
73 | if (
74 | this.#callbacks.onWindowChange(
75 | this,
76 | this.subtitle || '',
77 | entry.text || '',
78 | )
79 | ) {
80 | this.set_subtitle(entry.text || '');
81 | }
82 | }
83 |
84 | onDelete() {
85 | this.#callbacks?.onDelete(this);
86 | }
87 |
88 | pickWindow(entry: Adw.EntryRow) {
89 | onPicked(wmInstanceClass => {
90 | if (wmInstanceClass === 'window-not-found') {
91 | const win = this.root as unknown as Adw.PreferencesDialog;
92 | win.add_toast(
93 | new Adw.Toast({
94 | title: _("Can't pick window from this position"),
95 | }),
96 | );
97 | return;
98 | }
99 | entry.text = wmInstanceClass;
100 | });
101 | pick();
102 | }
103 | }
104 |
105 | export const AppRow = GObject.registerClass(
106 | {
107 | GTypeName: 'AppRow',
108 | },
109 | AppRowClass,
110 | );
111 |
112 | export type AppRowCallbacks = {
113 | onDelete: (row: AppRowClass) => void;
114 | onWindowChange: (
115 | row: AppRowClass,
116 | oldWmClass: string,
117 | newWmClass: string,
118 | ) => boolean;
119 | };
120 |
--------------------------------------------------------------------------------
/src/preferences/widgets/custom_settings_row.ts:
--------------------------------------------------------------------------------
1 | /** @file An extension of {@link AppRowClass} that adds widgets for setting config overrides. */
2 |
3 | import Adw from 'gi://Adw';
4 | import GObject from 'gi://GObject';
5 | import Gtk from 'gi://Gtk';
6 |
7 | import {PaddingsRow} from './paddings_row.js';
8 | import './app_row.js';
9 | import {gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
10 |
11 | import {type AppRowCallbacks, AppRowClass} from './app_row.js';
12 |
13 | export class CustomSettingsRowClass extends AppRowClass {
14 | enabledRow = new Adw.SwitchRow({
15 | title: _('Enabled'),
16 | });
17 |
18 | #borderColorRow = new Adw.ActionRow({
19 | title: _('Border color'),
20 | });
21 | borderColorButton = new Gtk.ColorDialogButton({
22 | valign: Gtk.Align.CENTER,
23 | });
24 | borderColorDialog = new Gtk.ColorDialog();
25 |
26 | #cornerRadiusRow = new Adw.ActionRow({
27 | title: _('Corner radius'),
28 | });
29 | cornerRadius = new Gtk.Adjustment({
30 | lower: 0,
31 | upper: 40,
32 | stepIncrement: 1,
33 | pageIncrement: 1,
34 | });
35 |
36 | #cornerSmoothingRow = new Adw.ActionRow({
37 | title: _('Corner smoothing'),
38 | });
39 | cornerSmoothing = new Gtk.Adjustment({
40 | lower: 0,
41 | upper: 1,
42 | stepIncrement: 0.1,
43 | pageIncrement: 0.1,
44 | });
45 |
46 | keepForMaximized = new Adw.SwitchRow({
47 | title: _('Keep rounded corners when maximized'),
48 | subtitle: _(
49 | 'Always clip rounded corners even if window is maximized or tiled',
50 | ),
51 | });
52 | keepForFullscreen = new Adw.SwitchRow({
53 | title: _('Keep rounded corners when in fullscreen'),
54 | subtitle: _('Always clip rounded corners even for fullscreen window'),
55 | });
56 | paddings = new PaddingsRow();
57 |
58 | constructor(cb: AppRowCallbacks) {
59 | super(cb);
60 |
61 | this.#borderColorRow.add_suffix(this.borderColorButton);
62 | this.borderColorButton.set_dialog(this.borderColorDialog);
63 |
64 | this.#cornerRadiusRow.add_suffix(
65 | new Gtk.Scale({
66 | valign: Gtk.Align.CENTER,
67 | hexpand: true,
68 | draw_value: true,
69 | value_pos: Gtk.PositionType.LEFT,
70 | round_digits: 0,
71 | digits: 0,
72 | orientation: Gtk.Orientation.HORIZONTAL,
73 | adjustment: this.cornerRadius,
74 | }),
75 | );
76 | this.#cornerSmoothingRow.add_suffix(
77 | new Gtk.Scale({
78 | valign: Gtk.Align.CENTER,
79 | hexpand: true,
80 | draw_value: true,
81 | value_pos: Gtk.PositionType.LEFT,
82 | round_digits: 1,
83 | orientation: Gtk.Orientation.HORIZONTAL,
84 | adjustment: this.cornerSmoothing,
85 | }),
86 | );
87 |
88 | this.add_row(this.enabledRow);
89 | this.add_row(this.#borderColorRow);
90 | this.add_row(this.#cornerRadiusRow);
91 | this.add_row(this.#cornerSmoothingRow);
92 | this.add_row(this.keepForMaximized);
93 | this.add_row(this.keepForFullscreen);
94 | this.add_row(this.paddings);
95 |
96 | this.checkState();
97 | }
98 |
99 | public checkState() {
100 | if (!this.enabledRow.get_active()) {
101 | this.toggleSensitivity(false);
102 | return;
103 | }
104 |
105 | if (this.subtitle === '') {
106 | this.toggleSensitivity(false);
107 | return;
108 | }
109 |
110 | this.toggleSensitivity(true);
111 | }
112 |
113 | private toggleSensitivity(state: boolean) {
114 | this.#borderColorRow.set_sensitive(state);
115 | this.#cornerRadiusRow.set_sensitive(state);
116 | this.#cornerSmoothingRow.set_sensitive(state);
117 | this.keepForMaximized.set_sensitive(state);
118 | this.keepForFullscreen.set_sensitive(state);
119 | this.paddings.set_sensitive(state);
120 | }
121 | }
122 |
123 | export const CustomSettingsRow = GObject.registerClass(
124 | {
125 | GTypeName: 'CustomSettingsRow',
126 | },
127 | CustomSettingsRowClass,
128 | );
129 |
--------------------------------------------------------------------------------
/src/preferences/widgets/paddings-row.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 |
8 |
9 | vertical
10 |
11 |
12 | Paddings
13 |
16 |
17 |
18 |
19 |
20 | true
21 | true
22 | 2
23 |
24 |
25 | Top
26 | false
27 |
28 |
29 | 0
30 | 100
31 | 10
32 | 1
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | Bottom
41 | false
42 |
43 |
44 | 0
45 | 100
46 | 10
47 | 1
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | Left
56 | false
57 |
58 |
59 | 0
60 | 100
61 | 10
62 | 1
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Right
71 | false
72 |
73 |
74 | 0
75 | 100
76 | 10
77 | 1
78 |
79 |
80 |
81 |
82 |
83 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/src/preferences/widgets/paddings_row.ts:
--------------------------------------------------------------------------------
1 | /** @file A widget for setting paddings for windows, used inside of {@link CustomSettingsRow}. */
2 |
3 | import Adw from 'gi://Adw';
4 | import GLib from 'gi://GLib';
5 | import GObject from 'gi://GObject';
6 |
7 | export class PaddingsRowClass extends Adw.PreferencesRow {
8 | public declare paddingTop: number;
9 | public declare paddingBottom: number;
10 | public declare paddingStart: number;
11 | public declare paddingEnd: number;
12 | }
13 |
14 | export const PaddingsRow = GObject.registerClass(
15 | {
16 | Template: GLib.uri_resolve_relative(
17 | import.meta.url,
18 | 'paddings-row.ui',
19 | GLib.UriFlags.NONE,
20 | ),
21 | GTypeName: 'PaddingsRow',
22 | Properties: {
23 | PaddingTop: GObject.ParamSpec.int(
24 | 'padding-top',
25 | 'Padding top',
26 | 'Padding from the top',
27 | GObject.ParamFlags.READWRITE,
28 | 0,
29 | 100,
30 | 0,
31 | ),
32 | PaddingBottom: GObject.ParamSpec.int(
33 | 'padding-bottom',
34 | 'Padding bottom',
35 | 'Padding from the bottom',
36 | GObject.ParamFlags.READWRITE,
37 | 0,
38 | 100,
39 | 0,
40 | ),
41 | PaddingStart: GObject.ParamSpec.int(
42 | 'padding-start',
43 | 'Padding start',
44 | 'Padding from the start',
45 | GObject.ParamFlags.READWRITE,
46 | 0,
47 | 100,
48 | 0,
49 | ),
50 | PaddingEnd: GObject.ParamSpec.int(
51 | 'padding-end',
52 | 'Padding end',
53 | 'Padding from the end',
54 | GObject.ParamFlags.READWRITE,
55 | 0,
56 | 100,
57 | 0,
58 | ),
59 | },
60 | },
61 | PaddingsRowClass,
62 | );
63 |
--------------------------------------------------------------------------------
/src/prefs.ts:
--------------------------------------------------------------------------------
1 | /** @file Contains the implementation of the preferences page. */
2 |
3 | import type Adw from 'gi://Adw';
4 | import GLib from 'gi://GLib';
5 | import Gdk from 'gi://Gdk';
6 | import Gtk from 'gi://Gtk';
7 |
8 | import {ExtensionPreferences} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
9 | import {prefsTabs} from './preferences/index.js';
10 | import {logDebug} from './utils/log.js';
11 | import {initPrefs, uninitPrefs} from './utils/settings.js';
12 |
13 | export default class RoundedWindowCornersRebornPrefs extends ExtensionPreferences {
14 | async fillPreferencesWindow(win: Adw.PreferencesWindow) {
15 | initPrefs(this.getSettings());
16 |
17 | for (const page of prefsTabs) {
18 | win.add(new page());
19 | }
20 |
21 | // Disconnect all signals when closing the preferences
22 | win.connect('close-request', () => {
23 | logDebug('Disconnect Signals');
24 | uninitPrefs();
25 | });
26 |
27 | this.#loadCss();
28 | }
29 |
30 | #loadCss() {
31 | const display = Gdk.Display.get_default();
32 | if (display) {
33 | const css = new Gtk.CssProvider();
34 | const path = GLib.build_filenamev([
35 | import.meta.url,
36 | 'stylesheet-prefs.css',
37 | ]);
38 | css.load_from_path(path);
39 | Gtk.StyleContext.add_provider_for_display(display, css, 0);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/utils/README.md:
--------------------------------------------------------------------------------
1 | # `utils`
2 |
3 | This directory contains functions which are used in different places throughout
4 | the codebase, so they can't be put anywhere else.
5 |
6 | ## `background_menu.ts`
7 |
8 | Handles adding and removing the RWC settings item in the desktop context menu.
9 |
10 | ## `box_shadow.ts`
11 |
12 | Contains a function for converting box shadow JS objects into CSS styles for
13 | those shadows.
14 |
15 | ## `constants.ts`
16 |
17 | Defines the constants used in the codebase.
18 |
19 | ## `file.ts`
20 |
21 | Contains utility functions for reading file contents.
22 |
23 | ## `log.ts`
24 |
25 | Provides wrapper functions for printing out debug messages.
26 |
27 | ## `settings.ts`
28 |
29 | Provides wrappers around the GSettings object that add type safety and
30 | automatically convert values between JS types and GLib Variant types that are
31 | used for storing GSettings.
32 |
33 | ## `types.ts`
34 |
35 | Provides types used throughout the codebase, mostly for storing settings.
36 |
--------------------------------------------------------------------------------
/src/utils/background_menu.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Handles adding and removing the RWC settings item in the desktop
3 | * context menu.
4 | *
5 | * XXX: It seems like this relies on GNOME Shell methods which aren't supposed
6 | * to be public. Perhaps this would be removed in the future.
7 | */
8 |
9 | import {
10 | Extension,
11 | gettext as _,
12 | } from 'resource:///org/gnome/shell/extensions/extension.js';
13 | import {PopupMenuItem} from 'resource:///org/gnome/shell/ui/popupMenu.js';
14 |
15 | import type Clutter from 'gi://Clutter';
16 | import type {PopupMenu} from 'resource:///org/gnome/shell/ui/popupMenu.js';
17 |
18 | /**
19 | * Clutter Actor of the desktop background.
20 | *
21 | * https://gjs-docs.gnome.org/meta15~15/meta.backgroundactor
22 | */
23 | type BackgroundActor = Clutter.Actor & {
24 | _backgroundMenu: PopupMenu;
25 | };
26 |
27 | /** Enable the "rounded corner settings" item in desktop context menu. */
28 | export function enableBackgroundMenuItem() {
29 | for (const background of global.windowGroup.firstChild.get_children()) {
30 | const menu = (background as BackgroundActor)._backgroundMenu;
31 | addItemToMenu(menu);
32 | }
33 | }
34 |
35 | /** Disable the "rounded corner settings" item in desktop context menu. */
36 | export function disableBackgroundMenuItem() {
37 | for (const background of global.windowGroup.firstChild.get_children()) {
38 | const menu = (background as BackgroundActor)._backgroundMenu;
39 | removeItemFromMenu(menu);
40 | }
41 | }
42 |
43 | /**
44 | * Add the menu item to the background menu.
45 | *
46 | * @param menu - BackgroundMenu to add the item to.
47 | */
48 | function addItemToMenu(menu: PopupMenu) {
49 | const rwcMenuItemName = _('Rounded Corners Settings...');
50 |
51 | // Check if the item already exists
52 | for (const item of menu._getMenuItems()) {
53 | if (
54 | item instanceof PopupMenuItem &&
55 | item.label.text === rwcMenuItemName
56 | ) {
57 | return;
58 | }
59 | }
60 |
61 | menu.addAction(rwcMenuItemName, () => {
62 | const extension = Extension.lookupByURL(import.meta.url) as Extension;
63 | extension.openPreferences();
64 | });
65 | }
66 |
67 | /**
68 | * Remove the menu item from the background menu.
69 | *
70 | * @param menu - BackgroundMenu to remove the item from.
71 | */
72 | function removeItemFromMenu(menu: PopupMenu) {
73 | const items = menu._getMenuItems();
74 | const rwcMenuItemName = _('Rounded Corners Settings...');
75 | for (const item of items) {
76 | if (
77 | item instanceof PopupMenuItem &&
78 | item.label.text === rwcMenuItemName
79 | ) {
80 | item.destroy();
81 | break;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/utils/box_shadow.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Contains a single function - {@link boxShadowCss}, which converts
3 | * {@link BoxShadow} objects into CSS code for the shadow.
4 | */
5 |
6 | import type {BoxShadow} from './types.js';
7 |
8 | /**
9 | * Generate a CSS style for a box shadow from the provided {@link BoxShadow}
10 | * object.
11 | *
12 | * @param shadow - The settings for the box shadow.
13 | * @param scale - The scale of the window, 1 by default.
14 | * @returns The box-shadow CSS string.
15 | */
16 | export function boxShadowCss(shadow: BoxShadow, scale = 1) {
17 | return `box-shadow: ${shadow.horizontalOffset * scale}px
18 | ${shadow.verticalOffset * scale}px
19 | ${shadow.blurOffset * scale}px
20 | ${shadow.spreadRadius * scale}px
21 | rgba(0,0,0, ${shadow.opacity / 100})`;
22 | }
23 |
--------------------------------------------------------------------------------
/src/utils/constants.ts:
--------------------------------------------------------------------------------
1 | /** @file Defines the constants used in this extension. */
2 |
3 | /** Name of the rounded corners effect */
4 | export const ROUNDED_CORNERS_EFFECT = 'Rounded Corners Effect';
5 |
6 | /** Name of the shadow clipping effect */
7 | export const CLIP_SHADOW_EFFECT = 'Clip Shadow Effect';
8 |
9 | /** Padding of shadow actors */
10 | export const SHADOW_PADDING = 80;
11 |
12 | /**
13 | * Hardcoded shadow size for certain applications that have to be
14 | * manually clipped
15 | */
16 | export const APP_SHADOWS = {
17 | kitty: [11, 35, 11, 11],
18 | };
19 |
20 | /** Name of shadow actor to be added in overview */
21 | export const OVERVIEW_SHADOW_ACTOR = 'Shadow Actor (Overview)';
22 |
--------------------------------------------------------------------------------
/src/utils/file.ts:
--------------------------------------------------------------------------------
1 | /** @file Contains utility functions for reading file contents. */
2 |
3 | import GLib from 'gi://GLib';
4 | import Gio from 'gi://Gio';
5 |
6 | /**
7 | * Read file contents as a string.
8 | *
9 | * @param path - The path to the file to be read.
10 | * @returns Contents of the file as a UTF-8 string.
11 | */
12 | export function readFile(path: string) {
13 | const file = Gio.File.new_for_path(path);
14 |
15 | const contents = file.load_contents(null)[1];
16 |
17 | const decoder = new TextDecoder('utf-8');
18 | return decoder.decode(contents);
19 | }
20 |
21 | /**
22 | * Read a file relative to the current module.
23 | *
24 | * @param module - `import.meta.url` of the current module.
25 | * @param path - File path relative to the current module.
26 | * @returns Contents of the file as a UTF-8 string.
27 | */
28 | export function readRelativeFile(module: string, path: string) {
29 | const basedir = GLib.path_get_dirname(module);
30 | const fileUri = GLib.build_filenamev([basedir, path]);
31 | const filePath = GLib.filename_from_uri(fileUri)[0];
32 | return readFile(filePath ?? '');
33 | }
34 |
35 | /**
36 | * Read a shader file and split it into declarations and main code, since
37 | * GNOME's `add_glsl_snippet` function takes those parts as two separate
38 | * arguments.
39 | *
40 | * @param module - `import.meta.url` of the current module.
41 | * @param path - File path relative to the current module.
42 | * @returns A list containing the declarations as the first element and
43 | * contents of the main function as the second.
44 | */
45 | export function readShader(module: string, path: string) {
46 | const shader = readRelativeFile(module, path);
47 | // This function isn't called very often, so creating the regex at the top
48 | // level doesn't really make sense.
49 | // biome-ignore lint/performance/useTopLevelRegex:
50 | let [declarations, code] = shader.split(/^.*?main\(\s?\)\s?/m);
51 | declarations = declarations.trim();
52 | code = code.trim().replace(/^[{}]/gm, '').trim();
53 | return [declarations, code];
54 | }
55 |
--------------------------------------------------------------------------------
/src/utils/log.ts:
--------------------------------------------------------------------------------
1 | /** @file Provides wrapper functions for printing out debug messages. */
2 |
3 | import {getPref} from './settings.js';
4 |
5 | /**
6 | * Log a message with a [Rounded Window Corners] prefix, but only
7 | * when debug mode is enabled.
8 | */
9 | export function logDebug(...args: unknown[]) {
10 | if (getPref('debug-mode')) {
11 | console.log(`[Rounded Window Corners] ${args}`);
12 | }
13 | }
14 |
15 | /**
16 | * Log an error with a [Rounded Window Corners] prefix.
17 | */
18 | export function logError(...args: unknown[]) {
19 | console.error(`[Rounded Window Corners] ${args}`);
20 | }
21 |
--------------------------------------------------------------------------------
/src/utils/settings.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Provides wrappers around the GSettings object that add type safety and
3 | * automatically convert values between JS types and GLib Variant types that
4 | * are used for storing GSettings.
5 | */
6 |
7 | import GLib from 'gi://GLib';
8 |
9 | import {logDebug} from './log.js';
10 |
11 | import type GObject from 'gi://GObject';
12 | import type Gio from 'gi://Gio';
13 | import type {
14 | BoxShadow,
15 | CustomRoundedCornerSettings,
16 | RoundedCornerSettings,
17 | } from './types.js';
18 |
19 | /** Mapping of schema keys to the JS representation of their type. */
20 | type Schema = {
21 | 'settings-version': number;
22 | blacklist: string[];
23 | 'skip-libadwaita-app': boolean;
24 | 'skip-libhandy-app': boolean;
25 | 'border-width': number;
26 | 'global-rounded-corner-settings': RoundedCornerSettings;
27 | 'custom-rounded-corner-settings': CustomRoundedCornerSettings;
28 | 'focused-shadow': BoxShadow;
29 | 'unfocused-shadow': BoxShadow;
30 | 'debug-mode': boolean;
31 | 'tweak-kitty-terminal': boolean;
32 | 'enable-preferences-entry': boolean;
33 | };
34 |
35 | /** All existing schema keys. */
36 | export type SchemaKey = keyof Schema;
37 |
38 | /** Mapping of schema keys to their GLib Variant type string */
39 | export const Schema = {
40 | 'settings-version': 'u',
41 | blacklist: 'as',
42 | 'skip-libadwaita-app': 'b',
43 | 'skip-libhandy-app': 'b',
44 | 'border-width': 'i',
45 | 'global-rounded-corner-settings': 'a{sv}',
46 | 'custom-rounded-corner-settings': 'a{sv}',
47 | 'focused-shadow': 'a{si}',
48 | 'unfocused-shadow': 'a{si}',
49 | 'debug-mode': 'b',
50 | 'tweak-kitty-terminal': 'b',
51 | 'enable-preferences-entry': 'b',
52 | };
53 |
54 | /** The raw GSettings object for direct manipulation. */
55 | export let prefs: Gio.Settings;
56 |
57 | /**
58 | * Initialize the {@link prefs} object with existing GSettings.
59 | *
60 | * @param gSettings - GSettings to initialize the prefs with.
61 | */
62 | export function initPrefs(gSettings: Gio.Settings) {
63 | resetOutdated(gSettings);
64 | prefs = gSettings;
65 | }
66 |
67 | /** Delete the {@link prefs} object for garbage collection. */
68 | export function uninitPrefs() {
69 | (prefs as Gio.Settings | null) = null;
70 | }
71 |
72 | /**
73 | * Get a preference from GSettings and convert it from a GLib Variant to a
74 | * JavaScript type.
75 | *
76 | * @param key - The key of the preference to get.
77 | * @returns The value of the preference.
78 | */
79 | export function getPref(key: K): Schema[K] {
80 | return prefs.get_value(key).recursiveUnpack();
81 | }
82 |
83 | /**
84 | * Pack a value into a GLib Variant type and store it in GSettings.
85 | *
86 | * @param key - The key of the preference to set.
87 | * @param value - The value to set the preference to.
88 | */
89 | export function setPref(key: K, value: Schema[K]) {
90 | logDebug(`Settings pref: ${key}, ${value}`);
91 | let variant: GLib.Variant;
92 |
93 | if (key === 'global-rounded-corner-settings') {
94 | variant = packRoundedCornerSettings(value as RoundedCornerSettings);
95 | } else if (key === 'custom-rounded-corner-settings') {
96 | variant = packCustomRoundedCornerSettings(
97 | value as CustomRoundedCornerSettings,
98 | );
99 | } else {
100 | variant = new GLib.Variant(Schema[key], value);
101 | }
102 |
103 | prefs.set_value(key, variant);
104 | }
105 |
106 | /** A simple type-checked wrapper around {@link prefs.bind} */
107 | export function bindPref(
108 | key: SchemaKey,
109 | object: GObject.Object,
110 | property: string,
111 | flags: Gio.SettingsBindFlags,
112 | ) {
113 | prefs.bind(key, object, property, flags);
114 | }
115 |
116 | /**
117 | * Reset setting keys that changed their type between releases
118 | * to avoid conflicts.
119 | *
120 | * @param prefs the GSettings object to clean.
121 | */
122 | function resetOutdated(prefs: Gio.Settings) {
123 | const lastVersion = 7;
124 | const currentVersion = prefs
125 | .get_user_value('settings-version')
126 | ?.recursiveUnpack();
127 |
128 | if (!currentVersion || currentVersion < lastVersion) {
129 | if (prefs.list_keys().includes('black-list')) {
130 | prefs.reset('black-list');
131 | }
132 | prefs.reset('global-rounded-corner-settings');
133 | prefs.reset('custom-rounded-corner-settings');
134 | if (prefs.list_keys().includes('border-color')) {
135 | prefs.reset('border-color');
136 | }
137 | prefs.reset('focused-shadow');
138 | prefs.reset('unfocused-shadow');
139 | prefs.set_uint('settings-version', lastVersion);
140 | }
141 | }
142 |
143 | /**
144 | * Pack rounded corner settings into a GLib Variant object.
145 | *
146 | * Since rounded corner settings are stored as a dictionary where the values
147 | * are of different types, it can't be automatically packed into a variant.
148 | * Instead, we need to pack each of the values into the correct variant
149 | * type, and only then pack the entire dictionary into a variant with type
150 | * "a{sv}" (dictionary with string keys and arbitrary variant values).
151 | *
152 | * @param settings - The rounded corner settings to pack.
153 | * @returns The packed GLib Variant object.
154 | */
155 | function packRoundedCornerSettings(settings: RoundedCornerSettings) {
156 | const padding = new GLib.Variant('a{su}', settings.padding);
157 | const keepRoundedCorners = new GLib.Variant(
158 | 'a{sb}',
159 | settings.keepRoundedCorners,
160 | );
161 | const borderRadius = GLib.Variant.new_uint32(settings.borderRadius);
162 | const smoothing = GLib.Variant.new_double(settings.smoothing);
163 | const borderColor = new GLib.Variant('(dddd)', settings.borderColor);
164 | const enabled = GLib.Variant.new_boolean(settings.enabled);
165 |
166 | const variantObject = {
167 | padding: padding,
168 | keepRoundedCorners: keepRoundedCorners,
169 | borderRadius: borderRadius,
170 | smoothing: smoothing,
171 | borderColor: borderColor,
172 | enabled: enabled,
173 | };
174 |
175 | return new GLib.Variant('a{sv}', variantObject);
176 | }
177 |
178 | /**
179 | * Pack custom rounded corner overrides into a GLib Variant object.
180 | *
181 | * Custom rounded corner settings are stored as a dictionary from window
182 | * wm_class to {@link RoundedCornerSettings} objects. See the documentation for
183 | * {@link packRoundedCornerSettings} for more information on why manual packing
184 | * is needed here.
185 | *
186 | * @param settings - The custom rounded corner setting overrides to pack.
187 | * @returns The packed GLib Variant object.
188 | */
189 | function packCustomRoundedCornerSettings(
190 | settings: CustomRoundedCornerSettings,
191 | ) {
192 | const packedSettings: Record> = {};
193 | for (const [wmClass, windowSettings] of Object.entries(settings)) {
194 | packedSettings[wmClass] = packRoundedCornerSettings(windowSettings);
195 | }
196 |
197 | const variant = new GLib.Variant('a{sv}', packedSettings);
198 | return variant;
199 | }
200 |
--------------------------------------------------------------------------------
/src/utils/types.ts:
--------------------------------------------------------------------------------
1 | /** @file Provides types used throughout the codebase, mostly for storing settings. */
2 |
3 | import type Meta from 'gi://Meta';
4 | import type St from 'gi://St';
5 |
6 | /** Bounds of rounded corners */
7 | export type Bounds = {
8 | x1: number;
9 | y1: number;
10 | x2: number;
11 | y2: number;
12 | };
13 |
14 | /** Settings for corner rounding. */
15 | export type RoundedCornerSettings = {
16 | keepRoundedCorners: {
17 | maximized: boolean;
18 | fullscreen: boolean;
19 | };
20 | borderRadius: number;
21 | smoothing: number;
22 | padding: {
23 | left: number;
24 | right: number;
25 | top: number;
26 | bottom: number;
27 | };
28 | borderColor: [number, number, number, number];
29 | enabled: boolean;
30 | };
31 |
32 | /** Rounded corner settings exceptions for specific windows. */
33 | export type CustomRoundedCornerSettings = {
34 | [wmClass: string]: RoundedCornerSettings;
35 | };
36 |
37 | /** Window shadow properties. */
38 | export type BoxShadow = {
39 | opacity: number;
40 | spreadRadius: number;
41 | blurOffset: number;
42 | verticalOffset: number;
43 | horizontalOffset: number;
44 | };
45 |
46 | /**
47 | * A window actor with rounded corners.
48 | *
49 | * This type is needed to store extra custom properties on a window actor.
50 | */
51 | export type RoundedWindowActor = Meta.WindowActor & {
52 | rwcCustomData?: {
53 | shadow: St.Bin;
54 | unminimizedTimeoutId: number;
55 | };
56 | };
57 |
--------------------------------------------------------------------------------
/src/window_picker/README.md:
--------------------------------------------------------------------------------
1 | # `window_picker`
2 |
3 | The extensions preferences window runs in a separate isolated process which has
4 | no access to GNOME Shell methods. However, the window picking functionality is
5 | based on GNOME Shell's Looking Glass.
6 |
7 | To allow the preferences window to communicate with the main process, the code
8 | in this directory creates a DBus service, which has a method to open the window
9 | picker and a signal to transmit the class of the selected window.
10 |
11 | ## `iface.xml`
12 |
13 | Defines the DBus interface for the window picker.
14 |
15 | ## `service.ts`
16 |
17 | Contains the implementation of the DBus interface.
18 |
19 | ## `client.ts`
20 |
21 | Provides wrapper JavaScript functions around the DBus method calls.
22 |
--------------------------------------------------------------------------------
/src/window_picker/client.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file This file provides wrapper functions around the DBus window picker
3 | * interface.
4 | */
5 |
6 | import Gio from 'gi://Gio';
7 |
8 | const connection = Gio.DBus.session;
9 | const busName = 'org.gnome.Shell';
10 | const interfaceName = 'org.gnome.Shell.Extensions.RoundedWindowCorners';
11 | const objectPath = '/org/gnome/shell/extensions/RoundedWindowCorners';
12 |
13 | /** Open the window picker and select a window. */
14 | export function pick() {
15 | connection.call(
16 | busName,
17 | objectPath,
18 | interfaceName,
19 | 'pick',
20 | null,
21 | null,
22 | Gio.DBusCallFlags.NO_AUTO_START,
23 | -1,
24 | null,
25 | null,
26 | );
27 | }
28 |
29 | /**
30 | * Connect a callback to the `picked` signal, which is emitted when a window
31 | * is picked.
32 | *
33 | * @param callback - The function to execute when the window is picked.
34 | */
35 | export function onPicked(callback: (wmInstanceClass: string) => void) {
36 | const id = connection.signal_subscribe(
37 | busName,
38 | interfaceName,
39 | 'picked',
40 | objectPath,
41 | null,
42 | Gio.DBusSignalFlags.NONE,
43 | (_conn, _sender, _objectPath, _iface, _signal, params) => {
44 | const val = params.get_child_value(0);
45 | callback(val.get_string()[0]);
46 | connection.signal_unsubscribe(id);
47 | },
48 | );
49 | }
50 |
--------------------------------------------------------------------------------
/src/window_picker/iface.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/window_picker/service.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file This file contains the implementation of the DBus interface for the
3 | * window picker. See the {@link WindowPicker} class for more information.
4 | */
5 |
6 | import GLib from 'gi://GLib';
7 | import Gio from 'gi://Gio';
8 | import Meta from 'gi://Meta';
9 |
10 | import {Inspector} from 'resource:///org/gnome/shell/ui/lookingGlass.js';
11 | import * as Main from 'resource:///org/gnome/shell/ui/main.js';
12 |
13 | import {readRelativeFile} from '../utils/file.js';
14 | import {logDebug} from '../utils/log.js';
15 |
16 | /**
17 | * This class provides the implementation of the DBus interface for the window
18 | * picker. It implements a single method - `pick` - which opens the window picker
19 | * and allows the user to select a window.
20 | */
21 | export class WindowPicker {
22 | #iface = readRelativeFile(import.meta.url, 'iface.xml');
23 | #dbus = Gio.DBusExportedObject.wrapJSObject(this.#iface, this);
24 |
25 | /** Emit the wm_class of the picked window to the `picked` signal. */
26 | #sendPickedWindow(wmClass: string) {
27 | this.#dbus.emit_signal('picked', new GLib.Variant('(s)', [wmClass]));
28 | }
29 |
30 | /**
31 | * Open the window picker and select a window.
32 | *
33 | * This uses the window picker from GNOME's Looking Glass. This is the
34 | * easiest way to pick a window, and this is also what's used by other
35 | * extensions such as Blur my Shell.
36 | */
37 | pick() {
38 | const lookingGlass = Main.createLookingGlass();
39 | const inspector = new Inspector(lookingGlass);
40 |
41 | inspector.connect('target', (me, target, x, y) => {
42 | logDebug(`${me}: pick ${target} in ${x}, ${y}`);
43 |
44 | // Remove the red border effect when the window is picked.
45 | const effectName = 'lookingGlass_RedBorderEffect';
46 | for (const effect of target.get_effects()) {
47 | if (effect.toString().includes(effectName)) {
48 | target.remove_effect(effect);
49 | }
50 | }
51 |
52 | let actor = target;
53 |
54 | // If the picked actor is not a Meta.WindowActor, which happens
55 | // often since it's usually a Meta.SurfaceActor, try to find its
56 | // parent which is a Meta.WindowActor.
57 | for (let i = 0; i < 2; i++) {
58 | if (actor == null || actor instanceof Meta.WindowActor) {
59 | break;
60 | }
61 | actor = actor.get_parent();
62 | }
63 |
64 | if (!(actor instanceof Meta.WindowActor)) {
65 | this.#sendPickedWindow('window-not-found');
66 | return;
67 | }
68 |
69 | this.#sendPickedWindow(
70 | actor.metaWindow.get_wm_class_instance() ?? 'window-not-found',
71 | );
72 | });
73 |
74 | inspector.connect('closed', () => {
75 | lookingGlass.close();
76 | });
77 | }
78 |
79 | export() {
80 | this.#dbus.export(
81 | Gio.DBus.session,
82 | '/org/gnome/shell/extensions/RoundedWindowCorners',
83 | );
84 | logDebug('DBus Service exported');
85 | }
86 |
87 | unexport() {
88 | this.#dbus.unexport();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "esnext",
5 | "moduleResolution": "bundler",
6 | "sourceMap": false,
7 | "strict": true,
8 | "skipLibCheck": true,
9 | "outDir": "./_build/"
10 | },
11 | "include": ["src/**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------