KWin
Loading...
Searching...
No Matches
windows.cpp
Go to the documentation of this file.
1/*
2 windows.cpp
3
4 SPDX-FileCopyrightText: 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
5 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#include <QApplication>
11#include <QCheckBox>
12#include <QFormLayout>
13#include <QGroupBox>
14#include <QHBoxLayout>
15#include <QLabel>
16#include <QRadioButton>
17#include <QScreen>
18#include <QtDBus>
19
20#include <KConfig>
21#include <KConfigGroup>
22#include <KLocalizedString>
23#include <KWindowSystem>
24
25#include "kwinoptions_settings.h"
26#include "windows.h"
27#include <kwin_effects_interface.h>
28
29#include "kwinoptions_kdeglobals_settings.h"
30#include "kwinoptions_settings.h"
31
32#define CLICK_TO_FOCUS 0
33#define CLICK_TO_FOCUS_MOUSE_PRECEDENT 1
34#define FOCUS_FOLLOWS_MOUSE 2
35#define FOCUS_FOLLOWS_MOUSE_PRECEDENT 3
36#define FOCUS_UNDER_MOUSE 4
37#define FOCUS_STRICTLY_UNDER_MOUSE 5
38
39namespace
40{
41constexpr int defaultFocusPolicyIndex = CLICK_TO_FOCUS;
42}
43
45 : QWidget(parent)
46{
47 setupUi(parent);
48}
49
50KFocusConfig::KFocusConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
51 : KCModule(parent, KPluginMetaData())
52 , standAlone(_standAlone)
53 , m_ui(new KWinFocusConfigForm(widget()))
54{
55 if (settings) {
56 initialize(settings);
57 }
58}
59
60void KFocusConfig::initialize(KWinOptionsSettings *settings)
61{
62 m_settings = settings;
63 addConfig(m_settings, widget());
64
65 connect(m_ui->windowFocusPolicy, qOverload<int>(&QComboBox::currentIndexChanged), this, &KFocusConfig::focusPolicyChanged);
66 connect(m_ui->windowFocusPolicy, qOverload<int>(&QComboBox::currentIndexChanged), this, &KFocusConfig::updateDefaultIndicator);
67 connect(this, SIGNAL(defaultsIndicatorsVisibleChanged(bool)), this, SLOT(updateDefaultIndicator()));
68
69 connect(qApp, &QGuiApplication::screenAdded, this, &KFocusConfig::updateMultiScreen);
70 connect(qApp, &QGuiApplication::screenRemoved, this, &KFocusConfig::updateMultiScreen);
71 updateMultiScreen();
72}
73
74void KFocusConfig::updateMultiScreen()
75{
76 m_ui->multiscreenBehaviorLabel->setVisible(QApplication::screens().count() > 1);
77 m_ui->kcfg_SeparateScreenFocus->setVisible(QApplication::screens().count() > 1);
78}
79
80void KFocusConfig::updateDefaultIndicator()
81{
82 const bool isDefault = m_ui->windowFocusPolicy->currentIndex() == defaultFocusPolicyIndex;
83 m_ui->windowFocusPolicy->setProperty("_kde_highlight_neutral", defaultsIndicatorsVisible() && !isDefault);
84 m_ui->windowFocusPolicy->update();
85}
86
87void KFocusConfig::updateFocusPolicyExplanatoryText()
88{
89 const int focusPolicy = m_ui->windowFocusPolicy->currentIndex();
90 switch (focusPolicy) {
91 case CLICK_TO_FOCUS:
92 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("<em>Click to focus:</em> A window becomes active when you click into it. This behavior is common on other operating systems and likely what you want."));
93 break;
95 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("<em>Click to focus (mouse precedence):</em> Mostly the same as <em>Click to focus</em>. If an active window has to be chosen by the system (eg. because the currently active one was closed) the window under the mouse is the preferred candidate. Unusual, but possible variant of <em>Click to focus</em>."));
96 break;
98 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("<em>Focus follows mouse:</em> Moving the mouse onto a window will activate it. Eg. windows randomly appearing under the mouse will not gain the focus. <em>Focus stealing prevention</em> takes place as usual. Think as <em>Click to focus</em> just without having to actually click."));
99 break;
101 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("This is mostly the same as <em>Focus follows mouse</em>. If an active window has to be chosen by the system (eg. because the currently active one was closed) the window under the mouse is the preferred candidate. Choose this, if you want a hover controlled focus."));
102 break;
104 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("<em>Focus under mouse:</em> The focus always remains on the window under the mouse.<br/><strong>Warning:</strong> <em>Focus stealing prevention</em> and the <em>tabbox ('Alt+Tab')</em> contradict the activation policy and will not work. You very likely want to use <em>Focus follows mouse (mouse precedence)</em> instead!"));
105 break;
107 m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("<em>Focus strictly under mouse:</em> The focus is always on the window under the mouse (in doubt nowhere) very much like the focus behavior in an unmanaged legacy X11 environment.<br/><strong>Warning:</strong> <em>Focus stealing prevention</em> and the <em>tabbox ('Alt+Tab')</em> contradict the activation policy and will not work. You very likely want to use <em>Focus follows mouse (mouse precedence)</em> instead!"));
108 break;
109 }
110}
111
112void KFocusConfig::focusPolicyChanged()
113{
114 int selectedFocusPolicy = 0;
115 bool selectedNextFocusPrefersMouseItem = false;
116 const bool loadedNextFocusPrefersMouseItem = m_settings->nextFocusPrefersMouse();
117
118 updateFocusPolicyExplanatoryText();
119
120 int focusPolicy = m_ui->windowFocusPolicy->currentIndex();
121 switch (focusPolicy) {
122 case CLICK_TO_FOCUS:
123 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::ClickToFocus;
124 break;
126 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::ClickToFocus;
127 selectedNextFocusPrefersMouseItem = true;
128 break;
130 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse;
131 break;
133 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse;
134 selectedNextFocusPrefersMouseItem = true;
135 break;
137 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusUnderMouse;
138 break;
140 selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusStrictlyUnderMouse;
141 break;
142 }
143
144 unmanagedWidgetChangeState(m_settings->focusPolicy() != selectedFocusPolicy || loadedNextFocusPrefersMouseItem != selectedNextFocusPrefersMouseItem);
145
146 unmanagedWidgetDefaultState(focusPolicy == defaultFocusPolicyIndex);
147
148 // the auto raise related widgets are: autoRaise
149 m_ui->kcfg_AutoRaise->setEnabled(focusPolicy != CLICK_TO_FOCUS && focusPolicy != CLICK_TO_FOCUS_MOUSE_PRECEDENT);
150
151 m_ui->kcfg_FocusStealingPreventionLevel->setDisabled(focusPolicy == FOCUS_UNDER_MOUSE || focusPolicy == FOCUS_STRICTLY_UNDER_MOUSE);
152
153 // the delayed focus related widgets are: delayFocus
154 m_ui->delayFocusOnLabel->setEnabled(focusPolicy != CLICK_TO_FOCUS);
155 m_ui->kcfg_DelayFocusInterval->setEnabled(focusPolicy != CLICK_TO_FOCUS);
156}
157
159{
160 KCModule::load();
161
162 const bool loadedNextFocusPrefersMouseItem = m_settings->nextFocusPrefersMouse();
163
164 int focusPolicy = m_settings->focusPolicy();
165
166 switch (focusPolicy) {
167 // the ClickToFocus and FocusFollowsMouse have special values when
168 // NextFocusPrefersMouse is true
169 case KWinOptionsSettings::EnumFocusPolicy::ClickToFocus:
170 m_ui->windowFocusPolicy->setCurrentIndex(CLICK_TO_FOCUS + loadedNextFocusPrefersMouseItem);
171 break;
172 case KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse:
173 m_ui->windowFocusPolicy->setCurrentIndex(FOCUS_FOLLOWS_MOUSE + loadedNextFocusPrefersMouseItem);
174 break;
175 default:
176 // +2 to ignore the two special values
177 m_ui->windowFocusPolicy->setCurrentIndex(focusPolicy + 2);
178 break;
179 }
180 updateFocusPolicyExplanatoryText();
181}
182
184{
185 KCModule::save();
186
187 int idxFocusPolicy = m_ui->windowFocusPolicy->currentIndex();
188 switch (idxFocusPolicy) {
189 case CLICK_TO_FOCUS:
191 m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::ClickToFocus);
192 break;
195 // the ClickToFocus and FocusFollowsMouse have special values when
196 // NextFocusPrefersMouse is true
197 m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse);
198 break;
200 m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusUnderMouse);
201 break;
203 m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusStrictlyUnderMouse);
204 break;
205 }
206 m_settings->setNextFocusPrefersMouse(idxFocusPolicy == CLICK_TO_FOCUS_MOUSE_PRECEDENT || idxFocusPolicy == FOCUS_FOLLOWS_MOUSE_PRECEDENT);
207
208 m_settings->save();
209
210 if (standAlone) {
211 // Send signal to all kwin instances
212 QDBusMessage message =
213 QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
214 QDBusConnection::sessionBus().send(message);
215 }
216}
217
219{
220 KCModule::defaults();
221 m_ui->windowFocusPolicy->setCurrentIndex(defaultFocusPolicyIndex);
222}
223
225 : QWidget(parent)
226{
227 setupUi(parent);
228}
229
230KAdvancedConfig::KAdvancedConfig(bool _standAlone, KWinOptionsSettings *settings, KWinOptionsKDEGlobalsSettings *globalSettings, QWidget *parent)
231 : KCModule(parent, KPluginMetaData())
232 , standAlone(_standAlone)
233 , m_ui(new KWinAdvancedConfigForm(widget()))
234{
235 if (settings && globalSettings) {
236 initialize(settings, globalSettings);
237 }
238}
239
240void KAdvancedConfig::initialize(KWinOptionsSettings *settings, KWinOptionsKDEGlobalsSettings *globalSettings)
241{
242 m_settings = settings;
243 addConfig(m_settings, widget());
244 addConfig(globalSettings, widget());
245
246 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Smart, "Smart");
247 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Maximizing, "Maximizing");
248 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Random, "Random");
249 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Centered, "Centered");
250 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::ZeroCornered, "ZeroCornered");
251 m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::UnderMouse, "UnderMouse");
252
253 // Don't show the option to prevent apps from remembering their window
254 // positions on Wayland because it doesn't work on Wayland and the feature
255 // will eventually be implemented in a different way there.
256 // This option lives in the kdeglobals file because it is consumed by
257 // kxmlgui.
258 m_ui->kcfg_AllowKDEAppsToRememberWindowPositions->setVisible(KWindowSystem::isPlatformX11());
259
260 m_ui->kcfg_ActivationDesktopPolicy->setItemData(KWinOptionsSettings::ActivationDesktopPolicyChoices::SwitchToOtherDesktop, "SwitchToOtherDesktop");
261 m_ui->kcfg_ActivationDesktopPolicy->setItemData(KWinOptionsSettings::ActivationDesktopPolicyChoices::BringToCurrentDesktop, "BringToCurrentDesktop");
262}
263
265{
266 KCModule::save();
267
268 if (standAlone) {
269 // Send signal to all kwin instances
270 QDBusMessage message =
271 QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
272 QDBusConnection::sessionBus().send(message);
273 }
274}
275
277 : QWidget(parent)
278{
279 setupUi(parent);
280}
281
282KMovingConfig::KMovingConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
283 : KCModule(parent, KPluginMetaData())
284 , standAlone(_standAlone)
285 , m_ui(new KWinMovingConfigForm(widget()))
286{
287 if (settings) {
288 initialize(settings);
289 }
290}
291
292void KMovingConfig::initialize(KWinOptionsSettings *settings)
293{
294 m_settings = settings;
295 addConfig(m_settings, widget());
296}
297
299{
300 KCModule::save();
301
302 if (standAlone) {
303 // Send signal to all kwin instances
304 QDBusMessage message =
305 QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
306 QDBusConnection::sessionBus().send(message);
307 }
308}
309
310#include "moc_windows.cpp"
void save() override
Definition windows.cpp:264
void initialize(KWinOptionsSettings *settings, KWinOptionsKDEGlobalsSettings *globalSettings)
Definition windows.cpp:240
KAdvancedConfig(bool _standAlone, KWinOptionsSettings *settings, KWinOptionsKDEGlobalsSettings *globalSettings, QWidget *parent)
Definition windows.cpp:230
void defaults() override
Definition windows.cpp:218
void initialize(KWinOptionsSettings *settings)
Definition windows.cpp:60
void save() override
Definition windows.cpp:183
void load() override
Definition windows.cpp:158
KFocusConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
Definition windows.cpp:50
KMovingConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
Definition windows.cpp:282
void initialize(KWinOptionsSettings *settings)
Definition windows.cpp:292
void save() override
Definition windows.cpp:298
KWinAdvancedConfigForm(QWidget *parent)
Definition windows.cpp:224
KWinFocusConfigForm(QWidget *parent)
Definition windows.cpp:44
KWinMovingConfigForm(QWidget *parent)
Definition windows.cpp:276
#define FOCUS_FOLLOWS_MOUSE
Definition windows.cpp:34
#define CLICK_TO_FOCUS
Definition windows.cpp:32
#define CLICK_TO_FOCUS_MOUSE_PRECEDENT
Definition windows.cpp:33
#define FOCUS_FOLLOWS_MOUSE_PRECEDENT
Definition windows.cpp:35
#define FOCUS_UNDER_MOUSE
Definition windows.cpp:36
#define FOCUS_STRICTLY_UNDER_MOUSE
Definition windows.cpp:37