1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *********************************************************************/
28 #include <kapplication.h>
31 #include <kglobalsettings.h>
33 #include <QDesktopWidget>
36 #include "compositingprefs.h"
38 #include <kephal/screens.h>
48 : electric_borders( 0 )
49 , electric_border_delay( 0 )
58 unsigned long Options::updateSettings()
60 KSharedConfig::Ptr _config
= KGlobal::config();
61 unsigned long changed
= 0;
62 changed
|= KDecorationOptions::updateSettings( _config
.data() ); // read decoration settings
64 KConfigGroup
config( _config
, "Windows" );
65 moveMode
= stringToMoveResizeMode( config
.readEntry("MoveMode", "Opaque" ));
66 resizeMode
= stringToMoveResizeMode( config
.readEntry("ResizeMode", "Opaque" ));
67 show_geometry_tip
= config
.readEntry("GeometryTip", false);
71 val
= config
.readEntry ("FocusPolicy", "ClickToFocus");
72 focusPolicy
= ClickToFocus
; // what a default :-)
73 if ( val
== "FocusFollowsMouse" )
74 focusPolicy
= FocusFollowsMouse
;
75 else if ( val
== "FocusUnderMouse" )
76 focusPolicy
= FocusUnderMouse
;
77 else if ( val
== "FocusStrictlyUnderMouse" )
78 focusPolicy
= FocusStrictlyUnderMouse
;
80 val
= config
.readEntry ("AltTabStyle", "KDE");
81 altTabStyle
= KDE
; // what a default :-)
85 separateScreenFocus
= config
.readEntry( "SeparateScreenFocus", false );
86 activeMouseScreen
= config
.readEntry( "ActiveMouseScreen", focusPolicy
!= ClickToFocus
);
88 rollOverDesktops
= config
.readEntry("RollOverDesktops", true);
90 // focusStealingPreventionLevel = config.readEntry( "FocusStealingPreventionLevel", 2 );
91 // TODO use low level for now
92 focusStealingPreventionLevel
= config
.readEntry( "FocusStealingPreventionLevel", 1 );
93 focusStealingPreventionLevel
= qMax( 0, qMin( 4, focusStealingPreventionLevel
));
94 if( !focusPolicyIsReasonable()) // #48786, comments #7 and later
95 focusStealingPreventionLevel
= 0;
97 xineramaEnabled
= config
.readEntry ("XineramaEnabled", true);
98 xineramaPlacementEnabled
= config
.readEntry ("XineramaPlacementEnabled", true);
99 xineramaMovementEnabled
= config
.readEntry ("XineramaMovementEnabled", true);
100 xineramaMaximizeEnabled
= config
.readEntry ("XineramaMaximizeEnabled", true);
101 xineramaFullscreenEnabled
= config
.readEntry ("XineramaFullscreenEnabled", true);
103 placement
= Placement::policyFromString( config
.readEntry("Placement"), true );
104 xineramaPlacementScreen
= qBound( -1, config
.readEntry( "XineramaPlacementScreen", -1 ),
105 Kephal::ScreenUtils::numScreens() - 1 );
107 if( focusPolicy
== ClickToFocus
)
110 autoRaiseInterval
= 0;
112 delayFocusInterval
= 0;
116 autoRaise
= config
.readEntry("AutoRaise", false);
117 autoRaiseInterval
= config
.readEntry("AutoRaiseInterval", 0 );
118 delayFocus
= config
.readEntry("DelayFocus", false);
119 delayFocusInterval
= config
.readEntry("DelayFocusInterval", 0 );
122 shadeHover
= config
.readEntry("ShadeHover", false);
123 shadeHoverInterval
= config
.readEntry("ShadeHoverInterval", 250 );
125 // important: autoRaise implies ClickRaise
126 clickRaise
= autoRaise
|| config
.readEntry("ClickRaise", true);
128 borderSnapZone
= config
.readEntry("BorderSnapZone", 10);
129 windowSnapZone
= config
.readEntry("WindowSnapZone", 10);
130 centerSnapZone
= config
.readEntry("CenterSnapZone", 0);
131 snapOnlyWhenOverlapping
= config
.readEntry("SnapOnlyWhenOverlapping", false);
132 electric_borders
= config
.readEntry("ElectricBorders", 0);
133 electric_border_delay
= config
.readEntry("ElectricBorderDelay", 150);
135 OpTitlebarDblClick
= windowOperation( config
.readEntry("TitlebarDoubleClickCommand", "Maximize"), true );
136 setOpMaxButtonLeftClick( windowOperation( config
.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true ));
137 setOpMaxButtonMiddleClick( windowOperation( config
.readEntry("MaximizeButtonMiddleClickCommand", "Maximize (vertical only)"), true ));
138 setOpMaxButtonRightClick( windowOperation( config
.readEntry("MaximizeButtonRightClickCommand", "Maximize (horizontal only)"), true ));
140 ignorePositionClasses
= config
.readEntry("IgnorePositionClasses",QStringList());
141 ignoreFocusStealingClasses
= config
.readEntry("IgnoreFocusStealingClasses",QStringList());
142 // Qt3.2 and older had resource class all lowercase, but Qt3.3 has it capitalized
143 // therefore Client::resourceClass() forces lowercase, force here lowercase as well
144 for( QStringList::Iterator it
= ignorePositionClasses
.begin();
145 it
!= ignorePositionClasses
.end();
147 (*it
) = (*it
).toLower();
148 for( QStringList::Iterator it
= ignoreFocusStealingClasses
.begin();
149 it
!= ignoreFocusStealingClasses
.end();
151 (*it
) = (*it
).toLower();
153 killPingTimeout
= config
.readEntry( "KillPingTimeout", 5000 );
154 hideUtilityWindowsForInactive
= config
.readEntry( "HideUtilityWindowsForInactive", true);
155 showDesktopIsMinimizeAll
= config
.readEntry( "ShowDesktopIsMinimizeAll", false );
158 config
= KConfigGroup( _config
, "MouseBindings" );
159 CmdActiveTitlebar1
= mouseCommand(config
.readEntry("CommandActiveTitlebar1","Raise"), true );
160 CmdActiveTitlebar2
= mouseCommand(config
.readEntry("CommandActiveTitlebar2","Lower"), true );
161 CmdActiveTitlebar3
= mouseCommand(config
.readEntry("CommandActiveTitlebar3","Operations menu"), true );
162 CmdInactiveTitlebar1
= mouseCommand(config
.readEntry("CommandInactiveTitlebar1","Activate and raise"), true );
163 CmdInactiveTitlebar2
= mouseCommand(config
.readEntry("CommandInactiveTitlebar2","Activate and lower"), true );
164 CmdInactiveTitlebar3
= mouseCommand(config
.readEntry("CommandInactiveTitlebar3","Operations menu"), true );
165 CmdTitlebarWheel
= mouseWheelCommand(config
.readEntry("CommandTitlebarWheel","Nothing"));
166 CmdWindow1
= mouseCommand(config
.readEntry("CommandWindow1","Activate, raise and pass click"), false );
167 CmdWindow2
= mouseCommand(config
.readEntry("CommandWindow2","Activate and pass click"), false );
168 CmdWindow3
= mouseCommand(config
.readEntry("CommandWindow3","Activate and pass click"), false );
169 CmdAllModKey
= (config
.readEntry("CommandAllKey","Alt") == "Meta") ? Qt::Key_Meta
: Qt::Key_Alt
;
170 CmdAll1
= mouseCommand(config
.readEntry("CommandAll1","Move"), false );
171 CmdAll2
= mouseCommand(config
.readEntry("CommandAll2","Toggle raise and lower"), false );
172 CmdAll3
= mouseCommand(config
.readEntry("CommandAll3","Resize"), false );
173 CmdAllWheel
= mouseWheelCommand(config
.readEntry("CommandAllWheel","Nothing"));
175 config
=KConfigGroup(_config
,"Compositing");
176 refreshRate
= config
.readEntry( "RefreshRate", 0 );
178 // Read button tooltip animation effect from kdeglobals
179 // Since we want to allow users to enable window decoration tooltips
180 // and not kstyle tooltips and vise-versa, we don't read the
181 // "EffectNoTooltip" setting from kdeglobals.
184 FIXME
: we have no mac style menu implementation in kwin anymore
, so
this just breaks
186 KConfig
_globalConfig("kdeglobals");
187 KConfigGroup
globalConfig(&_globalConfig
, "KDE");
188 topmenus
= globalConfig
.readEntry("macStyle", false);
193 // QToolTip::setGloballyEnabled( d->show_tooltips );
194 // KDE4 this probably needs to be done manually in clients
196 // Driver-specific config detection
197 CompositingPrefs prefs
;
199 reloadCompositingSettings( prefs
);
204 void Options::reloadCompositingSettings(const CompositingPrefs
& prefs
)
206 KSharedConfig::Ptr _config
= KGlobal::config();
207 KConfigGroup
config(_config
, "Compositing");
209 // Compositing settings
210 useCompositing
= config
.readEntry("Enabled", prefs
.enableCompositing());
211 QString compositingBackend
= config
.readEntry("Backend", "OpenGL");
212 if( compositingBackend
== "XRender" )
213 compositingMode
= XRenderCompositing
;
215 compositingMode
= OpenGLCompositing
;
216 disableCompositingChecks
= config
.readEntry("DisableChecks", false);
217 QString glmode
= config
.readEntry("GLMode", "TFP" ).toUpper();
218 if( glmode
== "TFP" )
220 else if( glmode
== "SHM" )
224 glDirect
= config
.readEntry("GLDirect", prefs
.enableDirectRendering() );
225 glVSync
= config
.readEntry("GLVSync", prefs
.enableVSync() );
226 smoothScale
= qBound( -1, config
.readEntry( "GLTextureFilter", -1 ), 2 );
227 glStrictBinding
= config
.readEntry( "GLStrictBinding", prefs
.strictBinding());
229 xrenderSmoothScale
= config
.readEntry("XRenderSmoothScale", false );
231 hiddenPreviews
= HiddenPreviewsShown
;
232 // 4 - off, 5 - shown, 6 - always, other are old values
233 int hps
= config
.readEntry( "HiddenPreviews", 5 );
235 hiddenPreviews
= HiddenPreviewsNever
;
237 hiddenPreviews
= HiddenPreviewsShown
;
239 hiddenPreviews
= HiddenPreviewsAlways
;
241 unredirectFullscreen
= config
.readEntry( "UnredirectFullscreen", true );
242 animationSpeed
= qBound( 0, config
.readEntry( "AnimationSpeed", 3 ), 6 );
244 if( !disableCompositingChecks
&& !prefs
.validateSetup( compositingMode
))
245 useCompositing
= false;
249 // restricted should be true for operations that the user may not be able to repeat
250 // if the window is moved out of the workspace (e.g. if the user moves a window
251 // by the titlebar, and moves it too high beneath Kicker at the top edge, they
252 // may not be able to move it back, unless they know about Alt+LMB)
253 Options::WindowOperation
Options::windowOperation(const QString
&name
, bool restricted
)
256 return restricted
? MoveOp
: UnrestrictedMoveOp
;
257 else if (name
== "Resize")
258 return restricted
? ResizeOp
: UnrestrictedResizeOp
;
259 else if (name
== "Maximize")
261 else if (name
== "Minimize")
263 else if (name
== "Close")
265 else if (name
== "OnAllDesktops")
266 return OnAllDesktopsOp
;
267 else if (name
== "Shade")
269 else if (name
== "Operations")
271 else if (name
== "Maximize (vertical only)")
273 else if (name
== "Maximize (horizontal only)")
275 else if (name
== "Lower")
280 Options::MouseCommand
Options::mouseCommand(const QString
&name
, bool restricted
)
282 QString lowerName
= name
.toLower();
283 if (lowerName
== "raise") return MouseRaise
;
284 if (lowerName
== "lower") return MouseLower
;
285 if (lowerName
== "operations menu") return MouseOperationsMenu
;
286 if (lowerName
== "toggle raise and lower") return MouseToggleRaiseAndLower
;
287 if (lowerName
== "activate and raise") return MouseActivateAndRaise
;
288 if (lowerName
== "activate and lower") return MouseActivateAndLower
;
289 if (lowerName
== "activate") return MouseActivate
;
290 if (lowerName
== "activate, raise and pass click") return MouseActivateRaiseAndPassClick
;
291 if (lowerName
== "activate and pass click") return MouseActivateAndPassClick
;
292 if (lowerName
== "activate, raise and move")
293 return restricted
? MouseActivateRaiseAndMove
: MouseActivateRaiseAndUnrestrictedMove
;
294 if (lowerName
== "move") return restricted
? MouseMove
: MouseUnrestrictedMove
;
295 if (lowerName
== "resize") return restricted
? MouseResize
: MouseUnrestrictedResize
;
296 if (lowerName
== "shade") return MouseShade
;
297 if (lowerName
== "minimize") return MouseMinimize
;
298 if (lowerName
== "nothing") return MouseNothing
;
302 Options::MouseWheelCommand
Options::mouseWheelCommand(const QString
&name
)
304 QString lowerName
= name
.toLower();
305 if (lowerName
== "raise/lower") return MouseWheelRaiseLower
;
306 if (lowerName
== "shade/unshade") return MouseWheelShadeUnshade
;
307 if (lowerName
== "maximize/restore") return MouseWheelMaximizeRestore
;
308 if (lowerName
== "above/below") return MouseWheelAboveBelow
;
309 if (lowerName
== "previous/next desktop") return MouseWheelPreviousNextDesktop
;
310 if (lowerName
== "change opacity") return MouseWheelChangeOpacity
;
311 return MouseWheelNothing
;
314 bool Options::showGeometryTip()
316 return show_geometry_tip
;
319 int Options::electricBorders()
321 return electric_borders
;
324 int Options::electricBorderDelay()
326 return electric_border_delay
;
329 bool Options::checkIgnoreFocusStealing( const Client
* c
)
331 return ignoreFocusStealingClasses
.contains(QString::fromLatin1(c
->resourceClass()));
334 Options::MouseCommand
Options::wheelToMouseCommand( MouseWheelCommand com
, int delta
)
338 case MouseWheelRaiseLower
:
339 return delta
> 0 ? MouseRaise
: MouseLower
;
340 case MouseWheelShadeUnshade
:
341 return delta
> 0 ? MouseSetShade
: MouseUnsetShade
;
342 case MouseWheelMaximizeRestore
:
343 return delta
> 0 ? MouseMaximize
: MouseRestore
;
344 case MouseWheelAboveBelow
:
345 return delta
> 0 ? MouseAbove
: MouseBelow
;
346 case MouseWheelPreviousNextDesktop
:
347 return delta
> 0 ? MousePreviousDesktop
: MouseNextDesktop
;
348 case MouseWheelChangeOpacity
:
349 return delta
> 0 ? MouseOpacityMore
: MouseOpacityLess
;
356 Options::MoveResizeMode
Options::stringToMoveResizeMode( const QString
& s
)
358 return s
== "Opaque" ? Opaque
: Transparent
;
361 const char* Options::moveResizeModeToString( MoveResizeMode mode
)
363 return mode
== Opaque
? "Opaque" : "Transparent";
366 double Options::animationTimeFactor() const
368 const double factors
[] = { 0, 0.2, 0.5, 1, 2, 4, 20 };
369 return factors
[ animationSpeed
];