KWin
Loading...
Searching...
No Matches
options.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
7 SPDX-FileCopyrightText: 2012 Martin Gräßlin <m.graesslin@kde.org>
8
9 SPDX-License-Identifier: GPL-2.0-or-later
10*/
11#include "options.h"
12
13#include "config-kwin.h"
14
15#include "utils/common.h"
16
17#ifndef KCMRULES
18
19#include <QProcess>
20
21#include "settings.h"
22#include "workspace.h"
23#include <QOpenGLContext>
24
25#endif // KCMRULES
26
27namespace KWin
28{
29
30#ifndef KCMRULES
31
32Options::Options(QObject *parent)
33 : QObject(parent)
34 , m_settings(new Settings(kwinApp()->config()))
35 , m_focusPolicy(ClickToFocus)
36 , m_nextFocusPrefersMouse(false)
37 , m_clickRaise(false)
38 , m_autoRaise(false)
39 , m_autoRaiseInterval(0)
40 , m_delayFocusInterval(0)
41 , m_shadeHover(false)
42 , m_shadeHoverInterval(0)
43 , m_separateScreenFocus(false)
44 , m_activeMouseScreen(false)
45 , m_placement(PlacementNone)
46 , m_activationDesktopPolicy(Options::defaultActivationDesktopPolicy())
47 , m_borderSnapZone(0)
48 , m_windowSnapZone(0)
49 , m_centerSnapZone(0)
50 , m_snapOnlyWhenOverlapping(false)
51 , m_rollOverDesktops(false)
52 , m_focusStealingPreventionLevel(0)
53 , m_killPingTimeout(0)
54 , m_hideUtilityWindowsForInactive(false)
55 , m_xwaylandCrashPolicy(Options::defaultXwaylandCrashPolicy())
56 , m_xwaylandMaxCrashCount(Options::defaultXwaylandMaxCrashCount())
57 , m_xwaylandEavesdrops(Options::defaultXwaylandEavesdrops())
58 , m_compositingMode(Options::defaultCompositingMode())
59 , m_useCompositing(Options::defaultUseCompositing())
60 , m_hiddenPreviews(Options::defaultHiddenPreviews())
61 , m_glSmoothScale(Options::defaultGlSmoothScale())
62 , m_glStrictBinding(Options::defaultGlStrictBinding())
63 , m_glStrictBindingFollowsDriver(Options::defaultGlStrictBindingFollowsDriver())
64 , m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap())
65 , m_glPlatformInterface(Options::defaultGlPlatformInterface())
66 , m_windowsBlockCompositing(true)
67 , OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick())
68 , CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1())
69 , CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2())
70 , CmdActiveTitlebar3(Options::defaultCommandActiveTitlebar3())
71 , CmdInactiveTitlebar1(Options::defaultCommandInactiveTitlebar1())
72 , CmdInactiveTitlebar2(Options::defaultCommandInactiveTitlebar2())
73 , CmdInactiveTitlebar3(Options::defaultCommandInactiveTitlebar3())
74 , CmdTitlebarWheel(Options::defaultCommandTitlebarWheel())
75 , CmdWindow1(Options::defaultCommandWindow1())
76 , CmdWindow2(Options::defaultCommandWindow2())
77 , CmdWindow3(Options::defaultCommandWindow3())
78 , CmdWindowWheel(Options::defaultCommandWindowWheel())
79 , CmdAll1(Options::defaultCommandAll1())
80 , CmdAll2(Options::defaultCommandAll2())
81 , CmdAll3(Options::defaultCommandAll3())
82 , CmdAllWheel(Options::defaultCommandAllWheel())
83 , CmdAllModKey(Options::defaultKeyCmdAllModKey())
84 , electric_border_maximize(false)
85 , electric_border_tiling(false)
86 , electric_border_corner_ratio(0.0)
87 , borderless_maximized_windows(false)
88 , condensed_title(false)
89{
90 m_settings->setDefaults();
91
92 loadConfig();
93
94 m_configWatcher = KConfigWatcher::create(m_settings->sharedConfig());
95 connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) {
96 if (group.name() == QLatin1String("KDE") && names.contains(QByteArrayLiteral("AnimationDurationFactor"))) {
97 m_settings->load();
98 Q_EMIT animationSpeedChanged();
99 } else if (group.name() == QLatin1String("Xwayland")) {
101 }
102 });
103}
104
105Options::~Options()
106{
107}
108
109void Options::setFocusPolicy(FocusPolicy focusPolicy)
110{
111 if (m_focusPolicy == focusPolicy) {
112 return;
113 }
114 m_focusPolicy = focusPolicy;
115 Q_EMIT focusPolicyChanged();
116 if (m_focusPolicy == ClickToFocus) {
117 setAutoRaise(false);
118 setAutoRaiseInterval(0);
119 setDelayFocusInterval(0);
120 }
121}
122
123void Options::setNextFocusPrefersMouse(bool nextFocusPrefersMouse)
124{
125 if (m_nextFocusPrefersMouse == nextFocusPrefersMouse) {
126 return;
127 }
128 m_nextFocusPrefersMouse = nextFocusPrefersMouse;
129 Q_EMIT nextFocusPrefersMouseChanged();
130}
131
132void Options::setXwaylandCrashPolicy(XwaylandCrashPolicy crashPolicy)
133{
134 if (m_xwaylandCrashPolicy == crashPolicy) {
135 return;
136 }
137 m_xwaylandCrashPolicy = crashPolicy;
138 Q_EMIT xwaylandCrashPolicyChanged();
139}
140
141void Options::setXwaylandMaxCrashCount(int maxCrashCount)
142{
143 if (m_xwaylandMaxCrashCount == maxCrashCount) {
144 return;
145 }
146 m_xwaylandMaxCrashCount = maxCrashCount;
147 Q_EMIT xwaylandMaxCrashCountChanged();
148}
149
150void Options::setXwaylandEavesdrops(XwaylandEavesdropsMode mode)
151{
152 if (m_xwaylandEavesdrops == mode) {
153 return;
154 }
155 m_xwaylandEavesdrops = mode;
156 Q_EMIT xwaylandEavesdropsChanged();
157}
158
159void Options::setClickRaise(bool clickRaise)
160{
161 if (m_autoRaise) {
162 // important: autoRaise implies ClickRaise
163 clickRaise = true;
164 }
165 if (m_clickRaise == clickRaise) {
166 return;
167 }
168 m_clickRaise = clickRaise;
169 Q_EMIT clickRaiseChanged();
170}
171
172void Options::setAutoRaise(bool autoRaise)
173{
174 if (m_focusPolicy == ClickToFocus) {
175 autoRaise = false;
176 }
177 if (m_autoRaise == autoRaise) {
178 return;
179 }
180 m_autoRaise = autoRaise;
181 if (m_autoRaise) {
182 // important: autoRaise implies ClickRaise
183 setClickRaise(true);
184 }
185 Q_EMIT autoRaiseChanged();
186}
187
188void Options::setAutoRaiseInterval(int autoRaiseInterval)
189{
190 if (m_focusPolicy == ClickToFocus) {
191 autoRaiseInterval = 0;
192 }
193 if (m_autoRaiseInterval == autoRaiseInterval) {
194 return;
195 }
196 m_autoRaiseInterval = autoRaiseInterval;
197 Q_EMIT autoRaiseIntervalChanged();
198}
199
200void Options::setDelayFocusInterval(int delayFocusInterval)
201{
202 if (m_focusPolicy == ClickToFocus) {
203 delayFocusInterval = 0;
204 }
205 if (m_delayFocusInterval == delayFocusInterval) {
206 return;
207 }
208 m_delayFocusInterval = delayFocusInterval;
209 Q_EMIT delayFocusIntervalChanged();
210}
211
212void Options::setShadeHover(bool shadeHover)
213{
214 if (m_shadeHover == shadeHover) {
215 return;
216 }
217 m_shadeHover = shadeHover;
218 Q_EMIT shadeHoverChanged();
219}
220
221void Options::setShadeHoverInterval(int shadeHoverInterval)
222{
223 if (m_shadeHoverInterval == shadeHoverInterval) {
224 return;
225 }
226 m_shadeHoverInterval = shadeHoverInterval;
227 Q_EMIT shadeHoverIntervalChanged();
228}
229
230void Options::setSeparateScreenFocus(bool separateScreenFocus)
231{
232 if (m_separateScreenFocus == separateScreenFocus) {
233 return;
234 }
235 m_separateScreenFocus = separateScreenFocus;
236 Q_EMIT separateScreenFocusChanged(m_separateScreenFocus);
237}
238
239void Options::setActiveMouseScreen(bool activeMouseScreen)
240{
241 if (m_activeMouseScreen == activeMouseScreen) {
242 return;
243 }
244 m_activeMouseScreen = activeMouseScreen;
245 Q_EMIT activeMouseScreenChanged();
246}
247
248void Options::setPlacement(PlacementPolicy placement)
249{
250 if (m_placement == placement) {
251 return;
252 }
253 m_placement = placement;
254 Q_EMIT placementChanged();
255}
256
257void Options::setActivationDesktopPolicy(ActivationDesktopPolicy activationDesktopPolicy)
258{
259 if (m_activationDesktopPolicy == activationDesktopPolicy) {
260 return;
261 }
262 m_activationDesktopPolicy = activationDesktopPolicy;
263 Q_EMIT activationDesktopPolicyChanged();
264}
265
266void Options::setBorderSnapZone(int borderSnapZone)
267{
268 if (m_borderSnapZone == borderSnapZone) {
269 return;
270 }
271 m_borderSnapZone = borderSnapZone;
272 Q_EMIT borderSnapZoneChanged();
273}
274
275void Options::setWindowSnapZone(int windowSnapZone)
276{
277 if (m_windowSnapZone == windowSnapZone) {
278 return;
279 }
280 m_windowSnapZone = windowSnapZone;
281 Q_EMIT windowSnapZoneChanged();
282}
283
284void Options::setCenterSnapZone(int centerSnapZone)
285{
286 if (m_centerSnapZone == centerSnapZone) {
287 return;
288 }
289 m_centerSnapZone = centerSnapZone;
290 Q_EMIT centerSnapZoneChanged();
291}
292
293void Options::setSnapOnlyWhenOverlapping(bool snapOnlyWhenOverlapping)
294{
295 if (m_snapOnlyWhenOverlapping == snapOnlyWhenOverlapping) {
296 return;
297 }
298 m_snapOnlyWhenOverlapping = snapOnlyWhenOverlapping;
299 Q_EMIT snapOnlyWhenOverlappingChanged();
300}
301
302void Options::setRollOverDesktops(bool rollOverDesktops)
303{
304 if (m_rollOverDesktops == rollOverDesktops) {
305 return;
306 }
307 m_rollOverDesktops = rollOverDesktops;
308 Q_EMIT rollOverDesktopsChanged(m_rollOverDesktops);
309}
310
311void Options::setFocusStealingPreventionLevel(int focusStealingPreventionLevel)
312{
313 if (!focusPolicyIsReasonable()) {
314 focusStealingPreventionLevel = 0;
315 }
316 if (m_focusStealingPreventionLevel == focusStealingPreventionLevel) {
317 return;
318 }
319 m_focusStealingPreventionLevel = std::max(0, std::min(4, focusStealingPreventionLevel));
320 Q_EMIT focusStealingPreventionLevelChanged();
321}
322
323void Options::setOperationTitlebarDblClick(WindowOperation operationTitlebarDblClick)
324{
325 if (OpTitlebarDblClick == operationTitlebarDblClick) {
326 return;
327 }
328 OpTitlebarDblClick = operationTitlebarDblClick;
329 Q_EMIT operationTitlebarDblClickChanged();
330}
331
332void Options::setOperationMaxButtonLeftClick(WindowOperation op)
333{
334 if (opMaxButtonLeftClick == op) {
335 return;
336 }
337 opMaxButtonLeftClick = op;
338 Q_EMIT operationMaxButtonLeftClickChanged();
339}
340
341void Options::setOperationMaxButtonRightClick(WindowOperation op)
342{
343 if (opMaxButtonRightClick == op) {
344 return;
345 }
346 opMaxButtonRightClick = op;
347 Q_EMIT operationMaxButtonRightClickChanged();
348}
349
350void Options::setOperationMaxButtonMiddleClick(WindowOperation op)
351{
352 if (opMaxButtonMiddleClick == op) {
353 return;
354 }
355 opMaxButtonMiddleClick = op;
356 Q_EMIT operationMaxButtonMiddleClickChanged();
357}
358
359void Options::setCommandActiveTitlebar1(MouseCommand commandActiveTitlebar1)
360{
361 if (CmdActiveTitlebar1 == commandActiveTitlebar1) {
362 return;
363 }
364 CmdActiveTitlebar1 = commandActiveTitlebar1;
365 Q_EMIT commandActiveTitlebar1Changed();
366}
367
368void Options::setCommandActiveTitlebar2(MouseCommand commandActiveTitlebar2)
369{
370 if (CmdActiveTitlebar2 == commandActiveTitlebar2) {
371 return;
372 }
373 CmdActiveTitlebar2 = commandActiveTitlebar2;
374 Q_EMIT commandActiveTitlebar2Changed();
375}
376
377void Options::setCommandActiveTitlebar3(MouseCommand commandActiveTitlebar3)
378{
379 if (CmdActiveTitlebar3 == commandActiveTitlebar3) {
380 return;
381 }
382 CmdActiveTitlebar3 = commandActiveTitlebar3;
383 Q_EMIT commandActiveTitlebar3Changed();
384}
385
386void Options::setCommandInactiveTitlebar1(MouseCommand commandInactiveTitlebar1)
387{
388 if (CmdInactiveTitlebar1 == commandInactiveTitlebar1) {
389 return;
390 }
391 CmdInactiveTitlebar1 = commandInactiveTitlebar1;
392 Q_EMIT commandInactiveTitlebar1Changed();
393}
394
395void Options::setCommandInactiveTitlebar2(MouseCommand commandInactiveTitlebar2)
396{
397 if (CmdInactiveTitlebar2 == commandInactiveTitlebar2) {
398 return;
399 }
400 CmdInactiveTitlebar2 = commandInactiveTitlebar2;
401 Q_EMIT commandInactiveTitlebar2Changed();
402}
403
404void Options::setCommandInactiveTitlebar3(MouseCommand commandInactiveTitlebar3)
405{
406 if (CmdInactiveTitlebar3 == commandInactiveTitlebar3) {
407 return;
408 }
409 CmdInactiveTitlebar3 = commandInactiveTitlebar3;
410 Q_EMIT commandInactiveTitlebar3Changed();
411}
412
413void Options::setCommandWindow1(MouseCommand commandWindow1)
414{
415 if (CmdWindow1 == commandWindow1) {
416 return;
417 }
418 CmdWindow1 = commandWindow1;
419 Q_EMIT commandWindow1Changed();
420}
421
422void Options::setCommandWindow2(MouseCommand commandWindow2)
423{
424 if (CmdWindow2 == commandWindow2) {
425 return;
426 }
427 CmdWindow2 = commandWindow2;
428 Q_EMIT commandWindow2Changed();
429}
430
431void Options::setCommandWindow3(MouseCommand commandWindow3)
432{
433 if (CmdWindow3 == commandWindow3) {
434 return;
435 }
436 CmdWindow3 = commandWindow3;
437 Q_EMIT commandWindow3Changed();
438}
439
440void Options::setCommandWindowWheel(MouseCommand commandWindowWheel)
441{
442 if (CmdWindowWheel == commandWindowWheel) {
443 return;
444 }
445 CmdWindowWheel = commandWindowWheel;
446 Q_EMIT commandWindowWheelChanged();
447}
448
449void Options::setCommandAll1(MouseCommand commandAll1)
450{
451 if (CmdAll1 == commandAll1) {
452 return;
453 }
454 CmdAll1 = commandAll1;
455 Q_EMIT commandAll1Changed();
456}
457
458void Options::setCommandAll2(MouseCommand commandAll2)
459{
460 if (CmdAll2 == commandAll2) {
461 return;
462 }
463 CmdAll2 = commandAll2;
464 Q_EMIT commandAll2Changed();
465}
466
467void Options::setCommandAll3(MouseCommand commandAll3)
468{
469 if (CmdAll3 == commandAll3) {
470 return;
471 }
472 CmdAll3 = commandAll3;
473 Q_EMIT commandAll3Changed();
474}
475
476void Options::setKeyCmdAllModKey(uint keyCmdAllModKey)
477{
478 if (CmdAllModKey == keyCmdAllModKey) {
479 return;
480 }
481 CmdAllModKey = keyCmdAllModKey;
482 Q_EMIT keyCmdAllModKeyChanged();
483}
484
485void Options::setCondensedTitle(bool condensedTitle)
486{
487 if (condensed_title == condensedTitle) {
488 return;
489 }
490 condensed_title = condensedTitle;
491 Q_EMIT condensedTitleChanged();
492}
493
494void Options::setElectricBorderMaximize(bool electricBorderMaximize)
495{
496 if (electric_border_maximize == electricBorderMaximize) {
497 return;
498 }
499 electric_border_maximize = electricBorderMaximize;
500 Q_EMIT electricBorderMaximizeChanged();
501}
502
503void Options::setElectricBorderTiling(bool electricBorderTiling)
504{
505 if (electric_border_tiling == electricBorderTiling) {
506 return;
507 }
508 electric_border_tiling = electricBorderTiling;
509 Q_EMIT electricBorderTilingChanged();
510}
511
512void Options::setElectricBorderCornerRatio(float electricBorderCornerRatio)
513{
514 if (electric_border_corner_ratio == electricBorderCornerRatio) {
515 return;
516 }
517 electric_border_corner_ratio = electricBorderCornerRatio;
518 Q_EMIT electricBorderCornerRatioChanged();
519}
520
521void Options::setBorderlessMaximizedWindows(bool borderlessMaximizedWindows)
522{
523 if (borderless_maximized_windows == borderlessMaximizedWindows) {
524 return;
525 }
526 borderless_maximized_windows = borderlessMaximizedWindows;
527 Q_EMIT borderlessMaximizedWindowsChanged();
528}
529
530void Options::setKillPingTimeout(int killPingTimeout)
531{
532 if (m_killPingTimeout == killPingTimeout) {
533 return;
534 }
535 m_killPingTimeout = killPingTimeout;
536 Q_EMIT killPingTimeoutChanged();
537}
538
539void Options::setHideUtilityWindowsForInactive(bool hideUtilityWindowsForInactive)
540{
541 if (m_hideUtilityWindowsForInactive == hideUtilityWindowsForInactive) {
542 return;
543 }
544 m_hideUtilityWindowsForInactive = hideUtilityWindowsForInactive;
545 Q_EMIT hideUtilityWindowsForInactiveChanged();
546}
547
548void Options::setCompositingMode(int compositingMode)
549{
550 if (m_compositingMode == static_cast<CompositingType>(compositingMode)) {
551 return;
552 }
553 m_compositingMode = static_cast<CompositingType>(compositingMode);
554 Q_EMIT compositingModeChanged();
555}
556
557void Options::setUseCompositing(bool useCompositing)
558{
559 if (m_useCompositing == useCompositing) {
560 return;
561 }
562 m_useCompositing = useCompositing;
563 Q_EMIT useCompositingChanged();
564}
565
566void Options::setHiddenPreviews(int hiddenPreviews)
567{
568 if (m_hiddenPreviews == static_cast<HiddenPreviews>(hiddenPreviews)) {
569 return;
570 }
571 m_hiddenPreviews = static_cast<HiddenPreviews>(hiddenPreviews);
572 Q_EMIT hiddenPreviewsChanged();
573}
574
575void Options::setGlSmoothScale(int glSmoothScale)
576{
577 if (m_glSmoothScale == glSmoothScale) {
578 return;
579 }
580 m_glSmoothScale = glSmoothScale;
581 Q_EMIT glSmoothScaleChanged();
582}
583
584void Options::setGlStrictBinding(bool glStrictBinding)
585{
586 if (m_glStrictBinding == glStrictBinding) {
587 return;
588 }
589 m_glStrictBinding = glStrictBinding;
590 Q_EMIT glStrictBindingChanged();
591}
592
593void Options::setGlStrictBindingFollowsDriver(bool glStrictBindingFollowsDriver)
594{
595 if (m_glStrictBindingFollowsDriver == glStrictBindingFollowsDriver) {
596 return;
597 }
598 m_glStrictBindingFollowsDriver = glStrictBindingFollowsDriver;
599 Q_EMIT glStrictBindingFollowsDriverChanged();
600}
601
602void Options::setWindowsBlockCompositing(bool value)
603{
604 if (m_windowsBlockCompositing == value) {
605 return;
606 }
607 m_windowsBlockCompositing = value;
608 Q_EMIT windowsBlockCompositingChanged();
609}
610
611void Options::setGlPreferBufferSwap(char glPreferBufferSwap)
612{
613 if (m_glPreferBufferSwap == (GlSwapStrategy)glPreferBufferSwap) {
614 return;
615 }
616 m_glPreferBufferSwap = (GlSwapStrategy)glPreferBufferSwap;
617 Q_EMIT glPreferBufferSwapChanged();
618}
619
620bool Options::allowTearing() const
621{
622 return m_allowTearing;
623}
624
625void Options::setAllowTearing(bool allow)
626{
627 if (allow != m_allowTearing) {
628 m_allowTearing = allow;
629 Q_EMIT allowTearingChanged();
630 }
631}
632
633void Options::setGlPlatformInterface(OpenGLPlatformInterface interface)
634{
635 // check environment variable
636 const QByteArray envOpenGLInterface(qgetenv("KWIN_OPENGL_INTERFACE"));
637 if (!envOpenGLInterface.isEmpty()) {
638 if (qstrcmp(envOpenGLInterface, "egl") == 0) {
639 qCDebug(KWIN_CORE) << "Forcing EGL native interface through environment variable";
640 interface = EglPlatformInterface;
641 } else if (qstrcmp(envOpenGLInterface, "glx") == 0) {
642 qCDebug(KWIN_CORE) << "Forcing GLX native interface through environment variable";
643 interface = GlxPlatformInterface;
644 }
645 }
646 if (kwinApp()->shouldUseWaylandForCompositing() && interface == GlxPlatformInterface) {
647 // Glx is impossible on Wayland, enforce egl
648 qCDebug(KWIN_CORE) << "Forcing EGL native interface for Wayland mode";
649 interface = EglPlatformInterface;
650 }
651#if !HAVE_GLX
652 qCDebug(KWIN_CORE) << "Forcing EGL native interface as compiled without GLX support";
653 interface = EglPlatformInterface;
654#endif
655 if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
656 qCDebug(KWIN_CORE) << "Forcing EGL native interface as Qt uses OpenGL ES";
657 interface = EglPlatformInterface;
658 } else if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) {
659 qCDebug(KWIN_CORE) << "Forcing EGL native interface as OpenGL ES requested through KWIN_COMPOSE environment variable.";
660 interface = EglPlatformInterface;
661 }
662
663 if (m_glPlatformInterface == interface) {
664 return;
665 }
666 m_glPlatformInterface = interface;
667 Q_EMIT glPlatformInterfaceChanged();
668}
669
670void Options::reparseConfiguration()
671{
672 m_settings->config()->reparseConfiguration();
673}
674
675void Options::updateSettings()
676{
677 loadConfig();
678
679 Q_EMIT configChanged();
680}
681
682void Options::loadConfig()
683{
684 m_settings->load();
685
686 syncFromKcfgc();
687
688 // Electric borders
689 KConfigGroup config(m_settings->config(), QStringLiteral("Windows"));
690 OpTitlebarDblClick = windowOperation(config.readEntry("TitlebarDoubleClickCommand", "Maximize"), true);
691 setOperationMaxButtonLeftClick(windowOperation(config.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true));
692 setOperationMaxButtonMiddleClick(windowOperation(config.readEntry("MaximizeButtonMiddleClickCommand", "Maximize (vertical only)"), true));
693 setOperationMaxButtonRightClick(windowOperation(config.readEntry("MaximizeButtonRightClickCommand", "Maximize (horizontal only)"), true));
694
695 // Mouse bindings
696 config = KConfigGroup(m_settings->config(), QStringLiteral("MouseBindings"));
697 // TODO: add properties for missing options
698 CmdTitlebarWheel = mouseWheelCommand(config.readEntry("CommandTitlebarWheel", "Nothing"));
699 CmdAllModKey = (config.readEntry("CommandAllKey", "Meta") == QStringLiteral("Meta")) ? Qt::Key_Meta : Qt::Key_Alt;
700 CmdAllWheel = mouseWheelCommand(config.readEntry("CommandAllWheel", "Nothing"));
701 setCommandActiveTitlebar1(mouseCommand(config.readEntry("CommandActiveTitlebar1", "Raise"), true));
702 setCommandActiveTitlebar2(mouseCommand(config.readEntry("CommandActiveTitlebar2", "Nothing"), true));
703 setCommandActiveTitlebar3(mouseCommand(config.readEntry("CommandActiveTitlebar3", "Operations menu"), true));
704 setCommandInactiveTitlebar1(mouseCommand(config.readEntry("CommandInactiveTitlebar1", "Activate and raise"), true));
705 setCommandInactiveTitlebar2(mouseCommand(config.readEntry("CommandInactiveTitlebar2", "Nothing"), true));
706 setCommandInactiveTitlebar3(mouseCommand(config.readEntry("CommandInactiveTitlebar3", "Operations menu"), true));
707 setCommandWindow1(mouseCommand(config.readEntry("CommandWindow1", "Activate, raise and pass click"), false));
708 setCommandWindow2(mouseCommand(config.readEntry("CommandWindow2", "Activate and pass click"), false));
709 setCommandWindow3(mouseCommand(config.readEntry("CommandWindow3", "Activate and pass click"), false));
710 setCommandWindowWheel(mouseCommand(config.readEntry("CommandWindowWheel", "Scroll"), false));
711 setCommandAll1(mouseCommand(config.readEntry("CommandAll1", "Move"), false));
712 setCommandAll2(mouseCommand(config.readEntry("CommandAll2", "Toggle raise and lower"), false));
713 setCommandAll3(mouseCommand(config.readEntry("CommandAll3", "Resize"), false));
714
715 // Modifier Only Shortcuts
716 config = KConfigGroup(m_settings->config(), QStringLiteral("ModifierOnlyShortcuts"));
717 m_modifierOnlyShortcuts.clear();
718 if (config.hasKey("Shift")) {
719 m_modifierOnlyShortcuts.insert(Qt::ShiftModifier, config.readEntry("Shift", QStringList()));
720 }
721 if (config.hasKey("Control")) {
722 m_modifierOnlyShortcuts.insert(Qt::ControlModifier, config.readEntry("Control", QStringList()));
723 }
724 if (config.hasKey("Alt")) {
725 m_modifierOnlyShortcuts.insert(Qt::AltModifier, config.readEntry("Alt", QStringList()));
726 }
727 m_modifierOnlyShortcuts.insert(Qt::MetaModifier, config.readEntry("Meta", QStringList{QStringLiteral("org.kde.plasmashell"), QStringLiteral("/PlasmaShell"), QStringLiteral("org.kde.PlasmaShell"), QStringLiteral("activateLauncherMenu")}));
728
729 // Compositing
730 config = KConfigGroup(m_settings->config(), QStringLiteral("Compositing"));
731 bool useCompositing = false;
732 CompositingType compositingMode = NoCompositing;
733 QString compositingBackend = config.readEntry("Backend", "OpenGL");
734 if (compositingBackend == "QPainter") {
735 compositingMode = QPainterCompositing;
736 } else {
737 compositingMode = OpenGLCompositing;
738 }
739
740 if (const char *c = getenv("KWIN_COMPOSE")) {
741 switch (c[0]) {
742 case 'O':
743 qCDebug(KWIN_CORE) << "Compositing forced to OpenGL mode by environment variable";
744 compositingMode = OpenGLCompositing;
745 useCompositing = true;
746 break;
747 case 'Q':
748 qCDebug(KWIN_CORE) << "Compositing forced to QPainter mode by environment variable";
749 compositingMode = QPainterCompositing;
750 useCompositing = true;
751 break;
752 case 'N':
753 if (getenv("KDE_FAILSAFE")) {
754 qCDebug(KWIN_CORE) << "Compositing disabled forcefully by KDE failsafe mode";
755 } else {
756 qCDebug(KWIN_CORE) << "Compositing disabled forcefully by environment variable";
757 }
758 compositingMode = NoCompositing;
759 break;
760 default:
761 qCDebug(KWIN_CORE) << "Unknown KWIN_COMPOSE mode set, ignoring";
762 break;
763 }
764 }
765 setCompositingMode(compositingMode);
766 setUseCompositing(useCompositing || config.readEntry("Enabled", Options::defaultUseCompositing()));
767
768 setGlSmoothScale(std::clamp(config.readEntry("GLTextureFilter", Options::defaultGlSmoothScale()), -1, 2));
769 setGlStrictBindingFollowsDriver(!config.hasKey("GLStrictBinding"));
770 if (!isGlStrictBindingFollowsDriver()) {
771 setGlStrictBinding(config.readEntry("GLStrictBinding", Options::defaultGlStrictBinding()));
772 }
773
774 char c = 0;
775 const QString s = config.readEntry("GLPreferBufferSwap", QString(QLatin1Char(Options::defaultGlPreferBufferSwap())));
776 if (!s.isEmpty()) {
777 c = s.at(0).toLatin1();
778 }
779 if (c != 'a' && c != 'c' && c != 'p' && c != 'e') {
780 c = Options::defaultGlPreferBufferSwap();
781 }
782 setGlPreferBufferSwap(c);
783
784 HiddenPreviews previews = Options::defaultHiddenPreviews();
785 // 4 - off, 5 - shown, 6 - always, other are old values
786 int hps = config.readEntry("HiddenPreviews", 5);
787 if (hps == 4) {
788 previews = HiddenPreviewsNever;
789 } else if (hps == 5) {
790 previews = HiddenPreviewsShown;
791 } else if (hps == 6) {
792 previews = HiddenPreviewsAlways;
793 }
794 setHiddenPreviews(previews);
795
796 auto interfaceToKey = [](OpenGLPlatformInterface interface) {
797 switch (interface) {
799 return QStringLiteral("glx");
801 return QStringLiteral("egl");
802 default:
803 return QString();
804 }
805 };
806 auto keyToInterface = [](const QString &key) {
807 if (key == QStringLiteral("glx")) {
809 } else if (key == QStringLiteral("egl")) {
811 }
812 return defaultGlPlatformInterface();
813 };
814 setGlPlatformInterface(keyToInterface(config.readEntry("GLPlatformInterface", interfaceToKey(m_glPlatformInterface))));
815}
816
817void Options::syncFromKcfgc()
818{
819 setCondensedTitle(m_settings->condensedTitle());
820 setFocusPolicy(m_settings->focusPolicy());
821 setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse());
822 setSeparateScreenFocus(m_settings->separateScreenFocus());
823 setActiveMouseScreen(m_settings->activeMouseScreen());
824 setRollOverDesktops(m_settings->rollOverDesktops());
825 setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel());
826 setActivationDesktopPolicy(m_settings->activationDesktopPolicy());
827 setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy());
828 setXwaylandMaxCrashCount(m_settings->xwaylandMaxCrashCount());
829 setXwaylandEavesdrops(XwaylandEavesdropsMode(m_settings->xwaylandEavesdrops()));
830 setPlacement(m_settings->placement());
831 setAutoRaise(m_settings->autoRaise());
832 setAutoRaiseInterval(m_settings->autoRaiseInterval());
833 setDelayFocusInterval(m_settings->delayFocusInterval());
834 setShadeHover(m_settings->shadeHover());
835 setShadeHoverInterval(m_settings->shadeHoverInterval());
836 setClickRaise(m_settings->clickRaise());
837 setBorderSnapZone(m_settings->borderSnapZone());
838 setWindowSnapZone(m_settings->windowSnapZone());
839 setCenterSnapZone(m_settings->centerSnapZone());
840 setSnapOnlyWhenOverlapping(m_settings->snapOnlyWhenOverlapping());
841 setKillPingTimeout(m_settings->killPingTimeout());
842 setHideUtilityWindowsForInactive(m_settings->hideUtilityWindowsForInactive());
843 setBorderlessMaximizedWindows(m_settings->borderlessMaximizedWindows());
844 setElectricBorderMaximize(m_settings->electricBorderMaximize());
845 setElectricBorderTiling(m_settings->electricBorderTiling());
846 setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio());
847 setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
848 setAllowTearing(m_settings->allowTearing());
849}
850
851// restricted should be true for operations that the user may not be able to repeat
852// if the window is moved out of the workspace (e.g. if the user moves a window
853// by the titlebar, and moves it too high beneath Kicker at the top edge, they
854// may not be able to move it back, unless they know about Meta+LMB)
855Options::WindowOperation Options::windowOperation(const QString &name, bool restricted)
856{
857 if (name == QStringLiteral("Move")) {
858 return restricted ? MoveOp : UnrestrictedMoveOp;
859 } else if (name == QStringLiteral("Resize")) {
860 return restricted ? ResizeOp : UnrestrictedResizeOp;
861 } else if (name == QStringLiteral("Maximize")) {
862 return MaximizeOp;
863 } else if (name == QStringLiteral("Minimize")) {
864 return MinimizeOp;
865 } else if (name == QStringLiteral("Close")) {
866 return CloseOp;
867 } else if (name == QStringLiteral("OnAllDesktops")) {
868 return OnAllDesktopsOp;
869 } else if (name == QStringLiteral("Shade")) {
870 return ShadeOp;
871 } else if (name == QStringLiteral("Operations")) {
872 return OperationsOp;
873 } else if (name == QStringLiteral("Maximize (vertical only)")) {
874 return VMaximizeOp;
875 } else if (name == QStringLiteral("Maximize (horizontal only)")) {
876 return HMaximizeOp;
877 } else if (name == QStringLiteral("Lower")) {
878 return LowerOp;
879 }
880 return NoOp;
881}
882
883Options::MouseCommand Options::mouseCommand(const QString &name, bool restricted)
884{
885 QString lowerName = name.toLower();
886 if (lowerName == QStringLiteral("raise")) {
887 return MouseRaise;
888 }
889 if (lowerName == QStringLiteral("lower")) {
890 return MouseLower;
891 }
892 if (lowerName == QStringLiteral("operations menu")) {
893 return MouseOperationsMenu;
894 }
895 if (lowerName == QStringLiteral("toggle raise and lower")) {
896 return MouseToggleRaiseAndLower;
897 }
898 if (lowerName == QStringLiteral("activate and raise")) {
899 return MouseActivateAndRaise;
900 }
901 if (lowerName == QStringLiteral("activate and lower")) {
902 return MouseActivateAndLower;
903 }
904 if (lowerName == QStringLiteral("activate")) {
905 return MouseActivate;
906 }
907 if (lowerName == QStringLiteral("activate, raise and pass click")) {
908 return MouseActivateRaiseAndPassClick;
909 }
910 if (lowerName == QStringLiteral("activate and pass click")) {
911 return MouseActivateAndPassClick;
912 }
913 if (lowerName == QStringLiteral("scroll")) {
914 return MouseNothing;
915 }
916 if (lowerName == QStringLiteral("activate and scroll")) {
917 return MouseActivateAndPassClick;
918 }
919 if (lowerName == QStringLiteral("activate, raise and scroll")) {
920 return MouseActivateRaiseAndPassClick;
921 }
922 if (lowerName == QStringLiteral("activate, raise and move")) {
923 return restricted ? MouseActivateRaiseAndMove : MouseActivateRaiseAndUnrestrictedMove;
924 }
925 if (lowerName == QStringLiteral("move")) {
926 return restricted ? MouseMove : MouseUnrestrictedMove;
927 }
928 if (lowerName == QStringLiteral("resize")) {
929 return restricted ? MouseResize : MouseUnrestrictedResize;
930 }
931 if (lowerName == QStringLiteral("shade")) {
932 return MouseShade;
933 }
934 if (lowerName == QStringLiteral("minimize")) {
935 return MouseMinimize;
936 }
937 if (lowerName == QStringLiteral("close")) {
938 return MouseClose;
939 }
940 if (lowerName == QStringLiteral("increase opacity")) {
941 return MouseOpacityMore;
942 }
943 if (lowerName == QStringLiteral("decrease opacity")) {
944 return MouseOpacityLess;
945 }
946 if (lowerName == QStringLiteral("nothing")) {
947 return MouseNothing;
948 }
949 return MouseNothing;
950}
951
952Options::MouseWheelCommand Options::mouseWheelCommand(const QString &name)
953{
954 QString lowerName = name.toLower();
955 if (lowerName == QStringLiteral("raise/lower")) {
956 return MouseWheelRaiseLower;
957 }
958 if (lowerName == QStringLiteral("shade/unshade")) {
959 return MouseWheelShadeUnshade;
960 }
961 if (lowerName == QStringLiteral("maximize/restore")) {
962 return MouseWheelMaximizeRestore;
963 }
964 if (lowerName == QStringLiteral("above/below")) {
965 return MouseWheelAboveBelow;
966 }
967 if (lowerName == QStringLiteral("previous/next desktop")) {
968 return MouseWheelPreviousNextDesktop;
969 }
970 if (lowerName == QStringLiteral("change opacity")) {
971 return MouseWheelChangeOpacity;
972 }
973 if (lowerName == QStringLiteral("nothing")) {
974 return MouseWheelNothing;
975 }
976 return MouseWheelNothing;
977}
978
979bool Options::condensedTitle() const
980{
981 return condensed_title;
982}
983
984Options::MouseCommand Options::wheelToMouseCommand(MouseWheelCommand com, int delta) const
985{
986 switch (com) {
987 case MouseWheelRaiseLower:
988 return delta > 0 ? MouseRaise : MouseLower;
989 case MouseWheelShadeUnshade:
990 return delta > 0 ? MouseSetShade : MouseUnsetShade;
991 case MouseWheelMaximizeRestore:
992 return delta > 0 ? MouseMaximize : MouseRestore;
993 case MouseWheelAboveBelow:
994 return delta > 0 ? MouseAbove : MouseBelow;
995 case MouseWheelPreviousNextDesktop:
996 return delta > 0 ? MousePreviousDesktop : MouseNextDesktop;
997 case MouseWheelChangeOpacity:
998 return delta > 0 ? MouseOpacityMore : MouseOpacityLess;
999 default:
1000 return MouseNothing;
1001 }
1002}
1003#endif
1004
1005double Options::animationTimeFactor() const
1006{
1007#ifndef KCMRULES
1008 return m_settings->animationDurationFactor();
1009#else
1010 return 0;
1011#endif
1012}
1013
1014Options::WindowOperation Options::operationMaxButtonClick(Qt::MouseButtons button) const
1015{
1016 return button == Qt::RightButton ? opMaxButtonRightClick : button == Qt::MiddleButton ? opMaxButtonMiddleClick
1017 : opMaxButtonLeftClick;
1018}
1019
1020QStringList Options::modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const
1021{
1022 return m_modifierOnlyShortcuts.value(mod);
1023}
1024
1025bool Options::isUseCompositing() const
1026{
1027 return m_useCompositing;
1028}
1029
1030} // namespace
1031
1032#include "moc_options.cpp"
Options(QObject *parent=nullptr)
Definition options.cpp:32
ActivationDesktopPolicy
Definition options.h:338
void loadConfig()
Definition options.cpp:682
XwaylandEavesdropsMode
Definition options.h:36
PlacementPolicy
Definition options.h:57
@ PlacementNone
Definition options.h:58
Workspace * workspace()
Definition workspace.h:830
OpenGLPlatformInterface
Definition globals.h:42
@ EglPlatformInterface
Definition globals.h:45
@ GlxPlatformInterface
Definition globals.h:44
CompositingType
Definition globals.h:28
@ QPainterCompositing
Definition globals.h:39
@ NoCompositing
Definition globals.h:29
@ OpenGLCompositing
Definition globals.h:37
XwaylandCrashPolicy
Definition options.h:46
HiddenPreviews
Definition options.h:24
@ HiddenPreviewsNever
Definition options.h:28
@ HiddenPreviewsAlways
Definition options.h:33
@ HiddenPreviewsShown
Definition options.h:31