25 #include <tqapplication.h>
27 #include <tqdatetime.h>
29 #include <tqtooltip.h>
34 #include <tdeapplication.h>
35 #include <kdecorationfactory.h>
36 #include <tdelocale.h>
39 #include <X11/Xatom.h>
41 #include "kcommondecoration.h"
42 #include "kcommondecoration.moc"
44 KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
55 KCommonDecoration::~KCommonDecoration()
57 for (
int n=0; n<NumButtons; n++) {
58 if (m_button[n])
delete m_button[n];
60 delete m_previewWidget;
86 case LM_TitleEdgeBottom:
87 case LM_TitleEdgeLeft:
88 case LM_TitleEdgeRight:
89 case LM_TitleBorderLeft:
90 case LM_TitleBorderRight:
99 case LM_ButtonSpacing:
102 case LM_ButtonMarginTop:
103 case LM_RightButtonsMarginTop:
106 case LM_ExplicitButtonSpacer:
119 widget()->setBackgroundMode(NoBackground);
121 widget()->installEventFilter(
this );
125 connect(
this, TQT_SIGNAL(
keepAboveChanged(
bool) ), TQT_SLOT(keepAboveChange(
bool) ) );
126 connect(
this, TQT_SIGNAL(
keepBelowChanged(
bool) ), TQT_SLOT(keepBelowChange(
bool) ) );
164 TQRect r =
widget()->rect();
165 int r_x, r_y, r_x2, r_y2;
166 r.coords(&r_x, &r_y, &r_x2, &r_y2);
169 if (m_previewWidget) {
175 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
177 int left = r_x+borderLeft;
178 int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
179 int width = r_x2-borderRight-left+1;
180 int height = r_y2-borderBottom-top+1;
181 m_previewWidget->setGeometry(left, top, width, height);
182 moveWidget(left,top, m_previewWidget);
183 resizeWidget(width, height, m_previewWidget);
187 for (
int n=0; n<NumButtons; n++) {
189 TQSize newSize = TQSize(
layoutMetric(LM_ButtonWidth,
true, m_button[n]),
191 if (newSize != m_button[n]->size() )
198 if (m_buttonsLeft.count() > 0) {
199 const int buttonSpacing =
layoutMetric(LM_ButtonSpacing);
201 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
202 bool elementLayouted =
false;
204 if (!(*it)->isHidden() ) {
205 moveWidget(x,y, *it);
206 x +=
layoutMetric(LM_ButtonWidth,
true, ::tqqt_cast<KCommonDecorationButton*>(*it) );
207 elementLayouted =
true;
211 elementLayouted =
true;
213 if (elementLayouted && it != m_buttonsLeft.end() )
218 if (m_buttonsRight.count() > 0) {
220 const int titleEdgeRightLeft = r_x2-
layoutMetric(LM_TitleEdgeRight)+1;
222 const int buttonSpacing =
layoutMetric(LM_ButtonSpacing);
223 int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
224 for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
225 bool elementLayouted =
false;
227 if (!(*it)->isHidden() ) {
228 moveWidget(x,y, *it);
229 x +=
layoutMetric(LM_ButtonWidth,
true, ::tqqt_cast<KCommonDecorationButton*>(*it) );;
230 elementLayouted =
true;
234 elementLayouted =
true;
236 if (elementLayouted && it != m_buttonsRight.end() )
244 for (
int n=0; n<NumButtons; n++)
245 if (m_button[n]) m_button[n]->update();
250 for (
int n=0; n<NumButtons; n++)
254 void KCommonDecoration::resetLayout()
256 for (
int n=0; n<NumButtons; n++) {
262 m_buttonsLeft.clear();
263 m_buttonsRight.clear();
265 delete m_previewWidget;
270 m_previewWidget =
new TQLabel(i18n(
"%1 is the name of window decoration style",
"<center><b>%1 preview</b></center>").arg(
visibleName() ),
widget());
271 m_previewWidget->show();
274 addButtons(m_buttonsLeft,
277 addButtons(m_buttonsRight,
283 const int minTitleBarWidth = 35;
284 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,
true) + buttonContainerWidth(m_buttonsRight,
true) +
288 btnHideLastWidth = 0;
291 int KCommonDecoration::buttonsLeftWidth()
const
293 return buttonContainerWidth(m_buttonsLeft);
296 int KCommonDecoration::buttonsRightWidth()
const
298 return buttonContainerWidth(m_buttonsRight);
301 int KCommonDecoration::buttonContainerWidth(
const ButtonContainer &btnContainer,
bool countHidden)
const
303 int explicitSpacer =
layoutMetric(LM_ExplicitButtonSpacer);
305 int shownElementsCount = 0;
308 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
310 if (countHidden || !(*it)->isHidden() ) {
312 ++shownElementsCount;
316 ++shownElementsCount;
319 w +=
layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
324 bool KCommonDecoration::isModalSystemNotification()
326 unsigned char *data = 0;
329 unsigned long n, left;
330 Atom kde_wm_system_modal_notification;
331 kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(),
"_TDE_WM_MODAL_SYS_NOTIFICATION", False);
332 result = XGetWindowProperty(tqt_xdisplay(),
windowId(), kde_wm_system_modal_notification, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data);
333 if (result == Success && data != None && format == 32 )
340 void KCommonDecoration::addButtons(ButtonContainer &btnContainer,
const TQString& s,
bool isLeft)
342 if (s.length() > 0) {
343 for (
unsigned n=0; n < s.length(); n++) {
347 if (!isModalSystemNotification()) {
348 if (!m_button[MenuButton]){
353 connect(btn, TQT_SIGNAL(pressed()), TQT_SLOT(menuButtonPressed()));
354 connect(btn, TQT_SIGNAL(released()),
this, TQT_SLOT(menuButtonReleased()));
356 m_button[MenuButton] = btn;
361 if (!isModalSystemNotification()) {
362 if (!m_button[OnAllDesktopsButton]){
366 btn->
setTipText(oad?i18n(
"Not on all desktops"):i18n(
"On all desktops") );
367 btn->setToggleButton(
true);
371 m_button[OnAllDesktopsButton] = btn;
382 m_button[HelpButton] = btn;
390 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(
minimize()));
392 m_button[MinButton] = btn;
401 btn->
setTipText(max?i18n(
"Restore"):i18n(
"Maximize") );
402 btn->setToggleButton(
true);
404 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(slotMaximize()));
406 m_button[MaxButton] = btn;
414 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(
closeWindow()));
416 m_button[CloseButton] = btn;
420 if (!m_button[AboveButton]){
424 btn->
setTipText(above?i18n(
"Do not keep above others"):i18n(
"Keep above others") );
425 btn->setToggleButton(
true);
427 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(slotKeepAbove()));
429 m_button[AboveButton] = btn;
433 if (!m_button[BelowButton]){
437 btn->
setTipText(below?i18n(
"Do not keep below others"):i18n(
"Keep below others") );
438 btn->setToggleButton(
true);
440 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(slotKeepBelow()));
442 m_button[BelowButton] = btn;
450 btn->
setTipText(shaded?i18n(
"Unshade"):i18n(
"Shade") );
451 btn->setToggleButton(
true);
452 btn->setOn( shaded );
453 connect(btn, TQT_SIGNAL(clicked()), TQT_SLOT(slotShade()));
455 m_button[ShadeButton] = btn;
459 btnContainer.append(0);
464 btn->setLeft(isLeft);
467 btnContainer.append(btn);
474 void KCommonDecoration::calcHiddenButtons()
476 if (
width() == btnHideLastWidth)
479 btnHideLastWidth =
width();
483 m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
484 m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
485 const int buttonsCount =
sizeof( btnArray ) /
sizeof( btnArray[ 0 ] );
487 int current_width =
width();
491 while (current_width < btnHideMinWidth && count < buttonsCount)
493 if (btnArray[count] ) {
494 current_width += btnArray[count]->width();
495 if (btnArray[count]->isVisible() )
496 btnArray[count]->hide();
501 for(
int i = count; i < buttonsCount; i++)
505 if (! btnArray[i]->isHidden() )
513 void KCommonDecoration::show()
530 return TQSize(minWidth,
538 if( m_button[MaxButton] ) {
551 if ( m_button[OnAllDesktopsButton] ) {
554 i18n(
"Not on all desktops")
555 : i18n(
"On all desktops"));
562 if ( m_button[ShadeButton] ) {
564 m_button[ShadeButton]->setOn( shaded );
574 if (m_button[MenuButton])
576 m_button[MenuButton]->update();
592 void KCommonDecoration::keepAboveChange(
bool above)
594 if (m_button[AboveButton])
596 m_button[AboveButton]->setOn(above);
597 m_button[AboveButton]->
setTipText( above?i18n(
"Do not keep above others"):i18n(
"Keep above others") );
601 if (m_button[BelowButton] && m_button[BelowButton]->isOn())
603 m_button[BelowButton]->setOn(
false);
604 m_button[BelowButton]->
setTipText( i18n(
"Keep below others") );
609 void KCommonDecoration::keepBelowChange(
bool below)
611 if (m_button[BelowButton])
613 m_button[BelowButton]->setOn(below);
614 m_button[BelowButton]->
setTipText( below?i18n(
"Do not keep below others"):i18n(
"Keep below others") );
618 if (m_button[AboveButton] && m_button[AboveButton]->isOn())
620 m_button[AboveButton]->setOn(
false);
621 m_button[AboveButton]->
setTipText( i18n(
"Keep above others") );
626 void KCommonDecoration::slotMaximize()
628 if (m_button[MaxButton])
630 maximize(m_button[MaxButton]->lastMousePress() );
634 void KCommonDecoration::slotShade()
639 void KCommonDecoration::slotKeepAbove()
644 void KCommonDecoration::slotKeepBelow()
649 void KCommonDecoration::menuButtonPressed()
651 static TQTime* t = NULL;
655 bool dbl = (lastClient==
this && t->elapsed() <= TQApplication::doubleClickInterval());
659 TQRect menuRect = m_button[MenuButton]->rect();
660 TQPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
661 TQPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+TQPoint(0,2);
662 KDecorationFactory* f =
factory();
664 if( !f->exists(
this ))
666 m_button[MenuButton]->setDown(
false);
672 void KCommonDecoration::menuButtonReleased()
678 void KCommonDecoration::resizeEvent(TQResizeEvent *)
691 void KCommonDecoration::moveWidget(
int x,
int y, TQWidget *widget)
const
693 TQPoint p = widget->pos();
697 if (x!=oldX || y!=oldY)
701 void KCommonDecoration::resizeWidget(
int w,
int h, TQWidget *widget)
const
703 TQSize s = widget->size();
704 int oldW = s.width();
705 int oldH = s.height();
707 if (w!=oldW || h!=oldH)
711 void KCommonDecoration::mouseDoubleClickEvent(TQMouseEvent *e)
713 if( e->button() != Qt::LeftButton )
723 void KCommonDecoration::wheelEvent(TQWheelEvent *e)
732 const int corner = 18+3*
layoutMetric(LM_BorderBottom,
false)/2;
735 TQRect r =
widget()->rect();
736 int r_x, r_y, r_x2, r_y2;
737 r.coords(&r_x, &r_y, &r_x2, &r_y2);
745 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
746 const int titleEdgeLeft =
layoutMetric(LM_TitleEdgeLeft);
747 const int titleEdgeRight =
layoutMetric(LM_TitleEdgeRight);
749 const int borderBottomTop = r_y2-borderBottom+1;
750 const int borderLeftRight = r_x+borderLeft-1;
752 const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
753 const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
754 const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
755 const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
757 if (p_y <= titleEdgeTopBottom) {
758 if (p_x <= r_x+corner)
759 pos = PositionTopLeft;
760 else if (p_x >= r_x2-corner)
761 pos = PositionTopRight;
764 }
else if (p_y <= titleEdgeBottomBottom) {
765 if (p_x <= titleEdgeLeftRight)
766 pos = PositionTopLeft;
767 else if (p_x >= titleEdgeRightLeft)
768 pos = PositionTopRight;
770 pos = PositionCenter;
771 }
else if (p_y < borderBottomTop) {
772 if (p_y < r_y2-corner) {
773 if (p_x <= borderLeftRight)
778 if (p_x <= borderLeftRight)
779 pos = PositionBottomLeft;
781 pos = PositionBottomRight;
783 }
else if(p_y >= borderBottomTop) {
784 if (p_x <= r_x+corner)
785 pos = PositionBottomLeft;
786 else if (p_x >= r_x2-corner)
787 pos = PositionBottomRight;
789 pos = PositionBottom;
801 int w =
widget()->width();
802 int h =
widget()->height();
804 bool tl=
true,tr=
true,bl=
true,br=
true;
808 for(
int screen=0; screen < desktop->numScreens(); ++screen)
810 TQRect fullscreen(desktop->screenGeometry(screen));
813 if(window.topLeft() == fullscreen.topLeft() ) tl =
false;
814 if(window.topRight() == fullscreen.topRight() ) tr =
false;
815 if(window.bottomLeft() == fullscreen.bottomLeft() ) bl =
false;
816 if(window.bottomRight()== fullscreen.bottomRight() ) br =
false;
819 TQRegion mask(0, 0, w, h);
845 bool KCommonDecoration::eventFilter( TQObject* o, TQEvent* e )
847 if( TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(
widget()))
851 case TQEvent::Resize:
852 resizeEvent(TQT_TQRESIZEEVENT(e) );
857 case TQEvent::MouseButtonDblClick:
858 mouseDoubleClickEvent(TQT_TQMOUSEEVENT( e ));
860 case TQEvent::MouseButtonPress:
864 wheelEvent(TQT_TQWHEELEVENT( e ));
871 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
872 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::TopMenuMask
873 | NET::UtilityMask | NET::SplashMask;
877 NET::WindowType type =
windowType( SUPPORTED_WINDOW_TYPES_MASK );
878 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
883 int r_x, r_y, r_x2, r_y2;
884 TQT_TQRECT_OBJECT(
widget()->rect()).coords(&r_x, &r_y, &r_x2, &r_y2);
885 const int titleEdgeLeft =
layoutMetric(LM_TitleEdgeLeft);
887 const int titleEdgeRight =
layoutMetric(LM_TitleEdgeRight);
888 const int titleEdgeBottom =
layoutMetric(LM_TitleEdgeBottom);
889 const int titleBorderLeft =
layoutMetric(LM_TitleBorderLeft);
890 const int titleBorderRight =
layoutMetric(LM_TitleBorderRight);
892 const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
893 return TQRect(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft, r_y+titleEdgeTop,
894 r_x2-titleEdgeRight-buttonsRightWidth()-titleBorderRight-(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft),
895 titleEdgeBottomBottom-(r_y+titleEdgeTop) );
899 KCommonDecorationButton::KCommonDecorationButton(ButtonType type,
KCommonDecoration *parent,
const char *name)
900 : TQButton(parent->widget(), name),
901 m_decoration(parent),
903 m_realizeButtons(Qt::LeftButton),
904 m_lastMouse(Qt::NoButton),
907 setCursor(ArrowCursor);
910 KCommonDecorationButton::~KCommonDecorationButton()
929 void KCommonDecorationButton::setLeft(
bool left)
936 m_realizeButtons = btns;
941 if (!m_size.isValid() || s != size() ) {
944 setFixedSize(m_size);
949 TQSize KCommonDecorationButton::sizeHint()
const
955 TQToolTip::remove(
this );
956 TQToolTip::add(
this, tip );
959 void KCommonDecorationButton::setToggleButton(
bool toggle)
961 TQButton::setToggleButton(toggle);
965 void KCommonDecorationButton::setOn(
bool on)
973 void KCommonDecorationButton::mousePressEvent(TQMouseEvent* e)
975 m_lastMouse = e->button();
977 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
978 (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
980 TQButton::mousePressEvent(&me);
983 void KCommonDecorationButton::mouseReleaseEvent(TQMouseEvent* e)
985 m_lastMouse = e->button();
987 TQMouseEvent me(e->type(), e->pos(), e->globalPos(),
988 (e->button()&m_realizeButtons)?Qt::LeftButton:Qt::NoButton, e->state());
990 TQButton::mouseReleaseEvent(&me);