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
const int paddingLeft = layoutMetric(LM_OuterPaddingLeft);
182
const int paddingTop = layoutMetric(LM_OuterPaddingTop);
183
const int paddingRight = layoutMetric(LM_OuterPaddingRight);
184
const int paddingBottom = layoutMetric(LM_OuterPaddingBottom);
186
QRect r = widget()->rect().adjusted(paddingLeft, paddingTop, -paddingRight, -paddingBottom);
187
int r_x, r_y, r_x2, r_y2;
188
r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
190
// layout preview widget
191
if (m_previewWidget) {
192
const int borderLeft = layoutMetric(LM_BorderLeft);
193
const int borderRight = layoutMetric(LM_BorderRight);
194
const int borderBottom = layoutMetric(LM_BorderBottom);
195
const int titleHeight = layoutMetric(LM_TitleHeight);
196
const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
197
const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
199
int left = r_x + borderLeft;
200
int top = r_y + titleEdgeTop + titleHeight + titleEdgeBottom;
201
int width = r_x2 - borderRight - left + 1;
202
int height = r_y2 - borderBottom - top + 1;
203
m_previewWidget->setGeometry(left, top, width, height);
204
moveWidget(left, top, m_previewWidget);
205
resizeWidget(width, height, m_previewWidget);
209
for (int n = 0; n < NumButtons; n++) {
211
QSize newSize = QSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
212
layoutMetric(LM_ButtonHeight, true, m_button[n]));
213
if (newSize != m_button[n]->size())
214
m_button[n]->setSize(newSize);
219
int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
220
if (m_buttonsLeft.count() > 0) {
221
const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
222
int x = r_x + layoutMetric(LM_TitleEdgeLeft);
223
for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
224
bool elementLayouted = false;
226
if (!(*it)->isHidden()) {
227
moveWidget(x, y, *it);
228
x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it));
229
elementLayouted = true;
232
x += layoutMetric(LM_ExplicitButtonSpacer);
233
elementLayouted = true;
235
if (elementLayouted && it != m_buttonsLeft.end())
240
if (m_buttonsRight.count() > 0) {
241
const int titleEdgeRightLeft = r_x2 - layoutMetric(LM_TitleEdgeRight) + 1;
243
const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
244
int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
245
for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
246
bool elementLayouted = false;
248
if (!(*it)->isHidden()) {
249
moveWidget(x, y, *it);
250
x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it));;
251
elementLayouted = true;
254
x += layoutMetric(LM_ExplicitButtonSpacer);
255
elementLayouted = true;
257
if (elementLayouted && it != m_buttonsRight.end())
263
void KCommonDecoration::updateButtons() const
265
for (int n = 0; n < NumButtons; n++)
266
if (m_button[n]) m_button[n]->update();
269
void KCommonDecoration::resetButtons() const
271
for (int n = 0; n < NumButtons; n++)
272
if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
275
void KCommonDecoration::resetLayout()
277
for (int n = 0; n < NumButtons; n++) {
283
m_buttonsLeft.clear();
284
m_buttonsRight.clear();
286
delete m_previewWidget;
289
// shown instead of the window contents in decoration previews
291
m_previewWidget = new QLabel(i18n("<center><b>%1</b></center>", visibleName()), widget());
292
m_previewWidget->setAutoFillBackground(true);
293
m_previewWidget->show();
295
// fix double deletion, see buttonDestroyed()
296
connect(m_previewWidget, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
299
addButtons(m_buttonsLeft,
300
options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
302
addButtons(m_buttonsRight,
303
options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
308
const int minTitleBarWidth = 35;
309
btnHideMinWidth = buttonContainerWidth(m_buttonsLeft, true) + buttonContainerWidth(m_buttonsRight, true) +
310
layoutMetric(LM_TitleEdgeLeft, false) + layoutMetric(LM_TitleEdgeRight, false) +
311
layoutMetric(LM_TitleBorderLeft, false) + layoutMetric(LM_TitleBorderRight, false) +
313
btnHideLastWidth = 0;
316
void KCommonDecoration::objDestroyed(QObject *obj)
318
// make sure button deletion is reflected in the m_button[] array.
319
// this makes sure that m_button[]-entries are not destroyed
320
// twice, first in their KCommonDecorationButton/QObject
321
// destructor (button objects are parented with the decroation
322
// widget in KCommonDecoration constructor), and then in
323
// ~KCommonDecoration. a QPointer<KCommonDecorationButton> would
324
// have been the better approach, but changing the button array
325
// would have been ABI incompatible & would have required creation
326
// of kcommondecorationprivate instance.
327
// the same applies to m_previewWidget.
328
for (int n = 0; n < NumButtons; n++) {
329
if (m_button[n] == obj) {
334
if (obj == m_previewWidget)
338
int KCommonDecoration::buttonsLeftWidth() const
340
return buttonContainerWidth(m_buttonsLeft);
343
int KCommonDecoration::buttonsRightWidth() const
345
return buttonContainerWidth(m_buttonsRight);
348
int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
350
int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
352
int shownElementsCount = 0;
355
for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
357
if (countHidden || !(*it)->isHidden()) {
359
++shownElementsCount;
363
++shownElementsCount;
366
w += layoutMetric(LM_ButtonSpacing) * (shownElementsCount - 1);
371
void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
373
if (s.length() > 0) {
374
for (int n = 0; n < s.length(); n++) {
375
KCommonDecorationButton *btn = 0;
376
switch(s[n].toAscii()) {
377
case 'M': // Menu button
378
if (!m_button[MenuButton]) {
379
btn = createButton(MenuButton);
381
btn->setTipText(i18n("Menu"));
382
btn->setRealizeButtons(Qt::LeftButton | Qt::RightButton);
383
connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
384
connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
386
// fix double deletion, see objDestroyed()
387
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
389
m_button[MenuButton] = btn;
392
case 'S': // OnAllDesktops button
393
if (!m_button[OnAllDesktopsButton]) {
394
btn = createButton(OnAllDesktopsButton);
396
const bool oad = isOnAllDesktops();
397
btn->setTipText(oad ? i18n("Not on all desktops") : i18n("On all desktops"));
398
btn->setToggleButton(true);
400
connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
402
// fix double deletion, see objDestroyed()
403
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
405
m_button[OnAllDesktopsButton] = btn;
408
case 'H': // Help button
409
if ((!m_button[HelpButton]) && providesContextHelp()) {
410
btn = createButton(HelpButton);
412
btn->setTipText(i18n("Help"));
413
connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
415
// fix double deletion, see objDestroyed()
416
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
418
m_button[HelpButton] = btn;
421
case 'I': // Minimize button
422
if ((!m_button[MinButton]) && isMinimizable()) {
423
btn = createButton(MinButton);
425
btn->setTipText(i18n("Minimize"));
426
connect(btn, SIGNAL(clicked()), SLOT(minimize()));
428
// fix double deletion, see objDestroyed()
429
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
431
m_button[MinButton] = btn;
434
case 'A': // Maximize button
435
if ((!m_button[MaxButton]) && isMaximizable()) {
436
btn = createButton(MaxButton);
438
btn->setRealizeButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton);
439
const bool max = maximizeMode() == MaximizeFull;
440
btn->setTipText(max ? i18n("Restore") : i18n("Maximize"));
441
btn->setToggleButton(true);
443
connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
445
// fix double deletion, see objDestroyed()
446
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
448
m_button[MaxButton] = btn;
451
case 'X': // Close button
452
if ((!m_button[CloseButton]) && isCloseable()) {
453
btn = createButton(CloseButton);
455
btn->setTipText(i18n("Close"));
456
connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
458
// fix double deletion, see objDestroyed()
459
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
461
m_button[CloseButton] = btn;
464
case 'F': // AboveButton button
465
if (!m_button[AboveButton]) {
466
btn = createButton(AboveButton);
468
bool above = keepAbove();
469
btn->setTipText(above ? i18n("Do not keep above others") : i18n("Keep above others"));
470
btn->setToggleButton(true);
472
connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
474
// fix double deletion, see objDestroyed()
475
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
477
m_button[AboveButton] = btn;
480
case 'B': // BelowButton button
481
if (!m_button[BelowButton]) {
482
btn = createButton(BelowButton);
484
bool below = keepBelow();
485
btn->setTipText(below ? i18n("Do not keep below others") : i18n("Keep below others"));
486
btn->setToggleButton(true);
488
connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
490
// fix double deletion, see objDestroyed()
491
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
493
m_button[BelowButton] = btn;
496
case 'L': // Shade button
497
if ((!m_button[ShadeButton]) && isShadeable()) {
498
btn = createButton(ShadeButton);
500
bool shaded = isSetShade();
501
btn->setTipText(shaded ? i18n("Unshade") : i18n("Shade"));
502
btn->setToggleButton(true);
504
connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
506
// fix double deletion, see objDestroyed()
507
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
509
m_button[ShadeButton] = btn;
512
case '_': // Spacer item
513
btnContainer.append(0);
518
btn->setLeft(isLeft);
519
btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn), layoutMetric(LM_ButtonHeight, true, btn)));
521
btnContainer.append(btn);
528
void KCommonDecoration::calcHiddenButtons()
530
if (width() == btnHideLastWidth)
533
btnHideLastWidth = width();
535
//Hide buttons in the following order:
536
KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
537
m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
538
m_button[MinButton], m_button[MenuButton], m_button[CloseButton]
540
const int buttonsCount = sizeof(btnArray) / sizeof(btnArray[ 0 ]);
542
int current_width = width();
546
while (current_width < btnHideMinWidth && count < buttonsCount) {
547
if (btnArray[count]) {
548
current_width += btnArray[count]->width();
549
if (btnArray[count]->isVisible())
550
btnArray[count]->hide();
554
// Show the rest of the buttons...
555
for (int i = count; i < buttonsCount; i++) {
558
if (! btnArray[i]->isHidden())
559
break; // all buttons shown...
566
void KCommonDecoration::show()
568
if (decorationBehaviour(DB_ButtonHide))
573
void KCommonDecoration::resize(const QSize& s)
578
QSize KCommonDecoration::minimumSize() const
580
const int minWidth = qMax(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
581
+ qMax(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
582
+ layoutMetric(LM_TitleBorderLeft) + layoutMetric(LM_TitleBorderRight);
583
return QSize(minWidth,
584
layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_TitleHeight)
585
+ layoutMetric(LM_TitleEdgeBottom)
586
+ layoutMetric(LM_BorderBottom));
589
void KCommonDecoration::maximizeChange()
591
if (m_button[MaxButton]) {
592
m_button[MaxButton]->setOn(maximizeMode() == MaximizeFull);
593
m_button[MaxButton]->setTipText((maximizeMode() != MaximizeFull) ?
596
m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
602
void KCommonDecoration::desktopChange()
604
if (m_button[OnAllDesktopsButton]) {
605
m_button[OnAllDesktopsButton]->setOn(isOnAllDesktops());
606
m_button[OnAllDesktopsButton]->setTipText(isOnAllDesktops() ?
607
i18n("Not on all desktops")
608
: i18n("On all desktops"));
609
m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
613
void KCommonDecoration::shadeChange()
615
if (m_button[ShadeButton]) {
616
bool shaded = isSetShade();
617
m_button[ShadeButton]->setOn(shaded);
618
m_button[ShadeButton]->setTipText(shaded ?
621
m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
625
void KCommonDecoration::iconChange()
627
if (m_button[MenuButton]) {
628
m_button[MenuButton]->update();
629
m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
633
void KCommonDecoration::activeChange()
636
widget()->update(); // do something similar to updateCaption here
639
void KCommonDecoration::captionChange()
644
void KCommonDecoration::keepAboveChange(bool above)
646
if (m_button[AboveButton]) {
647
m_button[AboveButton]->setOn(above);
648
m_button[AboveButton]->setTipText(above ? i18n("Do not keep above others") : i18n("Keep above others"));
649
m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
652
if (m_button[BelowButton] && m_button[BelowButton]->isChecked()) {
653
m_button[BelowButton]->setOn(false);
654
m_button[BelowButton]->setTipText(i18n("Keep below others"));
655
m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
659
void KCommonDecoration::keepBelowChange(bool below)
661
if (m_button[BelowButton]) {
662
m_button[BelowButton]->setOn(below);
663
m_button[BelowButton]->setTipText(below ? i18n("Do not keep below others") : i18n("Keep below others"));
664
m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
667
if (m_button[AboveButton] && m_button[AboveButton]->isChecked()) {
668
m_button[AboveButton]->setOn(false);
669
m_button[AboveButton]->setTipText(i18n("Keep above others"));
670
m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
674
void KCommonDecoration::slotMaximize()
676
if (m_button[MaxButton]) {
677
maximize(m_button[MaxButton]->lastMousePress());
681
void KCommonDecoration::slotShade()
683
setShade(!isSetShade());
686
void KCommonDecoration::slotKeepAbove()
688
setKeepAbove(!keepAbove());
691
void KCommonDecoration::slotKeepBelow()
693
setKeepBelow(!keepBelow());
696
void KCommonDecoration::menuButtonPressed()
698
static QTime* t = NULL;
699
static KCommonDecoration* lastClient = NULL;
702
bool dbl = (lastClient == this && t->elapsed() <= QApplication::doubleClickInterval());
705
if (!dbl || !decorationBehaviour(DB_MenuClose)) {
706
QRect menuRect = m_button[MenuButton]->rect();
707
QPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
708
QPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight()) + QPoint(0, 2);
709
KDecorationFactory* f = factory();
710
showWindowMenu(QRect(menutop, menubottom));
711
if (!f->exists(decoration())) // 'this' was deleted
713
m_button[MenuButton]->setDown(false);
718
void KCommonDecoration::menuButtonReleased()
724
void KCommonDecoration::resizeEvent(QResizeEvent */*e*/)
726
if (decorationBehaviour(DB_ButtonHide))
732
// FIXME: don't update() here! this would result in two paintEvent()s
733
// because there is already "something" else triggering the repaint...
734
// widget()->update();
737
void KCommonDecoration::moveWidget(int x, int y, QWidget *widget) const
739
QPoint p = widget->pos();
743
if (x != oldX || y != oldY)
747
void KCommonDecoration::resizeWidget(int w, int h, QWidget *widget) const
749
QSize s = widget->size();
750
int oldW = s.width();
751
int oldH = s.height();
753
if (w != oldW || h != oldH)
754
widget->resize(w, h);
757
void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent *e)
759
if (e->button() != Qt::LeftButton)
762
int tb = layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_TitleHeight) +
763
layoutMetric(LM_TitleEdgeBottom) + layoutMetric(LM_OuterPaddingTop);
764
// when shaded, react on double clicks everywhere to make it easier to unshade. otherwise
765
// react only on double clicks in the title bar region...
766
if (isSetShade() || e->pos().y() <= tb)
767
titlebarDblClickOperation();
770
void KCommonDecoration::wheelEvent(QWheelEvent *e)
772
int tb = layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_TitleHeight) +
773
layoutMetric(LM_TitleEdgeBottom) + layoutMetric(LM_OuterPaddingTop);
774
if (isSetShade() || e->pos().y() <= tb)
775
titlebarMouseWheelOperation(e->delta());
778
KCommonDecoration::Position KCommonDecoration::mousePosition(const QPoint &point) const
780
const int corner = 18 + 3 * layoutMetric(LM_BorderBottom, false) / 2;
781
Position pos = PositionCenter;
783
const int paddingLeft = layoutMetric(LM_OuterPaddingLeft);
784
const int paddingTop = layoutMetric(LM_OuterPaddingTop);
785
const int paddingRight = layoutMetric(LM_OuterPaddingRight);
786
const int paddingBottom = layoutMetric(LM_OuterPaddingBottom);
788
QRect r = widget()->rect().adjusted(paddingLeft, paddingTop, -paddingRight, -paddingBottom);
789
int r_x, r_y, r_x2, r_y2;
790
r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
793
const int borderLeft = layoutMetric(LM_BorderLeft);
794
// const int borderRight = layoutMetric(LM_BorderRight);
795
const int borderBottom = layoutMetric(LM_BorderBottom);
796
const int titleHeight = layoutMetric(LM_TitleHeight);
797
const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
798
const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
799
const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
800
const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
802
const int borderBottomTop = r_y2 - borderBottom + 1;
803
const int borderLeftRight = r_x + borderLeft - 1;
804
// const int borderRightLeft = r_x2-borderRight+1;
805
const int titleEdgeLeftRight = r_x + titleEdgeLeft - 1;
806
const int titleEdgeRightLeft = r_x2 - titleEdgeRight + 1;
807
const int titleEdgeBottomBottom = r_y + titleEdgeTop + titleHeight + titleEdgeBottom - 1;
808
const int titleEdgeTopBottom = r_y + titleEdgeTop - 1;
810
if (p_y <= titleEdgeTopBottom) {
811
if (p_x <= r_x + corner)
812
pos = PositionTopLeft;
813
else if (p_x >= r_x2 - corner)
814
pos = PositionTopRight;
817
} else if (p_y <= titleEdgeBottomBottom) {
818
if (p_x <= titleEdgeLeftRight)
819
pos = PositionTopLeft;
820
else if (p_x >= titleEdgeRightLeft)
821
pos = PositionTopRight;
823
pos = PositionCenter; // title bar
824
} else if (p_y < borderBottomTop) {
825
if (p_y < r_y2 - corner) {
826
if (p_x <= borderLeftRight)
831
if (p_x <= borderLeftRight)
832
pos = PositionBottomLeft;
834
pos = PositionBottomRight;
836
} else if (p_y >= borderBottomTop) {
837
if (p_x <= r_x + corner)
838
pos = PositionBottomLeft;
839
else if (p_x >= r_x2 - corner)
840
pos = PositionBottomRight;
842
pos = PositionBottom;
848
void KCommonDecoration::updateWindowShape()
850
// don't mask the widget...
851
if (!decorationBehaviour(DB_WindowMask))
854
int w = widget()->width();
855
int h = widget()->height();
857
QRegion mask(0, 0, w, h);
859
// Remove corners (if subclass wants to.)
860
mask -= cornerShape(WC_TopLeft);
861
mask -= cornerShape(WC_TopRight);
862
mask -= cornerShape(WC_BottomLeft);
863
mask -= cornerShape(WC_BottomRight);
868
bool KCommonDecoration::eventFilter(QObject* o, QEvent* e)
874
resizeEvent(static_cast<QResizeEvent*>(e));
877
paintEvent(static_cast< QPaintEvent* >(e));
879
case QEvent::MouseButtonDblClick:
880
mouseDoubleClickEvent(static_cast< QMouseEvent* >(e));
882
case QEvent::MouseButtonPress:
883
processMousePressEvent(static_cast< QMouseEvent* >(e));
886
wheelEvent(static_cast< QWheelEvent* >(e));
893
const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
894
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
895
| NET::UtilityMask | NET::SplashMask;
897
bool KCommonDecoration::isToolWindow() const
899
NET::WindowType type = windowType(SUPPORTED_WINDOW_TYPES_MASK);
900
return ((type == NET::Toolbar) || (type == NET::Utility) || (type == NET::Menu));
903
QRect KCommonDecoration::titleRect() const
905
const int pl = layoutMetric(LM_OuterPaddingLeft);
906
const int pt = layoutMetric(LM_OuterPaddingTop);
907
const int pr = layoutMetric(LM_OuterPaddingRight);
908
const int pb = layoutMetric(LM_OuterPaddingBottom);
910
int r_x, r_y, r_x2, r_y2;
911
widget()->rect().adjusted(pl, pt, -pr, -pb).getCoords(&r_x, &r_y, &r_x2, &r_y2);
913
const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
914
const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
915
const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
916
const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
917
const int titleBorderLeft = layoutMetric(LM_TitleBorderLeft);
918
const int titleBorderRight = layoutMetric(LM_TitleBorderRight);
919
const int ttlHeight = layoutMetric(LM_TitleHeight);
920
const int titleEdgeBottomBottom = r_y + titleEdgeTop + ttlHeight + titleEdgeBottom - 1;
921
return QRect(r_x + titleEdgeLeft + buttonsLeftWidth() + titleBorderLeft, r_y + titleEdgeTop,
922
r_x2 - titleEdgeRight - buttonsRightWidth() - titleBorderRight - (r_x + titleEdgeLeft + buttonsLeftWidth() + titleBorderLeft),
923
titleEdgeBottomBottom - (r_y + titleEdgeTop));
926
QRect KCommonDecoration::transparentRect() const
928
return wrapper->transparentRect();
931
KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent)
932
: QAbstractButton(parent ? parent->widget() : 0),
933
m_decoration(parent),
935
m_realizeButtons(Qt::LeftButton),
936
m_lastMouse(Qt::NoButton),
939
setCursor(Qt::ArrowCursor);
942
KCommonDecorationButton::~KCommonDecorationButton()
946
KCommonDecoration *KCommonDecorationButton::decoration() const
951
ButtonType KCommonDecorationButton::type() const
956
bool KCommonDecorationButton::isLeft() const
961
void KCommonDecorationButton::setLeft(bool left)
966
void KCommonDecorationButton::setRealizeButtons(int btns)
968
m_realizeButtons = btns;
971
void KCommonDecorationButton::setSize(const QSize &s)
973
if (!m_size.isValid() || s != size()) {
976
setFixedSize(m_size);
981
QSize KCommonDecorationButton::sizeHint() const
986
void KCommonDecorationButton::setTipText(const QString &tip)
988
this->setToolTip(tip);
991
void KCommonDecorationButton::setToggleButton(bool toggle)
993
QAbstractButton::setCheckable(toggle);
997
void KCommonDecorationButton::setOn(bool on)
999
if (on != isChecked()) {
1000
QAbstractButton::setChecked(on);
1005
void KCommonDecorationButton::mousePressEvent(QMouseEvent* e)
1007
m_lastMouse = e->button();
1008
// pass on event after changing button to LeftButton
1009
QMouseEvent me(e->type(), e->pos(), (e->button()&m_realizeButtons) ? Qt::LeftButton : Qt::NoButton, e->buttons(), e->modifiers());
1011
QAbstractButton::mousePressEvent(&me);
1014
void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent* e)
1016
m_lastMouse = e->button();
1017
// pass on event after changing button to LeftButton
1018
QMouseEvent me(e->type(), e->pos(), (e->button()&m_realizeButtons) ? Qt::LeftButton : Qt::NoButton, e->buttons(), e->modifiers());
1020
QAbstractButton::mouseReleaseEvent(&me);
1025
// *** wrap everything from KDecoration *** //
1026
bool KCommonDecoration::drawbound(const QRect&, bool)
1030
bool KCommonDecoration::windowDocked(Position)
1034
const KDecorationOptions* KCommonDecoration::options()
1036
return KDecoration::options();
1038
bool KCommonDecoration::isActive() const
1040
return wrapper->isActive();
1042
bool KCommonDecoration::isCloseable() const
1044
return wrapper->isCloseable();
1046
bool KCommonDecoration::isMaximizable() const
1048
return wrapper->isMaximizable();
1050
KCommonDecoration::MaximizeMode KCommonDecoration::maximizeMode() const
1052
return wrapper->maximizeMode();
1054
bool KCommonDecoration::isMinimizable() const
1056
return wrapper->isMinimizable();
1058
bool KCommonDecoration::providesContextHelp() const
1060
return wrapper->providesContextHelp();
1062
int KCommonDecoration::desktop() const
1064
return wrapper->desktop();
1066
bool KCommonDecoration::isOnAllDesktops() const
1068
return wrapper->isOnAllDesktops();
1070
bool KCommonDecoration::isModal() const
1072
return wrapper->isModal();
1074
bool KCommonDecoration::isShadeable() const
1076
return wrapper->isShadeable();
1078
bool KCommonDecoration::isShade() const
1080
return wrapper->isShade();
1082
bool KCommonDecoration::isSetShade() const
1084
return wrapper->isSetShade();
1086
bool KCommonDecoration::keepAbove() const
1088
return wrapper->keepAbove();
1090
bool KCommonDecoration::keepBelow() const
1092
return wrapper->keepBelow();
1094
bool KCommonDecoration::isMovable() const
1096
return wrapper->isMovable();
1098
bool KCommonDecoration::isResizable() const
1100
return wrapper->isResizable();
1102
NET::WindowType KCommonDecoration::windowType(unsigned long supported_types) const
1104
return wrapper->windowType(supported_types);
1106
QIcon KCommonDecoration::icon() const
1108
return wrapper->icon();
1110
QString KCommonDecoration::caption() const
1112
return wrapper->caption();
1114
void KCommonDecoration::showWindowMenu(const QRect &pos)
1116
return wrapper->showWindowMenu(pos);
1118
void KCommonDecoration::showWindowMenu(QPoint pos)
1120
return wrapper->showWindowMenu(pos);
1122
void KCommonDecoration::performWindowOperation(WindowOperation op)
1124
return wrapper->performWindowOperation(op);
1126
void KCommonDecoration::setMask(const QRegion& reg, int mode)
1128
return wrapper->setMask(reg, mode);
1130
void KCommonDecoration::clearMask()
1132
return wrapper->clearMask();
1134
bool KCommonDecoration::isPreview() const
1136
return wrapper->isPreview();
1138
QRect KCommonDecoration::geometry() const
1140
return wrapper->geometry();
1142
QRect KCommonDecoration::iconGeometry() const
1144
return wrapper->iconGeometry();
1146
QRegion KCommonDecoration::unobscuredRegion(const QRegion& r) const
1148
return wrapper->unobscuredRegion(r);
1150
WId KCommonDecoration::windowId() const
1152
return wrapper->windowId();
1154
int KCommonDecoration::width() const
1156
return wrapper->width();
1158
int KCommonDecoration::height() const
1160
return wrapper->height();
1162
void KCommonDecoration::processMousePressEvent(QMouseEvent* e)
1164
return wrapper->processMousePressEvent(e);
1166
void KCommonDecoration::setMainWidget(QWidget* w)
1168
return wrapper->setMainWidget(w);
1170
void KCommonDecoration::createMainWidget(Qt::WFlags flags)
1172
return wrapper->createMainWidget(flags);
1174
QWidget* KCommonDecoration::initialParentWidget() const
1176
return wrapper->initialParentWidget();
1178
Qt::WFlags KCommonDecoration::initialWFlags() const
1180
return wrapper->initialWFlags();
1182
QWidget* KCommonDecoration::widget()
1184
return wrapper->widget();
1186
const QWidget* KCommonDecoration::widget() const
1188
return wrapper->widget();
1190
KDecorationFactory* KCommonDecoration::factory() const
1192
return wrapper->factory();
1194
void KCommonDecoration::grabXServer()
1196
return wrapper->grabXServer();
1198
void KCommonDecoration::ungrabXServer()
1200
return wrapper->ungrabXServer();
1202
void KCommonDecoration::closeWindow()
1204
return wrapper->closeWindow();
1206
void KCommonDecoration::maximize(Qt::MouseButtons button)
1208
return wrapper->maximize(button);
1210
void KCommonDecoration::maximize(MaximizeMode mode)
1212
return wrapper->maximize(mode);
1214
void KCommonDecoration::minimize()
1216
return wrapper->minimize();
1218
void KCommonDecoration::showContextHelp()
1220
return wrapper->showContextHelp();
1222
void KCommonDecoration::setDesktop(int desktop)
1224
return wrapper->setDesktop(desktop);
1226
void KCommonDecoration::toggleOnAllDesktops()
1228
return wrapper->toggleOnAllDesktops();
1230
void KCommonDecoration::titlebarDblClickOperation()
1232
return wrapper->titlebarDblClickOperation();
1234
void KCommonDecoration::titlebarMouseWheelOperation(int delta)
1236
return wrapper->titlebarMouseWheelOperation(delta);
1238
void KCommonDecoration::setShade(bool set)
1240
return wrapper->setShade(set);
1242
void KCommonDecoration::setKeepAbove(bool set)
1244
return wrapper->setKeepAbove(set);
1246
void KCommonDecoration::setKeepBelow(bool set)
1248
return wrapper->setKeepBelow(set);
1250
// *** end of wrapping of everything from KDecoration *** //
1252
const KDecoration* KCommonDecoration::decoration() const
1256
KDecoration* KCommonDecoration::decoration()
1262
KCommonDecorationUnstable::KCommonDecorationUnstable(KDecorationBridge* bridge, KDecorationFactory* factory)
1263
: KCommonDecoration(bridge, factory)
1265
Q_ASSERT(dynamic_cast<const KDecorationUnstable*>(decoration()));
1268
KCommonDecorationUnstable::~KCommonDecorationUnstable()
1272
// All copied from kdecoration.cpp
1273
bool KCommonDecorationUnstable::compositingActive() const
1275
return static_cast<const KDecorationUnstable*>(decoration())->compositingActive();
1280
bool KCommonDecorationUnstable::isClientGroupActive()
1282
return static_cast<KDecorationUnstable*>(decoration())->isClientGroupActive();
1285
QList< ClientGroupItem > KCommonDecorationUnstable::clientGroupItems() const
1287
return static_cast<const KDecorationUnstable*>(decoration())->clientGroupItems();
1290
long KCommonDecorationUnstable::itemId(int index)
1292
return static_cast<KDecorationUnstable*>(decoration())->itemId(index);
1295
int KCommonDecorationUnstable::visibleClientGroupItem()
1297
return static_cast<KDecorationUnstable*>(decoration())->visibleClientGroupItem();
1300
void KCommonDecorationUnstable::setVisibleClientGroupItem(int index)
1302
static_cast<KDecorationUnstable*>(decoration())->setVisibleClientGroupItem(index);
1305
void KCommonDecorationUnstable::moveItemInClientGroup(int index, int before)
1307
static_cast<KDecorationUnstable*>(decoration())->moveItemInClientGroup(index, before);
1310
void KCommonDecorationUnstable::moveItemToClientGroup(long itemId, int before)
1312
static_cast<KDecorationUnstable*>(decoration())->moveItemToClientGroup(itemId, before);
1315
void KCommonDecorationUnstable::removeFromClientGroup(int index, const QRect& newGeom)
1317
static_cast<KDecorationUnstable*>(decoration())->removeFromClientGroup(index, newGeom);
1320
void KCommonDecorationUnstable::closeClientGroupItem(int index)
1322
static_cast<KDecorationUnstable*>(decoration())->closeClientGroupItem(index);
1325
void KCommonDecorationUnstable::closeAllInClientGroup()
1327
static_cast<KDecorationUnstable*>(decoration())->closeAllInClientGroup();
1330
void KCommonDecorationUnstable::displayClientMenu(int index, const QPoint& pos)
1332
static_cast<KDecorationUnstable*>(decoration())->displayClientMenu(index, pos);
1335
KDecoration::WindowOperation KCommonDecorationUnstable::buttonToWindowOperation(Qt::MouseButtons button)
1337
return static_cast<KDecorationUnstable*>(decoration())->buttonToWindowOperation(button);
1340
bool KCommonDecorationUnstable::eventFilter(QObject* o, QEvent* e)
1342
return KCommonDecoration::eventFilter(o, e);
1345
// kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;