2 This file is part of the KDE project.
4 Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
25 #include "kcommondecoration.h"
26 #include "kcommondecoration_p.h"
28 #include <QApplication>
37 #include <kapplication.h>
38 #include "kdecorationfactory.h"
41 #include <kephal/screens.h>
43 #include "kcommondecoration.moc"
45 /** @addtogroup kdecoration */
48 KCommonDecoration::KCommonDecoration(KDecorationBridge
* bridge
, KDecorationFactory
* factory
)
53 wrapper( new KCommonDecorationWrapper( this, bridge
, factory
))
56 // sizeof(...) is calculated at compile time
57 memset(m_button
, 0, sizeof(KCommonDecorationButton
*) * NumButtons
);
58 connect( wrapper
, SIGNAL( keepAboveChanged( bool )), this, SIGNAL( keepAboveChanged( bool )));
59 connect( wrapper
, SIGNAL( keepBelowChanged( bool )), this, SIGNAL( keepBelowChanged( bool )));
62 KCommonDecoration::~KCommonDecoration()
64 for (int n
=0; n
<NumButtons
; n
++) {
65 if (m_button
[n
]) delete m_button
[n
];
67 delete m_previewWidget
;
68 // delete wrapper; - do not do this, this object is actually owned and deleted by the wrapper
71 QString
KCommonDecoration::defaultButtonsLeft() const
73 return KDecorationOptions::defaultTitleButtonsLeft();
76 QString
KCommonDecoration::defaultButtonsRight() const
78 return KDecorationOptions::defaultTitleButtonsRight();
81 bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour
) const
97 int KCommonDecoration::layoutMetric(LayoutMetric lm
, bool respectWindowState
, const KCommonDecorationButton
*button
) const
102 case LM_BorderBottom
:
103 case LM_TitleEdgeTop
:
104 case LM_TitleEdgeBottom
:
105 case LM_TitleEdgeLeft
:
106 case LM_TitleEdgeRight
:
107 case LM_TitleBorderLeft
:
108 case LM_TitleBorderRight
:
113 case LM_ButtonHeight
:
117 case LM_ButtonSpacing
:
120 case LM_ButtonMarginTop
:
123 case LM_ExplicitButtonSpacer
:
124 return layoutMetric(LM_ButtonWidth
, respectWindowState
, button
)/2; // half button width by default
131 void KCommonDecoration::init()
135 // for flicker-free redraws
136 widget()->setAttribute(Qt::WA_NoSystemBackground
);
138 widget()->installEventFilter( this );
142 connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
143 connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
148 void KCommonDecoration::reset( unsigned long changed
)
150 if (changed
& SettingButtons
) {
156 QRegion
KCommonDecoration::cornerShape(WindowCorner
)
161 void KCommonDecoration::updateCaption()
163 // This should be reimplemented in decorations for better efficiency
167 void KCommonDecoration::borders( int& left
, int& right
, int& top
, int& bottom
) const
169 left
= layoutMetric(LM_BorderLeft
);
170 right
= layoutMetric(LM_BorderRight
);
171 bottom
= layoutMetric(LM_BorderBottom
);
172 top
= layoutMetric(LM_TitleHeight
) +
173 layoutMetric(LM_TitleEdgeTop
) +
174 layoutMetric(LM_TitleEdgeBottom
);
176 updateLayout(); // TODO!! don't call every time we are in ::borders
179 void KCommonDecoration::updateLayout() const
181 QRect r
= widget()->rect();
182 int r_x
, r_y
, r_x2
, r_y2
;
183 r
.getCoords(&r_x
, &r_y
, &r_x2
, &r_y2
);
185 // layout preview widget
186 if (m_previewWidget
) {
187 const int borderLeft
= layoutMetric(LM_BorderLeft
);
188 const int borderRight
= layoutMetric(LM_BorderRight
);
189 const int borderBottom
= layoutMetric(LM_BorderBottom
);
190 const int titleHeight
= layoutMetric(LM_TitleHeight
);
191 const int titleEdgeTop
= layoutMetric(LM_TitleEdgeTop
);
192 const int titleEdgeBottom
= layoutMetric(LM_TitleEdgeBottom
);
194 int left
= r_x
+borderLeft
;
195 int top
= r_y
+titleEdgeTop
+titleHeight
+titleEdgeBottom
;
196 int width
= r_x2
-borderRight
-left
+1;
197 int height
= r_y2
-borderBottom
-top
+1;
198 m_previewWidget
->setGeometry(left
, top
, width
, height
);
199 moveWidget(left
,top
, m_previewWidget
);
200 resizeWidget(width
, height
, m_previewWidget
);
204 for (int n
=0; n
<NumButtons
; n
++) {
206 QSize newSize
= QSize(layoutMetric(LM_ButtonWidth
, true, m_button
[n
]),
207 layoutMetric(LM_ButtonHeight
, true, m_button
[n
]) );
208 if (newSize
!= m_button
[n
]->size() )
209 m_button
[n
]->setSize(newSize
);
214 int y
= r_y
+ layoutMetric(LM_TitleEdgeTop
) + layoutMetric(LM_ButtonMarginTop
);
215 if (m_buttonsLeft
.count() > 0) {
216 const int buttonSpacing
= layoutMetric(LM_ButtonSpacing
);
217 int x
= r_x
+ layoutMetric(LM_TitleEdgeLeft
);
218 for (ButtonContainer::const_iterator it
= m_buttonsLeft
.begin(); it
!= m_buttonsLeft
.end(); ++it
) {
219 bool elementLayouted
= false;
221 if (!(*it
)->isHidden() ) {
222 moveWidget(x
,y
, *it
);
223 x
+= layoutMetric(LM_ButtonWidth
, true, qobject_cast
<KCommonDecorationButton
*>(*it
) );
224 elementLayouted
= true;
227 x
+= layoutMetric(LM_ExplicitButtonSpacer
);
228 elementLayouted
= true;
230 if (elementLayouted
&& it
!= m_buttonsLeft
.end() )
235 if (m_buttonsRight
.count() > 0) {
236 const int titleEdgeRightLeft
= r_x2
-layoutMetric(LM_TitleEdgeRight
)+1;
238 const int buttonSpacing
= layoutMetric(LM_ButtonSpacing
);
239 int x
= titleEdgeRightLeft
- buttonContainerWidth(m_buttonsRight
);
240 for (ButtonContainer::const_iterator it
= m_buttonsRight
.begin(); it
!= m_buttonsRight
.end(); ++it
) {
241 bool elementLayouted
= false;
243 if (!(*it
)->isHidden() ) {
244 moveWidget(x
,y
, *it
);
245 x
+= layoutMetric(LM_ButtonWidth
, true, qobject_cast
<KCommonDecorationButton
*>(*it
) );;
246 elementLayouted
= true;
249 x
+= layoutMetric(LM_ExplicitButtonSpacer
);
250 elementLayouted
= true;
252 if (elementLayouted
&& it
!= m_buttonsRight
.end() )
258 void KCommonDecoration::updateButtons() const
260 for (int n
=0; n
<NumButtons
; n
++)
261 if (m_button
[n
]) m_button
[n
]->update();
264 void KCommonDecoration::resetButtons() const
266 for (int n
=0; n
<NumButtons
; n
++)
267 if (m_button
[n
]) m_button
[n
]->reset(KCommonDecorationButton::ManualReset
);
270 void KCommonDecoration::resetLayout()
272 for (int n
=0; n
<NumButtons
; n
++) {
278 m_buttonsLeft
.clear();
279 m_buttonsRight
.clear();
281 delete m_previewWidget
;
284 // shown instead of the window contents in decoration previews
286 m_previewWidget
= new QLabel(i18n("<center><b>%1 preview</b></center>", visibleName() ), widget());
287 m_previewWidget
->setAutoFillBackground(true);
288 m_previewWidget
->show();
291 addButtons(m_buttonsLeft
,
292 options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
294 addButtons(m_buttonsRight
,
295 options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
300 const int minTitleBarWidth
= 35;
301 btnHideMinWidth
= buttonContainerWidth(m_buttonsLeft
,true) + buttonContainerWidth(m_buttonsRight
,true) +
302 layoutMetric(LM_TitleEdgeLeft
,false) + layoutMetric(LM_TitleEdgeRight
,false) +
303 layoutMetric(LM_TitleBorderLeft
,false) + layoutMetric(LM_TitleBorderRight
,false) +
305 btnHideLastWidth
= 0;
308 int KCommonDecoration::buttonsLeftWidth() const
310 return buttonContainerWidth(m_buttonsLeft
);
313 int KCommonDecoration::buttonsRightWidth() const
315 return buttonContainerWidth(m_buttonsRight
);
318 int KCommonDecoration::buttonContainerWidth(const ButtonContainer
&btnContainer
, bool countHidden
) const
320 int explicitSpacer
= layoutMetric(LM_ExplicitButtonSpacer
);
322 int shownElementsCount
= 0;
325 for (ButtonContainer::const_iterator it
= btnContainer
.begin(); it
!= btnContainer
.end(); ++it
) {
327 if (countHidden
|| !(*it
)->isHidden() ) {
329 ++shownElementsCount
;
333 ++shownElementsCount
;
336 w
+= layoutMetric(LM_ButtonSpacing
)*(shownElementsCount
-1);
341 void KCommonDecoration::addButtons(ButtonContainer
&btnContainer
, const QString
& s
, bool isLeft
)
343 if (s
.length() > 0) {
344 for (int n
=0; n
< s
.length(); n
++) {
345 KCommonDecorationButton
*btn
= 0;
346 switch (s
[n
].toAscii()) {
347 case 'M': // Menu button
348 if (!m_button
[MenuButton
]){
349 btn
= createButton(MenuButton
);
351 btn
->setTipText(i18n("Menu") );
352 btn
->setRealizeButtons(Qt::LeftButton
|Qt::RightButton
);
353 connect(btn
, SIGNAL(pressed()), SLOT(menuButtonPressed()));
354 connect(btn
, SIGNAL(released()), this, SLOT(menuButtonReleased()));
356 m_button
[MenuButton
] = btn
;
359 case 'S': // OnAllDesktops button
360 if (!m_button
[OnAllDesktopsButton
]){
361 btn
= createButton(OnAllDesktopsButton
);
363 const bool oad
= isOnAllDesktops();
364 btn
->setTipText(oad
?i18n("Not on all desktops"):i18n("On all desktops") );
365 btn
->setToggleButton(true);
367 connect(btn
, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
369 m_button
[OnAllDesktopsButton
] = btn
;
372 case 'H': // Help button
373 if ((!m_button
[HelpButton
]) && providesContextHelp()){
374 btn
= createButton(HelpButton
);
376 btn
->setTipText(i18n("Help") );
377 connect(btn
, SIGNAL(clicked()), SLOT(showContextHelp()));
379 m_button
[HelpButton
] = btn
;
382 case 'I': // Minimize button
383 if ((!m_button
[MinButton
]) && isMinimizable()){
384 btn
= createButton(MinButton
);
386 btn
->setTipText(i18n("Minimize") );
387 connect(btn
, SIGNAL(clicked()), SLOT(minimize()));
389 m_button
[MinButton
] = btn
;
392 case 'A': // Maximize button
393 if ((!m_button
[MaxButton
]) && isMaximizable()){
394 btn
= createButton(MaxButton
);
396 btn
->setRealizeButtons(Qt::LeftButton
|Qt::MidButton
|Qt::RightButton
);
397 const bool max
= maximizeMode()==MaximizeFull
;
398 btn
->setTipText(max
?i18n("Restore"):i18n("Maximize") );
399 btn
->setToggleButton(true);
401 connect(btn
, SIGNAL(clicked()), SLOT(slotMaximize()));
403 m_button
[MaxButton
] = btn
;
406 case 'X': // Close button
407 if ((!m_button
[CloseButton
]) && isCloseable()){
408 btn
= createButton(CloseButton
);
410 btn
->setTipText(i18n("Close") );
411 connect(btn
, SIGNAL(clicked()), SLOT(closeWindow()));
413 m_button
[CloseButton
] = btn
;
416 case 'F': // AboveButton button
417 if (!m_button
[AboveButton
]){
418 btn
= createButton(AboveButton
);
420 bool above
= keepAbove();
421 btn
->setTipText(above
?i18n("Do not keep above others"):i18n("Keep above others") );
422 btn
->setToggleButton(true);
424 connect(btn
, SIGNAL(clicked()), SLOT(slotKeepAbove()));
426 m_button
[AboveButton
] = btn
;
429 case 'B': // BelowButton button
430 if (!m_button
[BelowButton
]){
431 btn
= createButton(BelowButton
);
433 bool below
= keepBelow();
434 btn
->setTipText(below
?i18n("Do not keep below others"):i18n("Keep below others") );
435 btn
->setToggleButton(true);
437 connect(btn
, SIGNAL(clicked()), SLOT(slotKeepBelow()));
439 m_button
[BelowButton
] = btn
;
442 case 'L': // Shade button
443 if ((!m_button
[ShadeButton
]) && isShadeable()){
444 btn
= createButton(ShadeButton
);
446 bool shaded
= isSetShade();
447 btn
->setTipText(shaded
?i18n("Unshade"):i18n("Shade") );
448 btn
->setToggleButton(true);
449 btn
->setOn( shaded
);
450 connect(btn
, SIGNAL(clicked()), SLOT(slotShade()));
452 m_button
[ShadeButton
] = btn
;
455 case '_': // Spacer item
456 btnContainer
.append(0);
461 btn
->setLeft(isLeft
);
462 btn
->setSize(QSize(layoutMetric(LM_ButtonWidth
, true, btn
),layoutMetric(LM_ButtonHeight
, true, btn
)) );
464 btnContainer
.append(btn
);
471 void KCommonDecoration::calcHiddenButtons()
473 if (width() == btnHideLastWidth
)
476 btnHideLastWidth
= width();
478 //Hide buttons in the following order:
479 KCommonDecorationButton
* btnArray
[] = { m_button
[HelpButton
], m_button
[ShadeButton
], m_button
[BelowButton
],
480 m_button
[AboveButton
], m_button
[OnAllDesktopsButton
], m_button
[MaxButton
],
481 m_button
[MinButton
], m_button
[MenuButton
], m_button
[CloseButton
] };
482 const int buttonsCount
= sizeof( btnArray
) / sizeof( btnArray
[ 0 ] );
484 int current_width
= width();
488 while (current_width
< btnHideMinWidth
&& count
< buttonsCount
)
490 if (btnArray
[count
] ) {
491 current_width
+= btnArray
[count
]->width();
492 if (btnArray
[count
]->isVisible() )
493 btnArray
[count
]->hide();
497 // Show the rest of the buttons...
498 for(int i
= count
; i
< buttonsCount
; i
++)
502 if (! btnArray
[i
]->isHidden() )
503 break; // all buttons shown...
510 void KCommonDecoration::show()
512 if (decorationBehaviour(DB_ButtonHide
) )
517 void KCommonDecoration::resize( const QSize
& s
)
519 widget()->resize( s
);
522 QSize
KCommonDecoration::minimumSize() const
524 const int minWidth
= qMax(layoutMetric(LM_TitleEdgeLeft
), layoutMetric(LM_BorderLeft
))
525 +qMax(layoutMetric(LM_TitleEdgeRight
), layoutMetric(LM_BorderRight
))
526 +layoutMetric(LM_TitleBorderLeft
)+layoutMetric(LM_TitleBorderRight
);
527 return QSize(minWidth
,
528 layoutMetric(LM_TitleEdgeTop
)+layoutMetric(LM_TitleHeight
)
529 +layoutMetric(LM_TitleEdgeBottom
)
530 +layoutMetric(LM_BorderBottom
) );
533 void KCommonDecoration::maximizeChange()
535 if( m_button
[MaxButton
] ) {
536 m_button
[MaxButton
]->setOn( maximizeMode()==MaximizeFull
);
537 m_button
[MaxButton
]->setTipText( (maximizeMode()!=MaximizeFull
) ?
540 m_button
[MaxButton
]->reset(KCommonDecorationButton::StateChange
);
546 void KCommonDecoration::desktopChange()
548 if ( m_button
[OnAllDesktopsButton
] ) {
549 m_button
[OnAllDesktopsButton
]->setOn( isOnAllDesktops() );
550 m_button
[OnAllDesktopsButton
]->setTipText( isOnAllDesktops() ?
551 i18n("Not on all desktops")
552 : i18n("On all desktops"));
553 m_button
[OnAllDesktopsButton
]->reset(KCommonDecorationButton::StateChange
);
557 void KCommonDecoration::shadeChange()
559 if ( m_button
[ShadeButton
] ) {
560 bool shaded
= isSetShade();
561 m_button
[ShadeButton
]->setOn( shaded
);
562 m_button
[ShadeButton
]->setTipText( shaded
?
565 m_button
[ShadeButton
]->reset(KCommonDecorationButton::StateChange
);
569 void KCommonDecoration::iconChange()
571 if (m_button
[MenuButton
])
573 m_button
[MenuButton
]->update();
574 m_button
[MenuButton
]->reset(KCommonDecorationButton::IconChange
);
578 void KCommonDecoration::activeChange()
581 widget()->update(); // do something similar to updateCaption here
584 void KCommonDecoration::captionChange()
589 void KCommonDecoration::keepAboveChange(bool above
)
591 if (m_button
[AboveButton
])
593 m_button
[AboveButton
]->setOn(above
);
594 m_button
[AboveButton
]->setTipText( above
?i18n("Do not keep above others"):i18n("Keep above others") );
595 m_button
[AboveButton
]->reset(KCommonDecorationButton::StateChange
);
598 if (m_button
[BelowButton
] && m_button
[BelowButton
]->isChecked())
600 m_button
[BelowButton
]->setOn(false);
601 m_button
[BelowButton
]->setTipText( i18n("Keep below others") );
602 m_button
[BelowButton
]->reset(KCommonDecorationButton::StateChange
);
606 void KCommonDecoration::keepBelowChange(bool below
)
608 if (m_button
[BelowButton
])
610 m_button
[BelowButton
]->setOn(below
);
611 m_button
[BelowButton
]->setTipText( below
?i18n("Do not keep below others"):i18n("Keep below others") );
612 m_button
[BelowButton
]->reset(KCommonDecorationButton::StateChange
);
615 if (m_button
[AboveButton
] && m_button
[AboveButton
]->isChecked())
617 m_button
[AboveButton
]->setOn(false);
618 m_button
[AboveButton
]->setTipText( i18n("Keep above others") );
619 m_button
[AboveButton
]->reset(KCommonDecorationButton::StateChange
);
623 void KCommonDecoration::slotMaximize()
625 if (m_button
[MaxButton
])
627 maximize(m_button
[MaxButton
]->lastMousePress() );
631 void KCommonDecoration::slotShade()
633 setShade( !isSetShade() );
636 void KCommonDecoration::slotKeepAbove()
638 setKeepAbove(!keepAbove() );
641 void KCommonDecoration::slotKeepBelow()
643 setKeepBelow(!keepBelow() );
646 void KCommonDecoration::menuButtonPressed()
648 static QTime
* t
= NULL
;
649 static KCommonDecoration
* lastClient
= NULL
;
652 bool dbl
= (lastClient
==this && t
->elapsed() <= QApplication::doubleClickInterval());
655 if (!dbl
|| !decorationBehaviour(DB_MenuClose
) ) {
656 QRect menuRect
= m_button
[MenuButton
]->rect();
657 QPoint menutop
= m_button
[MenuButton
]->mapToGlobal(menuRect
.topLeft());
658 QPoint menubottom
= m_button
[MenuButton
]->mapToGlobal(menuRect
.bottomRight())+QPoint(0,2);
659 KDecorationFactory
* f
= factory();
660 showWindowMenu(QRect(menutop
, menubottom
));
661 if( !f
->exists( decoration())) // 'this' was deleted
663 m_button
[MenuButton
]->setDown(false);
669 void KCommonDecoration::menuButtonReleased()
675 void KCommonDecoration::resizeEvent(QResizeEvent */
*e*/
)
677 if (decorationBehaviour(DB_ButtonHide
) )
683 // FIXME: don't update() here! this would result in two paintEvent()s
684 // because there is already "something" else triggering the repaint...
685 // widget()->update();
688 void KCommonDecoration::moveWidget(int x
, int y
, QWidget
*widget
) const
690 QPoint p
= widget
->pos();
694 if (x
!=oldX
|| y
!=oldY
)
698 void KCommonDecoration::resizeWidget(int w
, int h
, QWidget
*widget
) const
700 QSize s
= widget
->size();
701 int oldW
= s
.width();
702 int oldH
= s
.height();
704 if (w
!=oldW
|| h
!=oldH
)
708 void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent
*e
)
710 if( e
->button() != Qt::LeftButton
)
713 int tb
= layoutMetric(LM_TitleEdgeTop
)+layoutMetric(LM_TitleHeight
)+layoutMetric(LM_TitleEdgeBottom
);
714 // when shaded, react on double clicks everywhere to make it easier to unshade. otherwise
715 // react only on double clicks in the title bar region...
716 if (isSetShade() || e
->pos().y() <= tb
)
717 titlebarDblClickOperation();
720 void KCommonDecoration::wheelEvent(QWheelEvent
*e
)
722 int tb
= layoutMetric(LM_TitleEdgeTop
)+layoutMetric(LM_TitleHeight
)+layoutMetric(LM_TitleEdgeBottom
);
723 if (isSetShade() || e
->pos().y() <= tb
)
724 titlebarMouseWheelOperation( e
->delta());
727 KCommonDecoration::Position
KCommonDecoration::mousePosition(const QPoint
&point
) const
729 const int corner
= 18+3*layoutMetric(LM_BorderBottom
, false)/2;
730 Position pos
= PositionCenter
;
732 QRect r
= widget()->rect();
733 int r_x
, r_y
, r_x2
, r_y2
;
734 r
.getCoords(&r_x
, &r_y
, &r_x2
, &r_y2
);
737 const int borderLeft
= layoutMetric(LM_BorderLeft
);
738 // const int borderRight = layoutMetric(LM_BorderRight);
739 const int borderBottom
= layoutMetric(LM_BorderBottom
);
740 const int titleHeight
= layoutMetric(LM_TitleHeight
);
741 const int titleEdgeTop
= layoutMetric(LM_TitleEdgeTop
);
742 const int titleEdgeBottom
= layoutMetric(LM_TitleEdgeBottom
);
743 const int titleEdgeLeft
= layoutMetric(LM_TitleEdgeLeft
);
744 const int titleEdgeRight
= layoutMetric(LM_TitleEdgeRight
);
746 const int borderBottomTop
= r_y2
-borderBottom
+1;
747 const int borderLeftRight
= r_x
+borderLeft
-1;
748 // const int borderRightLeft = r_x2-borderRight+1;
749 const int titleEdgeLeftRight
= r_x
+titleEdgeLeft
-1;
750 const int titleEdgeRightLeft
= r_x2
-titleEdgeRight
+1;
751 const int titleEdgeBottomBottom
= r_y
+titleEdgeTop
+titleHeight
+titleEdgeBottom
-1;
752 const int titleEdgeTopBottom
= r_y
+titleEdgeTop
-1;
754 if (p_y
<= titleEdgeTopBottom
) {
755 if (p_x
<= r_x
+corner
)
756 pos
= PositionTopLeft
;
757 else if (p_x
>= r_x2
-corner
)
758 pos
= PositionTopRight
;
761 } else if (p_y
<= titleEdgeBottomBottom
) {
762 if (p_x
<= titleEdgeLeftRight
)
763 pos
= PositionTopLeft
;
764 else if (p_x
>= titleEdgeRightLeft
)
765 pos
= PositionTopRight
;
767 pos
= PositionCenter
; // title bar
768 } else if (p_y
< borderBottomTop
) {
769 if (p_y
< r_y2
-corner
) {
770 if (p_x
<= borderLeftRight
)
775 if (p_x
<= borderLeftRight
)
776 pos
= PositionBottomLeft
;
778 pos
= PositionBottomRight
;
780 } else if(p_y
>= borderBottomTop
) {
781 if (p_x
<= r_x
+corner
)
782 pos
= PositionBottomLeft
;
783 else if (p_x
>= r_x2
-corner
)
784 pos
= PositionBottomRight
;
786 pos
= PositionBottom
;
792 void KCommonDecoration::updateWindowShape()
794 // don't mask the widget...
795 if (!decorationBehaviour(DB_WindowMask
) )
798 int w
= widget()->width();
799 int h
= widget()->height();
801 bool tl
=true,tr
=true,bl
=true,br
=true; // is there a transparent rounded corner in top-left? etc
803 // no transparent rounded corners if this window corner lines up with a screen corner
804 for(int screen
=0; screen
< Kephal::ScreenUtils::numScreens(); ++screen
)
806 QRect
fullscreen(Kephal::ScreenUtils::screenGeometry(screen
));
807 QRect window
= geometry();
809 if(window
.topLeft() == fullscreen
.topLeft() ) tl
= false;
810 if(window
.topRight() == fullscreen
.topRight() ) tr
= false;
811 if(window
.bottomLeft() == fullscreen
.bottomLeft() ) bl
= false;
812 if(window
.bottomRight()== fullscreen
.bottomRight() ) br
= false;
815 QRegion
mask(0, 0, w
, h
);
817 // Remove top-left corner.
820 mask
-= cornerShape(WC_TopLeft
);
822 // Remove top-right corner.
825 mask
-= cornerShape(WC_TopRight
);
827 // Remove top-left corner.
830 mask
-= cornerShape(WC_BottomLeft
);
832 // Remove top-right corner.
835 mask
-= cornerShape(WC_BottomRight
);
841 bool KCommonDecoration::eventFilter( QObject
* o
, QEvent
* e
)
848 resizeEvent(static_cast<QResizeEvent
*>(e
) );
851 paintEvent( static_cast< QPaintEvent
* >( e
));
853 case QEvent::MouseButtonDblClick
:
854 mouseDoubleClickEvent( static_cast< QMouseEvent
* >( e
));
856 case QEvent::MouseButtonPress
:
857 processMousePressEvent( static_cast< QMouseEvent
* >( e
));
860 wheelEvent( static_cast< QWheelEvent
* >( e
));
867 const int SUPPORTED_WINDOW_TYPES_MASK
= NET::NormalMask
| NET::DesktopMask
| NET::DockMask
868 | NET::ToolbarMask
| NET::MenuMask
| NET::DialogMask
/*| NET::OverrideMask*/ | NET::TopMenuMask
869 | NET::UtilityMask
| NET::SplashMask
;
871 bool KCommonDecoration::isToolWindow() const
873 NET::WindowType type
= windowType( SUPPORTED_WINDOW_TYPES_MASK
);
874 return ((type
==NET::Toolbar
)||(type
==NET::Utility
)||(type
==NET::Menu
));
877 QRect
KCommonDecoration::titleRect() const
879 int r_x
, r_y
, r_x2
, r_y2
;
880 widget()->rect().getCoords(&r_x
, &r_y
, &r_x2
, &r_y2
);
881 const int titleEdgeLeft
= layoutMetric(LM_TitleEdgeLeft
);
882 const int titleEdgeTop
= layoutMetric(LM_TitleEdgeTop
);
883 const int titleEdgeRight
= layoutMetric(LM_TitleEdgeRight
);
884 const int titleEdgeBottom
= layoutMetric(LM_TitleEdgeBottom
);
885 const int titleBorderLeft
= layoutMetric(LM_TitleBorderLeft
);
886 const int titleBorderRight
= layoutMetric(LM_TitleBorderRight
);
887 const int ttlHeight
= layoutMetric(LM_TitleHeight
);
888 const int titleEdgeBottomBottom
= r_y
+titleEdgeTop
+ttlHeight
+titleEdgeBottom
-1;
889 return QRect(r_x
+titleEdgeLeft
+buttonsLeftWidth()+titleBorderLeft
, r_y
+titleEdgeTop
,
890 r_x2
-titleEdgeRight
-buttonsRightWidth()-titleBorderRight
-(r_x
+titleEdgeLeft
+buttonsLeftWidth()+titleBorderLeft
),
891 titleEdgeBottomBottom
-(r_y
+titleEdgeTop
) );
895 KCommonDecorationButton::KCommonDecorationButton(ButtonType type
, KCommonDecoration
*parent
)
896 : QAbstractButton(parent
->widget() ),
897 m_decoration(parent
),
899 m_realizeButtons(Qt::LeftButton
),
900 m_lastMouse(Qt::NoButton
),
903 setCursor(Qt::ArrowCursor
);
906 KCommonDecorationButton::~KCommonDecorationButton()
910 KCommonDecoration
*KCommonDecorationButton::decoration() const
915 ButtonType
KCommonDecorationButton::type() const
920 bool KCommonDecorationButton::isLeft() const
925 void KCommonDecorationButton::setLeft(bool left
)
930 void KCommonDecorationButton::setRealizeButtons(int btns
)
932 m_realizeButtons
= btns
;
935 void KCommonDecorationButton::setSize(const QSize
&s
)
937 if (!m_size
.isValid() || s
!= size() ) {
940 setFixedSize(m_size
);
945 QSize
KCommonDecorationButton::sizeHint() const
950 void KCommonDecorationButton::setTipText(const QString
&tip
) {
951 this->setToolTip( tip
);
954 void KCommonDecorationButton::setToggleButton(bool toggle
)
956 QAbstractButton::setCheckable(toggle
);
960 void KCommonDecorationButton::setOn(bool on
)
962 if (on
!= isChecked() ) {
963 QAbstractButton::setChecked(on
);
968 void KCommonDecorationButton::mousePressEvent(QMouseEvent
* e
)
970 m_lastMouse
= e
->button();
971 // pass on event after changing button to LeftButton
972 QMouseEvent
me(e
->type(), e
->pos(), (e
->button()&m_realizeButtons
)?Qt::LeftButton
: Qt::NoButton
, e
->buttons(), e
->modifiers() );
974 QAbstractButton::mousePressEvent(&me
);
977 void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent
* e
)
979 m_lastMouse
= e
->button();
980 // pass on event after changing button to LeftButton
981 QMouseEvent
me(e
->type(), e
->pos(), (e
->button()&m_realizeButtons
)?Qt::LeftButton
: Qt::NoButton
, e
->buttons(), e
->modifiers() );
983 QAbstractButton::mouseReleaseEvent(&me
);
988 // *** wrap everything from KDecoration *** //
989 bool KCommonDecoration::drawbound( const QRect
&, bool )
993 bool KCommonDecoration::windowDocked( Position
)
997 const KDecorationOptions
* KCommonDecoration::options()
999 return KDecoration::options();
1001 bool KCommonDecoration::isActive() const
1003 return wrapper
->isActive();
1005 bool KCommonDecoration::isCloseable() const
1007 return wrapper
->isCloseable();
1009 bool KCommonDecoration::isMaximizable() const
1011 return wrapper
->isMaximizable();
1013 KCommonDecoration::MaximizeMode
KCommonDecoration::maximizeMode() const
1015 return wrapper
->maximizeMode();
1017 bool KCommonDecoration::isMinimizable() const
1019 return wrapper
->isMinimizable();
1021 bool KCommonDecoration::providesContextHelp() const
1023 return wrapper
->providesContextHelp();
1025 int KCommonDecoration::desktop() const
1027 return wrapper
->desktop();
1029 bool KCommonDecoration::isOnAllDesktops() const
1031 return wrapper
->isOnAllDesktops();
1033 bool KCommonDecoration::isModal() const
1035 return wrapper
->isModal();
1037 bool KCommonDecoration::isShadeable() const
1039 return wrapper
->isShadeable();
1041 bool KCommonDecoration::isShade() const
1043 return wrapper
->isShade();
1045 bool KCommonDecoration::isSetShade() const
1047 return wrapper
->isSetShade();
1049 bool KCommonDecoration::keepAbove() const
1051 return wrapper
->keepAbove();
1053 bool KCommonDecoration::keepBelow() const
1055 return wrapper
->keepBelow();
1057 bool KCommonDecoration::isMovable() const
1059 return wrapper
->isMovable();
1061 bool KCommonDecoration::isResizable() const
1063 return wrapper
->isResizable();
1065 NET::WindowType
KCommonDecoration::windowType( unsigned long supported_types
) const
1067 return wrapper
->windowType( supported_types
);
1069 QIcon
KCommonDecoration::icon() const
1071 return wrapper
->icon();
1073 QString
KCommonDecoration::caption() const
1075 return wrapper
->caption();
1077 void KCommonDecoration::showWindowMenu( const QRect
&pos
)
1079 return wrapper
->showWindowMenu( pos
);
1081 void KCommonDecoration::showWindowMenu( QPoint pos
)
1083 return wrapper
->showWindowMenu( pos
);
1085 void KCommonDecoration::performWindowOperation( WindowOperation op
)
1087 return wrapper
->performWindowOperation( op
);
1089 void KCommonDecoration::setMask( const QRegion
& reg
, int mode
)
1091 return wrapper
->setMask( reg
, mode
);
1093 void KCommonDecoration::clearMask()
1095 return wrapper
->clearMask();
1097 bool KCommonDecoration::isPreview() const
1099 return wrapper
->isPreview();
1101 QRect
KCommonDecoration::geometry() const
1103 return wrapper
->geometry();
1105 QRect
KCommonDecoration::iconGeometry() const
1107 return wrapper
->iconGeometry();
1109 QRegion
KCommonDecoration::unobscuredRegion( const QRegion
& r
) const
1111 return wrapper
->unobscuredRegion( r
);
1113 WId
KCommonDecoration::windowId() const
1115 return wrapper
->windowId();
1117 int KCommonDecoration::width() const
1119 return wrapper
->width();
1121 int KCommonDecoration::height() const
1123 return wrapper
->height();
1125 void KCommonDecoration::processMousePressEvent( QMouseEvent
* e
)
1127 return wrapper
->processMousePressEvent( e
);
1129 void KCommonDecoration::setMainWidget( QWidget
* w
)
1131 return wrapper
->setMainWidget( w
);
1133 void KCommonDecoration::createMainWidget( Qt::WFlags flags
)
1135 return wrapper
->createMainWidget( flags
);
1137 QWidget
* KCommonDecoration::initialParentWidget() const
1139 return wrapper
->initialParentWidget();
1141 Qt::WFlags
KCommonDecoration::initialWFlags() const
1143 return wrapper
->initialWFlags();
1145 QWidget
* KCommonDecoration::widget()
1147 return wrapper
->widget();
1149 const QWidget
* KCommonDecoration::widget() const
1151 return wrapper
->widget();
1153 KDecorationFactory
* KCommonDecoration::factory() const
1155 return wrapper
->factory();
1157 void KCommonDecoration::grabXServer()
1159 return wrapper
->grabXServer();
1161 void KCommonDecoration::ungrabXServer()
1163 return wrapper
->ungrabXServer();
1165 void KCommonDecoration::closeWindow()
1167 return wrapper
->closeWindow();
1169 void KCommonDecoration::maximize( Qt::MouseButtons button
)
1171 return wrapper
->maximize( button
);
1173 void KCommonDecoration::maximize( MaximizeMode mode
)
1175 return wrapper
->maximize( mode
);
1177 void KCommonDecoration::minimize()
1179 return wrapper
->minimize();
1181 void KCommonDecoration::showContextHelp()
1183 return wrapper
->showContextHelp();
1185 void KCommonDecoration::setDesktop( int desktop
)
1187 return wrapper
->setDesktop( desktop
);
1189 void KCommonDecoration::toggleOnAllDesktops()
1191 return wrapper
->toggleOnAllDesktops();
1193 void KCommonDecoration::titlebarDblClickOperation()
1195 return wrapper
->titlebarDblClickOperation();
1197 void KCommonDecoration::titlebarMouseWheelOperation( int delta
)
1199 return wrapper
->titlebarMouseWheelOperation( delta
);
1201 void KCommonDecoration::setShade( bool set
)
1203 return wrapper
->setShade( set
);
1205 void KCommonDecoration::setKeepAbove( bool set
)
1207 return wrapper
->setKeepAbove( set
);
1209 void KCommonDecoration::setKeepBelow( bool set
)
1211 return wrapper
->setKeepBelow( set
);
1213 // *** end of wrapping of everything from KDecoration *** //
1215 const KDecoration
* KCommonDecoration::decoration() const
1219 KDecoration
* KCommonDecoration::decoration()
1225 KCommonDecorationUnstable::KCommonDecorationUnstable(KDecorationBridge
* bridge
, KDecorationFactory
* factory
)
1226 : KCommonDecoration( bridge
, factory
)
1228 Q_ASSERT( dynamic_cast<const KDecorationUnstable
*>( decoration() ));
1231 KCommonDecorationUnstable::~KCommonDecorationUnstable()
1235 // All copied from kdecoration.cpp
1236 QList
<QRect
> KCommonDecorationUnstable::shadowQuads( ShadowType type
) const
1239 return QList
<QRect
>();
1241 double KCommonDecorationUnstable::shadowOpacity( ShadowType type
) const
1243 if( isActive() && type
== ShadowBorderedActive
)
1245 else if( !isActive() && type
== ShadowBorderedInactive
)
1249 double KCommonDecorationUnstable::shadowBrightness( ShadowType type
) const
1254 double KCommonDecorationUnstable::shadowSaturation( ShadowType type
) const
1260 void KCommonDecorationUnstable::repaintShadow()
1262 return static_cast<const KDecorationUnstable
*>( decoration() )->repaintShadow();
1264 bool KCommonDecorationUnstable::compositingActive() const
1266 return static_cast<const KDecorationUnstable
*>( decoration() )->compositingActive();
1268 bool KCommonDecorationUnstable::shadowsActive() const
1270 return static_cast<const KDecorationUnstable
*>( decoration() )->shadowsActive();
1272 double KCommonDecorationUnstable::opacity() const
1274 return static_cast<const KDecorationUnstable
*>( decoration() )->opacity();
1277 // kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;