1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
21 #include "maketransparent.h"
23 #include <kconfiggroup.h>
28 KWIN_EFFECT( maketransparent
, MakeTransparentEffect
)
30 MakeTransparentEffect::MakeTransparentEffect()
35 reconfigure( ReconfigureAll
);
36 active
= effects
->activeWindow();
39 void MakeTransparentEffect::reconfigure( ReconfigureFlags
)
41 KConfigGroup conf
= effects
->effectConfig("MakeTransparent");
42 decoration
= conf
.readEntry( "Decoration", 1.0 );
43 moveresize
= conf
.readEntry( "MoveResize", 0.8 );
44 dialogs
= conf
.readEntry( "Dialogs", 1.0 );
45 inactive
= conf
.readEntry( "Inactive", 1.0 );
46 comboboxpopups
= conf
.readEntry( "ComboboxPopups", 1.0 );
47 menus
= conf
.readEntry( "Menus", 1.0 );
48 individualmenuconfig
= conf
.readEntry( "IndividualMenuConfig", false );
49 if( individualmenuconfig
)
51 dropdownmenus
= conf
.readEntry( "DropdownMenus", 1.0 );
52 popupmenus
= conf
.readEntry( "PopupMenus", 1.0 );
53 tornoffmenus
= conf
.readEntry( "TornOffMenus", 1.0 );
57 dropdownmenus
= menus
;
61 moveresize_timeline
.setCurveShape( TimeLine::EaseOutCurve
);
62 moveresize_timeline
.setDuration( animationTime( conf
, "Duration", 800 ) );
63 activeinactive_timeline
.setCurveShape( TimeLine::EaseInOutCurve
);
64 activeinactive_timeline
.setDuration( animationTime( conf
, "Duration", 800 ) );
66 // Repaint the screen just in case the user changed the inactive opacity
67 effects
->addRepaintFull();
70 void MakeTransparentEffect::prePaintWindow( EffectWindow
* w
, WindowPrePaintData
& data
, int time
)
72 moveresize_timeline
.addTime(time
);
73 activeinactive_timeline
.addTime(time
);
75 if( decoration
!= 1.0 && w
->hasDecoration())
77 data
.mask
|= PAINT_WINDOW_TRANSLUCENT
;
78 // don't clear PAINT_WINDOW_OPAQUE, contents are not affected
79 data
.clip
&= w
->contentsRect().translated( w
->pos()); // decoration cannot clip
81 if( inactive
!= 1.0 && isInactive( w
))
82 data
.setTranslucent();
83 if(( moveresize
!= 1.0 && ( w
->isUserMove() || w
->isUserResize()))
84 || ( dialogs
!= 1.0 && w
->isDialog()))
86 data
.setTranslucent();
88 if( ( dropdownmenus
!= 1.0 && w
->isDropdownMenu() )
89 || ( popupmenus
!= 1.0 && w
->isPopupMenu() )
90 || ( tornoffmenus
!= 1.0 && w
->isMenu() )
91 || ( comboboxpopups
!= 1.0 && w
->isComboBox() ) )
93 data
.setTranslucent();
96 effects
->prePaintWindow( w
, data
, time
);
99 void MakeTransparentEffect::paintWindow( EffectWindow
* w
, int mask
, QRegion region
, WindowPaintData
& data
)
101 // We keep track of the windows that was last active so we know
102 // which one to fade out and which ones to paint as fully inactive
103 if ( w
== active
&& w
!= current
)
109 if ( w
->isDesktop() || w
->isDock() )
111 effects
->paintWindow( w
, mask
, region
, data
);
114 // Handling active and inactive windows
115 if( inactive
!= 1.0 && isInactive(w
) )
117 data
.opacity
*= inactive
;
121 data
.opacity
*= (inactive
+ ((1.0 - inactive
) * (1.0 - activeinactive_timeline
.value())));
122 if ( activeinactive_timeline
.value() < 1.0 )
129 if ( !isInactive(w
) && !w
->isDesktop() )
131 data
.opacity
*= (inactive
+ ((1.0 - inactive
) * activeinactive_timeline
.value()));
132 if ( activeinactive_timeline
.value() < 1.0 )
135 // decoration and dialogs
136 if( decoration
!= 1.0 && w
->hasDecoration())
137 data
.decoration_opacity
*= decoration
;
138 if( dialogs
!= 1.0 && w
->isDialog())
139 data
.opacity
*= dialogs
;
141 // Handling moving and resizing
142 if( moveresize
!= 1.0 && !w
->isDesktop() && !w
->isDock())
144 double progress
= moveresize_timeline
.value();
145 if ( w
->isUserMove() || w
->isUserResize() )
146 { // Fading to translucent
147 data
.opacity
*= (moveresize
+ ((1.0 - moveresize
) * ( 1.0 - progress
)));
148 if (progress
< 1.0 && progress
> 0.0)
156 { // Fading back to more opaque
157 if( w
== fadeout
&& !w
->isUserMove() && !w
->isUserResize() )
159 data
.opacity
*= (moveresize
+ ((1.0 - moveresize
) * (progress
)));
160 if ( progress
== 1.0 || progress
== 0.0)
170 if( dropdownmenus
!= 1.0 && w
->isDropdownMenu() )
171 data
.opacity
*= dropdownmenus
;
172 if( popupmenus
!= 1.0 && w
->isPopupMenu() )
173 data
.opacity
*= popupmenus
;
174 if( tornoffmenus
!= 1.0 && w
->isMenu() )
175 data
.opacity
*= tornoffmenus
;
176 if( comboboxpopups
!= 1.0 && w
->isComboBox() )
177 data
.opacity
*= comboboxpopups
;
180 effects
->paintWindow( w
, mask
, region
, data
);
183 bool MakeTransparentEffect::isInactive( const EffectWindow
* w
) const
185 if( active
== w
|| w
->isDock() || !w
->isManaged() )
187 if( NULL
!= active
&& NULL
!= active
->group() )
188 if (active
->group() == w
->group() )
190 if( !w
->isNormalWindow() && !w
->isDialog() && !w
->isDock() )
195 void MakeTransparentEffect::windowUserMovedResized( EffectWindow
* w
, bool first
, bool last
)
197 if( moveresize
!= 1.0 && ( first
|| last
))
199 moveresize_timeline
.setProgress(0.0);
204 void MakeTransparentEffect::windowActivated( EffectWindow
* w
)
206 if( inactive
!= 1.0 )
208 activeinactive_timeline
.setProgress(0.0);
209 if( NULL
!= active
&& active
!= w
)
211 if( ( NULL
== w
|| w
->group() != active
->group() ) &&
212 NULL
!= active
->group() )
214 // Active group has changed. so repaint old group
215 foreach( EffectWindow
*tmp
, active
->group()->members() )
216 tmp
->addRepaintFull();
219 active
->addRepaintFull();
224 if (NULL
!= w
->group() )
226 // Repaint windows in new group
227 foreach( EffectWindow
*tmp
, w
->group()->members() )
228 tmp
->addRepaintFull();