File indexing completed on 2024-11-10 04:57:52
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org> 0006 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0007 SPDX-FileCopyrightText: 2012 Martin Gräßlin <m.graesslin@kde.org> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 #include "options.h" 0012 0013 #include "config-kwin.h" 0014 0015 #include "utils/common.h" 0016 0017 #ifndef KCMRULES 0018 0019 #include <QProcess> 0020 0021 #include "settings.h" 0022 #include "workspace.h" 0023 #include <QOpenGLContext> 0024 0025 #endif // KCMRULES 0026 0027 namespace KWin 0028 { 0029 0030 #ifndef KCMRULES 0031 0032 Options::Options(QObject *parent) 0033 : QObject(parent) 0034 , m_settings(new Settings(kwinApp()->config())) 0035 , m_focusPolicy(ClickToFocus) 0036 , m_nextFocusPrefersMouse(false) 0037 , m_clickRaise(false) 0038 , m_autoRaise(false) 0039 , m_autoRaiseInterval(0) 0040 , m_delayFocusInterval(0) 0041 , m_shadeHover(false) 0042 , m_shadeHoverInterval(0) 0043 , m_separateScreenFocus(false) 0044 , m_activeMouseScreen(false) 0045 , m_placement(PlacementNone) 0046 , m_activationDesktopPolicy(Options::defaultActivationDesktopPolicy()) 0047 , m_borderSnapZone(0) 0048 , m_windowSnapZone(0) 0049 , m_centerSnapZone(0) 0050 , m_snapOnlyWhenOverlapping(false) 0051 , m_rollOverDesktops(false) 0052 , m_focusStealingPreventionLevel(0) 0053 , m_killPingTimeout(0) 0054 , m_hideUtilityWindowsForInactive(false) 0055 , m_xwaylandCrashPolicy(Options::defaultXwaylandCrashPolicy()) 0056 , m_xwaylandMaxCrashCount(Options::defaultXwaylandMaxCrashCount()) 0057 , m_xwaylandEavesdrops(Options::defaultXwaylandEavesdrops()) 0058 , m_compositingMode(Options::defaultCompositingMode()) 0059 , m_useCompositing(Options::defaultUseCompositing()) 0060 , m_hiddenPreviews(Options::defaultHiddenPreviews()) 0061 , m_glSmoothScale(Options::defaultGlSmoothScale()) 0062 , m_glStrictBinding(Options::defaultGlStrictBinding()) 0063 , m_glStrictBindingFollowsDriver(Options::defaultGlStrictBindingFollowsDriver()) 0064 , m_glPreferBufferSwap(Options::defaultGlPreferBufferSwap()) 0065 , m_glPlatformInterface(Options::defaultGlPlatformInterface()) 0066 , m_windowsBlockCompositing(true) 0067 , OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick()) 0068 , CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1()) 0069 , CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2()) 0070 , CmdActiveTitlebar3(Options::defaultCommandActiveTitlebar3()) 0071 , CmdInactiveTitlebar1(Options::defaultCommandInactiveTitlebar1()) 0072 , CmdInactiveTitlebar2(Options::defaultCommandInactiveTitlebar2()) 0073 , CmdInactiveTitlebar3(Options::defaultCommandInactiveTitlebar3()) 0074 , CmdTitlebarWheel(Options::defaultCommandTitlebarWheel()) 0075 , CmdWindow1(Options::defaultCommandWindow1()) 0076 , CmdWindow2(Options::defaultCommandWindow2()) 0077 , CmdWindow3(Options::defaultCommandWindow3()) 0078 , CmdWindowWheel(Options::defaultCommandWindowWheel()) 0079 , CmdAll1(Options::defaultCommandAll1()) 0080 , CmdAll2(Options::defaultCommandAll2()) 0081 , CmdAll3(Options::defaultCommandAll3()) 0082 , CmdAllWheel(Options::defaultCommandAllWheel()) 0083 , CmdAllModKey(Options::defaultKeyCmdAllModKey()) 0084 , electric_border_maximize(false) 0085 , electric_border_tiling(false) 0086 , electric_border_corner_ratio(0.0) 0087 , borderless_maximized_windows(false) 0088 , condensed_title(false) 0089 { 0090 m_settings->setDefaults(); 0091 0092 loadConfig(); 0093 0094 m_configWatcher = KConfigWatcher::create(m_settings->sharedConfig()); 0095 connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) { 0096 if (group.name() == QLatin1String("KDE") && names.contains(QByteArrayLiteral("AnimationDurationFactor"))) { 0097 m_settings->load(); 0098 Q_EMIT animationSpeedChanged(); 0099 } else if (group.name() == QLatin1String("Xwayland")) { 0100 workspace()->reconfigure(); 0101 } 0102 }); 0103 } 0104 0105 Options::~Options() 0106 { 0107 } 0108 0109 void Options::setFocusPolicy(FocusPolicy focusPolicy) 0110 { 0111 if (m_focusPolicy == focusPolicy) { 0112 return; 0113 } 0114 m_focusPolicy = focusPolicy; 0115 Q_EMIT focusPolicyChanged(); 0116 if (m_focusPolicy == ClickToFocus) { 0117 setAutoRaise(false); 0118 setAutoRaiseInterval(0); 0119 setDelayFocusInterval(0); 0120 } 0121 } 0122 0123 void Options::setNextFocusPrefersMouse(bool nextFocusPrefersMouse) 0124 { 0125 if (m_nextFocusPrefersMouse == nextFocusPrefersMouse) { 0126 return; 0127 } 0128 m_nextFocusPrefersMouse = nextFocusPrefersMouse; 0129 Q_EMIT nextFocusPrefersMouseChanged(); 0130 } 0131 0132 void Options::setXwaylandCrashPolicy(XwaylandCrashPolicy crashPolicy) 0133 { 0134 if (m_xwaylandCrashPolicy == crashPolicy) { 0135 return; 0136 } 0137 m_xwaylandCrashPolicy = crashPolicy; 0138 Q_EMIT xwaylandCrashPolicyChanged(); 0139 } 0140 0141 void Options::setXwaylandMaxCrashCount(int maxCrashCount) 0142 { 0143 if (m_xwaylandMaxCrashCount == maxCrashCount) { 0144 return; 0145 } 0146 m_xwaylandMaxCrashCount = maxCrashCount; 0147 Q_EMIT xwaylandMaxCrashCountChanged(); 0148 } 0149 0150 void Options::setXwaylandEavesdrops(XwaylandEavesdropsMode mode) 0151 { 0152 if (m_xwaylandEavesdrops == mode) { 0153 return; 0154 } 0155 m_xwaylandEavesdrops = mode; 0156 Q_EMIT xwaylandEavesdropsChanged(); 0157 } 0158 0159 void Options::setClickRaise(bool clickRaise) 0160 { 0161 if (m_autoRaise) { 0162 // important: autoRaise implies ClickRaise 0163 clickRaise = true; 0164 } 0165 if (m_clickRaise == clickRaise) { 0166 return; 0167 } 0168 m_clickRaise = clickRaise; 0169 Q_EMIT clickRaiseChanged(); 0170 } 0171 0172 void Options::setAutoRaise(bool autoRaise) 0173 { 0174 if (m_focusPolicy == ClickToFocus) { 0175 autoRaise = false; 0176 } 0177 if (m_autoRaise == autoRaise) { 0178 return; 0179 } 0180 m_autoRaise = autoRaise; 0181 if (m_autoRaise) { 0182 // important: autoRaise implies ClickRaise 0183 setClickRaise(true); 0184 } 0185 Q_EMIT autoRaiseChanged(); 0186 } 0187 0188 void Options::setAutoRaiseInterval(int autoRaiseInterval) 0189 { 0190 if (m_focusPolicy == ClickToFocus) { 0191 autoRaiseInterval = 0; 0192 } 0193 if (m_autoRaiseInterval == autoRaiseInterval) { 0194 return; 0195 } 0196 m_autoRaiseInterval = autoRaiseInterval; 0197 Q_EMIT autoRaiseIntervalChanged(); 0198 } 0199 0200 void Options::setDelayFocusInterval(int delayFocusInterval) 0201 { 0202 if (m_focusPolicy == ClickToFocus) { 0203 delayFocusInterval = 0; 0204 } 0205 if (m_delayFocusInterval == delayFocusInterval) { 0206 return; 0207 } 0208 m_delayFocusInterval = delayFocusInterval; 0209 Q_EMIT delayFocusIntervalChanged(); 0210 } 0211 0212 void Options::setShadeHover(bool shadeHover) 0213 { 0214 if (m_shadeHover == shadeHover) { 0215 return; 0216 } 0217 m_shadeHover = shadeHover; 0218 Q_EMIT shadeHoverChanged(); 0219 } 0220 0221 void Options::setShadeHoverInterval(int shadeHoverInterval) 0222 { 0223 if (m_shadeHoverInterval == shadeHoverInterval) { 0224 return; 0225 } 0226 m_shadeHoverInterval = shadeHoverInterval; 0227 Q_EMIT shadeHoverIntervalChanged(); 0228 } 0229 0230 void Options::setSeparateScreenFocus(bool separateScreenFocus) 0231 { 0232 if (m_separateScreenFocus == separateScreenFocus) { 0233 return; 0234 } 0235 m_separateScreenFocus = separateScreenFocus; 0236 Q_EMIT separateScreenFocusChanged(m_separateScreenFocus); 0237 } 0238 0239 void Options::setActiveMouseScreen(bool activeMouseScreen) 0240 { 0241 if (m_activeMouseScreen == activeMouseScreen) { 0242 return; 0243 } 0244 m_activeMouseScreen = activeMouseScreen; 0245 Q_EMIT activeMouseScreenChanged(); 0246 } 0247 0248 void Options::setPlacement(PlacementPolicy placement) 0249 { 0250 if (m_placement == placement) { 0251 return; 0252 } 0253 m_placement = placement; 0254 Q_EMIT placementChanged(); 0255 } 0256 0257 void Options::setActivationDesktopPolicy(ActivationDesktopPolicy activationDesktopPolicy) 0258 { 0259 if (m_activationDesktopPolicy == activationDesktopPolicy) { 0260 return; 0261 } 0262 m_activationDesktopPolicy = activationDesktopPolicy; 0263 Q_EMIT activationDesktopPolicyChanged(); 0264 } 0265 0266 void Options::setBorderSnapZone(int borderSnapZone) 0267 { 0268 if (m_borderSnapZone == borderSnapZone) { 0269 return; 0270 } 0271 m_borderSnapZone = borderSnapZone; 0272 Q_EMIT borderSnapZoneChanged(); 0273 } 0274 0275 void Options::setWindowSnapZone(int windowSnapZone) 0276 { 0277 if (m_windowSnapZone == windowSnapZone) { 0278 return; 0279 } 0280 m_windowSnapZone = windowSnapZone; 0281 Q_EMIT windowSnapZoneChanged(); 0282 } 0283 0284 void Options::setCenterSnapZone(int centerSnapZone) 0285 { 0286 if (m_centerSnapZone == centerSnapZone) { 0287 return; 0288 } 0289 m_centerSnapZone = centerSnapZone; 0290 Q_EMIT centerSnapZoneChanged(); 0291 } 0292 0293 void Options::setSnapOnlyWhenOverlapping(bool snapOnlyWhenOverlapping) 0294 { 0295 if (m_snapOnlyWhenOverlapping == snapOnlyWhenOverlapping) { 0296 return; 0297 } 0298 m_snapOnlyWhenOverlapping = snapOnlyWhenOverlapping; 0299 Q_EMIT snapOnlyWhenOverlappingChanged(); 0300 } 0301 0302 void Options::setRollOverDesktops(bool rollOverDesktops) 0303 { 0304 if (m_rollOverDesktops == rollOverDesktops) { 0305 return; 0306 } 0307 m_rollOverDesktops = rollOverDesktops; 0308 Q_EMIT rollOverDesktopsChanged(m_rollOverDesktops); 0309 } 0310 0311 void Options::setFocusStealingPreventionLevel(int focusStealingPreventionLevel) 0312 { 0313 if (!focusPolicyIsReasonable()) { 0314 focusStealingPreventionLevel = 0; 0315 } 0316 if (m_focusStealingPreventionLevel == focusStealingPreventionLevel) { 0317 return; 0318 } 0319 m_focusStealingPreventionLevel = std::max(0, std::min(4, focusStealingPreventionLevel)); 0320 Q_EMIT focusStealingPreventionLevelChanged(); 0321 } 0322 0323 void Options::setOperationTitlebarDblClick(WindowOperation operationTitlebarDblClick) 0324 { 0325 if (OpTitlebarDblClick == operationTitlebarDblClick) { 0326 return; 0327 } 0328 OpTitlebarDblClick = operationTitlebarDblClick; 0329 Q_EMIT operationTitlebarDblClickChanged(); 0330 } 0331 0332 void Options::setOperationMaxButtonLeftClick(WindowOperation op) 0333 { 0334 if (opMaxButtonLeftClick == op) { 0335 return; 0336 } 0337 opMaxButtonLeftClick = op; 0338 Q_EMIT operationMaxButtonLeftClickChanged(); 0339 } 0340 0341 void Options::setOperationMaxButtonRightClick(WindowOperation op) 0342 { 0343 if (opMaxButtonRightClick == op) { 0344 return; 0345 } 0346 opMaxButtonRightClick = op; 0347 Q_EMIT operationMaxButtonRightClickChanged(); 0348 } 0349 0350 void Options::setOperationMaxButtonMiddleClick(WindowOperation op) 0351 { 0352 if (opMaxButtonMiddleClick == op) { 0353 return; 0354 } 0355 opMaxButtonMiddleClick = op; 0356 Q_EMIT operationMaxButtonMiddleClickChanged(); 0357 } 0358 0359 void Options::setCommandActiveTitlebar1(MouseCommand commandActiveTitlebar1) 0360 { 0361 if (CmdActiveTitlebar1 == commandActiveTitlebar1) { 0362 return; 0363 } 0364 CmdActiveTitlebar1 = commandActiveTitlebar1; 0365 Q_EMIT commandActiveTitlebar1Changed(); 0366 } 0367 0368 void Options::setCommandActiveTitlebar2(MouseCommand commandActiveTitlebar2) 0369 { 0370 if (CmdActiveTitlebar2 == commandActiveTitlebar2) { 0371 return; 0372 } 0373 CmdActiveTitlebar2 = commandActiveTitlebar2; 0374 Q_EMIT commandActiveTitlebar2Changed(); 0375 } 0376 0377 void Options::setCommandActiveTitlebar3(MouseCommand commandActiveTitlebar3) 0378 { 0379 if (CmdActiveTitlebar3 == commandActiveTitlebar3) { 0380 return; 0381 } 0382 CmdActiveTitlebar3 = commandActiveTitlebar3; 0383 Q_EMIT commandActiveTitlebar3Changed(); 0384 } 0385 0386 void Options::setCommandInactiveTitlebar1(MouseCommand commandInactiveTitlebar1) 0387 { 0388 if (CmdInactiveTitlebar1 == commandInactiveTitlebar1) { 0389 return; 0390 } 0391 CmdInactiveTitlebar1 = commandInactiveTitlebar1; 0392 Q_EMIT commandInactiveTitlebar1Changed(); 0393 } 0394 0395 void Options::setCommandInactiveTitlebar2(MouseCommand commandInactiveTitlebar2) 0396 { 0397 if (CmdInactiveTitlebar2 == commandInactiveTitlebar2) { 0398 return; 0399 } 0400 CmdInactiveTitlebar2 = commandInactiveTitlebar2; 0401 Q_EMIT commandInactiveTitlebar2Changed(); 0402 } 0403 0404 void Options::setCommandInactiveTitlebar3(MouseCommand commandInactiveTitlebar3) 0405 { 0406 if (CmdInactiveTitlebar3 == commandInactiveTitlebar3) { 0407 return; 0408 } 0409 CmdInactiveTitlebar3 = commandInactiveTitlebar3; 0410 Q_EMIT commandInactiveTitlebar3Changed(); 0411 } 0412 0413 void Options::setCommandWindow1(MouseCommand commandWindow1) 0414 { 0415 if (CmdWindow1 == commandWindow1) { 0416 return; 0417 } 0418 CmdWindow1 = commandWindow1; 0419 Q_EMIT commandWindow1Changed(); 0420 } 0421 0422 void Options::setCommandWindow2(MouseCommand commandWindow2) 0423 { 0424 if (CmdWindow2 == commandWindow2) { 0425 return; 0426 } 0427 CmdWindow2 = commandWindow2; 0428 Q_EMIT commandWindow2Changed(); 0429 } 0430 0431 void Options::setCommandWindow3(MouseCommand commandWindow3) 0432 { 0433 if (CmdWindow3 == commandWindow3) { 0434 return; 0435 } 0436 CmdWindow3 = commandWindow3; 0437 Q_EMIT commandWindow3Changed(); 0438 } 0439 0440 void Options::setCommandWindowWheel(MouseCommand commandWindowWheel) 0441 { 0442 if (CmdWindowWheel == commandWindowWheel) { 0443 return; 0444 } 0445 CmdWindowWheel = commandWindowWheel; 0446 Q_EMIT commandWindowWheelChanged(); 0447 } 0448 0449 void Options::setCommandAll1(MouseCommand commandAll1) 0450 { 0451 if (CmdAll1 == commandAll1) { 0452 return; 0453 } 0454 CmdAll1 = commandAll1; 0455 Q_EMIT commandAll1Changed(); 0456 } 0457 0458 void Options::setCommandAll2(MouseCommand commandAll2) 0459 { 0460 if (CmdAll2 == commandAll2) { 0461 return; 0462 } 0463 CmdAll2 = commandAll2; 0464 Q_EMIT commandAll2Changed(); 0465 } 0466 0467 void Options::setCommandAll3(MouseCommand commandAll3) 0468 { 0469 if (CmdAll3 == commandAll3) { 0470 return; 0471 } 0472 CmdAll3 = commandAll3; 0473 Q_EMIT commandAll3Changed(); 0474 } 0475 0476 void Options::setKeyCmdAllModKey(uint keyCmdAllModKey) 0477 { 0478 if (CmdAllModKey == keyCmdAllModKey) { 0479 return; 0480 } 0481 CmdAllModKey = keyCmdAllModKey; 0482 Q_EMIT keyCmdAllModKeyChanged(); 0483 } 0484 0485 void Options::setCondensedTitle(bool condensedTitle) 0486 { 0487 if (condensed_title == condensedTitle) { 0488 return; 0489 } 0490 condensed_title = condensedTitle; 0491 Q_EMIT condensedTitleChanged(); 0492 } 0493 0494 void Options::setElectricBorderMaximize(bool electricBorderMaximize) 0495 { 0496 if (electric_border_maximize == electricBorderMaximize) { 0497 return; 0498 } 0499 electric_border_maximize = electricBorderMaximize; 0500 Q_EMIT electricBorderMaximizeChanged(); 0501 } 0502 0503 void Options::setElectricBorderTiling(bool electricBorderTiling) 0504 { 0505 if (electric_border_tiling == electricBorderTiling) { 0506 return; 0507 } 0508 electric_border_tiling = electricBorderTiling; 0509 Q_EMIT electricBorderTilingChanged(); 0510 } 0511 0512 void Options::setElectricBorderCornerRatio(float electricBorderCornerRatio) 0513 { 0514 if (electric_border_corner_ratio == electricBorderCornerRatio) { 0515 return; 0516 } 0517 electric_border_corner_ratio = electricBorderCornerRatio; 0518 Q_EMIT electricBorderCornerRatioChanged(); 0519 } 0520 0521 void Options::setBorderlessMaximizedWindows(bool borderlessMaximizedWindows) 0522 { 0523 if (borderless_maximized_windows == borderlessMaximizedWindows) { 0524 return; 0525 } 0526 borderless_maximized_windows = borderlessMaximizedWindows; 0527 Q_EMIT borderlessMaximizedWindowsChanged(); 0528 } 0529 0530 void Options::setKillPingTimeout(int killPingTimeout) 0531 { 0532 if (m_killPingTimeout == killPingTimeout) { 0533 return; 0534 } 0535 m_killPingTimeout = killPingTimeout; 0536 Q_EMIT killPingTimeoutChanged(); 0537 } 0538 0539 void Options::setHideUtilityWindowsForInactive(bool hideUtilityWindowsForInactive) 0540 { 0541 if (m_hideUtilityWindowsForInactive == hideUtilityWindowsForInactive) { 0542 return; 0543 } 0544 m_hideUtilityWindowsForInactive = hideUtilityWindowsForInactive; 0545 Q_EMIT hideUtilityWindowsForInactiveChanged(); 0546 } 0547 0548 void Options::setCompositingMode(int compositingMode) 0549 { 0550 if (m_compositingMode == static_cast<CompositingType>(compositingMode)) { 0551 return; 0552 } 0553 m_compositingMode = static_cast<CompositingType>(compositingMode); 0554 Q_EMIT compositingModeChanged(); 0555 } 0556 0557 void Options::setUseCompositing(bool useCompositing) 0558 { 0559 if (m_useCompositing == useCompositing) { 0560 return; 0561 } 0562 m_useCompositing = useCompositing; 0563 Q_EMIT useCompositingChanged(); 0564 } 0565 0566 void Options::setHiddenPreviews(int hiddenPreviews) 0567 { 0568 if (m_hiddenPreviews == static_cast<HiddenPreviews>(hiddenPreviews)) { 0569 return; 0570 } 0571 m_hiddenPreviews = static_cast<HiddenPreviews>(hiddenPreviews); 0572 Q_EMIT hiddenPreviewsChanged(); 0573 } 0574 0575 void Options::setGlSmoothScale(int glSmoothScale) 0576 { 0577 if (m_glSmoothScale == glSmoothScale) { 0578 return; 0579 } 0580 m_glSmoothScale = glSmoothScale; 0581 Q_EMIT glSmoothScaleChanged(); 0582 } 0583 0584 void Options::setGlStrictBinding(bool glStrictBinding) 0585 { 0586 if (m_glStrictBinding == glStrictBinding) { 0587 return; 0588 } 0589 m_glStrictBinding = glStrictBinding; 0590 Q_EMIT glStrictBindingChanged(); 0591 } 0592 0593 void Options::setGlStrictBindingFollowsDriver(bool glStrictBindingFollowsDriver) 0594 { 0595 if (m_glStrictBindingFollowsDriver == glStrictBindingFollowsDriver) { 0596 return; 0597 } 0598 m_glStrictBindingFollowsDriver = glStrictBindingFollowsDriver; 0599 Q_EMIT glStrictBindingFollowsDriverChanged(); 0600 } 0601 0602 void Options::setWindowsBlockCompositing(bool value) 0603 { 0604 if (m_windowsBlockCompositing == value) { 0605 return; 0606 } 0607 m_windowsBlockCompositing = value; 0608 Q_EMIT windowsBlockCompositingChanged(); 0609 } 0610 0611 void Options::setGlPreferBufferSwap(char glPreferBufferSwap) 0612 { 0613 if (m_glPreferBufferSwap == (GlSwapStrategy)glPreferBufferSwap) { 0614 return; 0615 } 0616 m_glPreferBufferSwap = (GlSwapStrategy)glPreferBufferSwap; 0617 Q_EMIT glPreferBufferSwapChanged(); 0618 } 0619 0620 bool Options::allowTearing() const 0621 { 0622 return m_allowTearing; 0623 } 0624 0625 void Options::setAllowTearing(bool allow) 0626 { 0627 if (allow != m_allowTearing) { 0628 m_allowTearing = allow; 0629 Q_EMIT allowTearingChanged(); 0630 } 0631 } 0632 0633 void Options::setGlPlatformInterface(OpenGLPlatformInterface interface) 0634 { 0635 // check environment variable 0636 const QByteArray envOpenGLInterface(qgetenv("KWIN_OPENGL_INTERFACE")); 0637 if (!envOpenGLInterface.isEmpty()) { 0638 if (qstrcmp(envOpenGLInterface, "egl") == 0) { 0639 qCDebug(KWIN_CORE) << "Forcing EGL native interface through environment variable"; 0640 interface = EglPlatformInterface; 0641 } else if (qstrcmp(envOpenGLInterface, "glx") == 0) { 0642 qCDebug(KWIN_CORE) << "Forcing GLX native interface through environment variable"; 0643 interface = GlxPlatformInterface; 0644 } 0645 } 0646 if (kwinApp()->shouldUseWaylandForCompositing() && interface == GlxPlatformInterface) { 0647 // Glx is impossible on Wayland, enforce egl 0648 qCDebug(KWIN_CORE) << "Forcing EGL native interface for Wayland mode"; 0649 interface = EglPlatformInterface; 0650 } 0651 #if !HAVE_GLX 0652 qCDebug(KWIN_CORE) << "Forcing EGL native interface as compiled without GLX support"; 0653 interface = EglPlatformInterface; 0654 #endif 0655 if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { 0656 qCDebug(KWIN_CORE) << "Forcing EGL native interface as Qt uses OpenGL ES"; 0657 interface = EglPlatformInterface; 0658 } else if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) { 0659 qCDebug(KWIN_CORE) << "Forcing EGL native interface as OpenGL ES requested through KWIN_COMPOSE environment variable."; 0660 interface = EglPlatformInterface; 0661 } 0662 0663 if (m_glPlatformInterface == interface) { 0664 return; 0665 } 0666 m_glPlatformInterface = interface; 0667 Q_EMIT glPlatformInterfaceChanged(); 0668 } 0669 0670 void Options::reparseConfiguration() 0671 { 0672 m_settings->config()->reparseConfiguration(); 0673 } 0674 0675 void Options::updateSettings() 0676 { 0677 loadConfig(); 0678 0679 Q_EMIT configChanged(); 0680 } 0681 0682 void Options::loadConfig() 0683 { 0684 m_settings->load(); 0685 0686 syncFromKcfgc(); 0687 0688 // Electric borders 0689 KConfigGroup config(m_settings->config(), QStringLiteral("Windows")); 0690 OpTitlebarDblClick = windowOperation(config.readEntry("TitlebarDoubleClickCommand", "Maximize"), true); 0691 setOperationMaxButtonLeftClick(windowOperation(config.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true)); 0692 setOperationMaxButtonMiddleClick(windowOperation(config.readEntry("MaximizeButtonMiddleClickCommand", "Maximize (vertical only)"), true)); 0693 setOperationMaxButtonRightClick(windowOperation(config.readEntry("MaximizeButtonRightClickCommand", "Maximize (horizontal only)"), true)); 0694 0695 // Mouse bindings 0696 config = KConfigGroup(m_settings->config(), QStringLiteral("MouseBindings")); 0697 // TODO: add properties for missing options 0698 CmdTitlebarWheel = mouseWheelCommand(config.readEntry("CommandTitlebarWheel", "Nothing")); 0699 CmdAllModKey = (config.readEntry("CommandAllKey", "Meta") == QStringLiteral("Meta")) ? Qt::Key_Meta : Qt::Key_Alt; 0700 CmdAllWheel = mouseWheelCommand(config.readEntry("CommandAllWheel", "Nothing")); 0701 setCommandActiveTitlebar1(mouseCommand(config.readEntry("CommandActiveTitlebar1", "Raise"), true)); 0702 setCommandActiveTitlebar2(mouseCommand(config.readEntry("CommandActiveTitlebar2", "Nothing"), true)); 0703 setCommandActiveTitlebar3(mouseCommand(config.readEntry("CommandActiveTitlebar3", "Operations menu"), true)); 0704 setCommandInactiveTitlebar1(mouseCommand(config.readEntry("CommandInactiveTitlebar1", "Activate and raise"), true)); 0705 setCommandInactiveTitlebar2(mouseCommand(config.readEntry("CommandInactiveTitlebar2", "Nothing"), true)); 0706 setCommandInactiveTitlebar3(mouseCommand(config.readEntry("CommandInactiveTitlebar3", "Operations menu"), true)); 0707 setCommandWindow1(mouseCommand(config.readEntry("CommandWindow1", "Activate, raise and pass click"), false)); 0708 setCommandWindow2(mouseCommand(config.readEntry("CommandWindow2", "Activate and pass click"), false)); 0709 setCommandWindow3(mouseCommand(config.readEntry("CommandWindow3", "Activate and pass click"), false)); 0710 setCommandWindowWheel(mouseCommand(config.readEntry("CommandWindowWheel", "Scroll"), false)); 0711 setCommandAll1(mouseCommand(config.readEntry("CommandAll1", "Move"), false)); 0712 setCommandAll2(mouseCommand(config.readEntry("CommandAll2", "Toggle raise and lower"), false)); 0713 setCommandAll3(mouseCommand(config.readEntry("CommandAll3", "Resize"), false)); 0714 0715 // Modifier Only Shortcuts 0716 config = KConfigGroup(m_settings->config(), QStringLiteral("ModifierOnlyShortcuts")); 0717 m_modifierOnlyShortcuts.clear(); 0718 if (config.hasKey("Shift")) { 0719 m_modifierOnlyShortcuts.insert(Qt::ShiftModifier, config.readEntry("Shift", QStringList())); 0720 } 0721 if (config.hasKey("Control")) { 0722 m_modifierOnlyShortcuts.insert(Qt::ControlModifier, config.readEntry("Control", QStringList())); 0723 } 0724 if (config.hasKey("Alt")) { 0725 m_modifierOnlyShortcuts.insert(Qt::AltModifier, config.readEntry("Alt", QStringList())); 0726 } 0727 m_modifierOnlyShortcuts.insert(Qt::MetaModifier, config.readEntry("Meta", QStringList{QStringLiteral("org.kde.plasmashell"), QStringLiteral("/PlasmaShell"), QStringLiteral("org.kde.PlasmaShell"), QStringLiteral("activateLauncherMenu")})); 0728 0729 // Compositing 0730 config = KConfigGroup(m_settings->config(), QStringLiteral("Compositing")); 0731 bool useCompositing = false; 0732 CompositingType compositingMode = NoCompositing; 0733 QString compositingBackend = config.readEntry("Backend", "OpenGL"); 0734 if (compositingBackend == "QPainter") { 0735 compositingMode = QPainterCompositing; 0736 } else { 0737 compositingMode = OpenGLCompositing; 0738 } 0739 0740 if (const char *c = getenv("KWIN_COMPOSE")) { 0741 switch (c[0]) { 0742 case 'O': 0743 qCDebug(KWIN_CORE) << "Compositing forced to OpenGL mode by environment variable"; 0744 compositingMode = OpenGLCompositing; 0745 useCompositing = true; 0746 break; 0747 case 'Q': 0748 qCDebug(KWIN_CORE) << "Compositing forced to QPainter mode by environment variable"; 0749 compositingMode = QPainterCompositing; 0750 useCompositing = true; 0751 break; 0752 case 'N': 0753 if (getenv("KDE_FAILSAFE")) { 0754 qCDebug(KWIN_CORE) << "Compositing disabled forcefully by KDE failsafe mode"; 0755 } else { 0756 qCDebug(KWIN_CORE) << "Compositing disabled forcefully by environment variable"; 0757 } 0758 compositingMode = NoCompositing; 0759 break; 0760 default: 0761 qCDebug(KWIN_CORE) << "Unknown KWIN_COMPOSE mode set, ignoring"; 0762 break; 0763 } 0764 } 0765 setCompositingMode(compositingMode); 0766 setUseCompositing(useCompositing || config.readEntry("Enabled", Options::defaultUseCompositing())); 0767 0768 setGlSmoothScale(std::clamp(config.readEntry("GLTextureFilter", Options::defaultGlSmoothScale()), -1, 2)); 0769 setGlStrictBindingFollowsDriver(!config.hasKey("GLStrictBinding")); 0770 if (!isGlStrictBindingFollowsDriver()) { 0771 setGlStrictBinding(config.readEntry("GLStrictBinding", Options::defaultGlStrictBinding())); 0772 } 0773 0774 char c = 0; 0775 const QString s = config.readEntry("GLPreferBufferSwap", QString(QLatin1Char(Options::defaultGlPreferBufferSwap()))); 0776 if (!s.isEmpty()) { 0777 c = s.at(0).toLatin1(); 0778 } 0779 if (c != 'a' && c != 'c' && c != 'p' && c != 'e') { 0780 c = Options::defaultGlPreferBufferSwap(); 0781 } 0782 setGlPreferBufferSwap(c); 0783 0784 HiddenPreviews previews = Options::defaultHiddenPreviews(); 0785 // 4 - off, 5 - shown, 6 - always, other are old values 0786 int hps = config.readEntry("HiddenPreviews", 5); 0787 if (hps == 4) { 0788 previews = HiddenPreviewsNever; 0789 } else if (hps == 5) { 0790 previews = HiddenPreviewsShown; 0791 } else if (hps == 6) { 0792 previews = HiddenPreviewsAlways; 0793 } 0794 setHiddenPreviews(previews); 0795 0796 auto interfaceToKey = [](OpenGLPlatformInterface interface) { 0797 switch (interface) { 0798 case GlxPlatformInterface: 0799 return QStringLiteral("glx"); 0800 case EglPlatformInterface: 0801 return QStringLiteral("egl"); 0802 default: 0803 return QString(); 0804 } 0805 }; 0806 auto keyToInterface = [](const QString &key) { 0807 if (key == QStringLiteral("glx")) { 0808 return GlxPlatformInterface; 0809 } else if (key == QStringLiteral("egl")) { 0810 return EglPlatformInterface; 0811 } 0812 return defaultGlPlatformInterface(); 0813 }; 0814 setGlPlatformInterface(keyToInterface(config.readEntry("GLPlatformInterface", interfaceToKey(m_glPlatformInterface)))); 0815 } 0816 0817 void Options::syncFromKcfgc() 0818 { 0819 setCondensedTitle(m_settings->condensedTitle()); 0820 setFocusPolicy(m_settings->focusPolicy()); 0821 setNextFocusPrefersMouse(m_settings->nextFocusPrefersMouse()); 0822 setSeparateScreenFocus(m_settings->separateScreenFocus()); 0823 setActiveMouseScreen(m_settings->activeMouseScreen()); 0824 setRollOverDesktops(m_settings->rollOverDesktops()); 0825 setFocusStealingPreventionLevel(m_settings->focusStealingPreventionLevel()); 0826 setActivationDesktopPolicy(m_settings->activationDesktopPolicy()); 0827 setXwaylandCrashPolicy(m_settings->xwaylandCrashPolicy()); 0828 setXwaylandMaxCrashCount(m_settings->xwaylandMaxCrashCount()); 0829 setXwaylandEavesdrops(XwaylandEavesdropsMode(m_settings->xwaylandEavesdrops())); 0830 setPlacement(m_settings->placement()); 0831 setAutoRaise(m_settings->autoRaise()); 0832 setAutoRaiseInterval(m_settings->autoRaiseInterval()); 0833 setDelayFocusInterval(m_settings->delayFocusInterval()); 0834 setShadeHover(m_settings->shadeHover()); 0835 setShadeHoverInterval(m_settings->shadeHoverInterval()); 0836 setClickRaise(m_settings->clickRaise()); 0837 setBorderSnapZone(m_settings->borderSnapZone()); 0838 setWindowSnapZone(m_settings->windowSnapZone()); 0839 setCenterSnapZone(m_settings->centerSnapZone()); 0840 setSnapOnlyWhenOverlapping(m_settings->snapOnlyWhenOverlapping()); 0841 setKillPingTimeout(m_settings->killPingTimeout()); 0842 setHideUtilityWindowsForInactive(m_settings->hideUtilityWindowsForInactive()); 0843 setBorderlessMaximizedWindows(m_settings->borderlessMaximizedWindows()); 0844 setElectricBorderMaximize(m_settings->electricBorderMaximize()); 0845 setElectricBorderTiling(m_settings->electricBorderTiling()); 0846 setElectricBorderCornerRatio(m_settings->electricBorderCornerRatio()); 0847 setWindowsBlockCompositing(m_settings->windowsBlockCompositing()); 0848 setAllowTearing(m_settings->allowTearing()); 0849 } 0850 0851 // restricted should be true for operations that the user may not be able to repeat 0852 // if the window is moved out of the workspace (e.g. if the user moves a window 0853 // by the titlebar, and moves it too high beneath Kicker at the top edge, they 0854 // may not be able to move it back, unless they know about Meta+LMB) 0855 Options::WindowOperation Options::windowOperation(const QString &name, bool restricted) 0856 { 0857 if (name == QStringLiteral("Move")) { 0858 return restricted ? MoveOp : UnrestrictedMoveOp; 0859 } else if (name == QStringLiteral("Resize")) { 0860 return restricted ? ResizeOp : UnrestrictedResizeOp; 0861 } else if (name == QStringLiteral("Maximize")) { 0862 return MaximizeOp; 0863 } else if (name == QStringLiteral("Minimize")) { 0864 return MinimizeOp; 0865 } else if (name == QStringLiteral("Close")) { 0866 return CloseOp; 0867 } else if (name == QStringLiteral("OnAllDesktops")) { 0868 return OnAllDesktopsOp; 0869 } else if (name == QStringLiteral("Shade")) { 0870 return ShadeOp; 0871 } else if (name == QStringLiteral("Operations")) { 0872 return OperationsOp; 0873 } else if (name == QStringLiteral("Maximize (vertical only)")) { 0874 return VMaximizeOp; 0875 } else if (name == QStringLiteral("Maximize (horizontal only)")) { 0876 return HMaximizeOp; 0877 } else if (name == QStringLiteral("Lower")) { 0878 return LowerOp; 0879 } 0880 return NoOp; 0881 } 0882 0883 Options::MouseCommand Options::mouseCommand(const QString &name, bool restricted) 0884 { 0885 QString lowerName = name.toLower(); 0886 if (lowerName == QStringLiteral("raise")) { 0887 return MouseRaise; 0888 } 0889 if (lowerName == QStringLiteral("lower")) { 0890 return MouseLower; 0891 } 0892 if (lowerName == QStringLiteral("operations menu")) { 0893 return MouseOperationsMenu; 0894 } 0895 if (lowerName == QStringLiteral("toggle raise and lower")) { 0896 return MouseToggleRaiseAndLower; 0897 } 0898 if (lowerName == QStringLiteral("activate and raise")) { 0899 return MouseActivateAndRaise; 0900 } 0901 if (lowerName == QStringLiteral("activate and lower")) { 0902 return MouseActivateAndLower; 0903 } 0904 if (lowerName == QStringLiteral("activate")) { 0905 return MouseActivate; 0906 } 0907 if (lowerName == QStringLiteral("activate, raise and pass click")) { 0908 return MouseActivateRaiseAndPassClick; 0909 } 0910 if (lowerName == QStringLiteral("activate and pass click")) { 0911 return MouseActivateAndPassClick; 0912 } 0913 if (lowerName == QStringLiteral("scroll")) { 0914 return MouseNothing; 0915 } 0916 if (lowerName == QStringLiteral("activate and scroll")) { 0917 return MouseActivateAndPassClick; 0918 } 0919 if (lowerName == QStringLiteral("activate, raise and scroll")) { 0920 return MouseActivateRaiseAndPassClick; 0921 } 0922 if (lowerName == QStringLiteral("activate, raise and move")) { 0923 return restricted ? MouseActivateRaiseAndMove : MouseActivateRaiseAndUnrestrictedMove; 0924 } 0925 if (lowerName == QStringLiteral("move")) { 0926 return restricted ? MouseMove : MouseUnrestrictedMove; 0927 } 0928 if (lowerName == QStringLiteral("resize")) { 0929 return restricted ? MouseResize : MouseUnrestrictedResize; 0930 } 0931 if (lowerName == QStringLiteral("shade")) { 0932 return MouseShade; 0933 } 0934 if (lowerName == QStringLiteral("minimize")) { 0935 return MouseMinimize; 0936 } 0937 if (lowerName == QStringLiteral("close")) { 0938 return MouseClose; 0939 } 0940 if (lowerName == QStringLiteral("increase opacity")) { 0941 return MouseOpacityMore; 0942 } 0943 if (lowerName == QStringLiteral("decrease opacity")) { 0944 return MouseOpacityLess; 0945 } 0946 if (lowerName == QStringLiteral("nothing")) { 0947 return MouseNothing; 0948 } 0949 return MouseNothing; 0950 } 0951 0952 Options::MouseWheelCommand Options::mouseWheelCommand(const QString &name) 0953 { 0954 QString lowerName = name.toLower(); 0955 if (lowerName == QStringLiteral("raise/lower")) { 0956 return MouseWheelRaiseLower; 0957 } 0958 if (lowerName == QStringLiteral("shade/unshade")) { 0959 return MouseWheelShadeUnshade; 0960 } 0961 if (lowerName == QStringLiteral("maximize/restore")) { 0962 return MouseWheelMaximizeRestore; 0963 } 0964 if (lowerName == QStringLiteral("above/below")) { 0965 return MouseWheelAboveBelow; 0966 } 0967 if (lowerName == QStringLiteral("previous/next desktop")) { 0968 return MouseWheelPreviousNextDesktop; 0969 } 0970 if (lowerName == QStringLiteral("change opacity")) { 0971 return MouseWheelChangeOpacity; 0972 } 0973 if (lowerName == QStringLiteral("nothing")) { 0974 return MouseWheelNothing; 0975 } 0976 return MouseWheelNothing; 0977 } 0978 0979 bool Options::condensedTitle() const 0980 { 0981 return condensed_title; 0982 } 0983 0984 Options::MouseCommand Options::wheelToMouseCommand(MouseWheelCommand com, int delta) const 0985 { 0986 switch (com) { 0987 case MouseWheelRaiseLower: 0988 return delta > 0 ? MouseRaise : MouseLower; 0989 case MouseWheelShadeUnshade: 0990 return delta > 0 ? MouseSetShade : MouseUnsetShade; 0991 case MouseWheelMaximizeRestore: 0992 return delta > 0 ? MouseMaximize : MouseRestore; 0993 case MouseWheelAboveBelow: 0994 return delta > 0 ? MouseAbove : MouseBelow; 0995 case MouseWheelPreviousNextDesktop: 0996 return delta > 0 ? MousePreviousDesktop : MouseNextDesktop; 0997 case MouseWheelChangeOpacity: 0998 return delta > 0 ? MouseOpacityMore : MouseOpacityLess; 0999 default: 1000 return MouseNothing; 1001 } 1002 } 1003 #endif 1004 1005 double Options::animationTimeFactor() const 1006 { 1007 #ifndef KCMRULES 1008 return m_settings->animationDurationFactor(); 1009 #else 1010 return 0; 1011 #endif 1012 } 1013 1014 Options::WindowOperation Options::operationMaxButtonClick(Qt::MouseButtons button) const 1015 { 1016 return button == Qt::RightButton ? opMaxButtonRightClick : button == Qt::MiddleButton ? opMaxButtonMiddleClick 1017 : opMaxButtonLeftClick; 1018 } 1019 1020 QStringList Options::modifierOnlyDBusShortcut(Qt::KeyboardModifier mod) const 1021 { 1022 return m_modifierOnlyShortcuts.value(mod); 1023 } 1024 1025 bool Options::isUseCompositing() const 1026 { 1027 return m_useCompositing; 1028 } 1029 1030 } // namespace 1031 1032 #include "moc_options.cpp"