29 #include <QtCore/QObject>
30 #include <QtCore/QTimer>
31 #include <QtGui/QActionEvent>
32 #include <QtGui/QDesktopWidget>
33 #include <QtGui/QMenuItem>
34 #include <QtGui/QPainter>
35 #include <QtGui/QStyle>
36 #include <QtGui/QStyleOptionMenuItem>
48 #include <qx11info_x11.h>
51 #include <X11/Xutil.h>
52 #include <X11/Xatom.h>
70 class KMenuBar::KMenuBarPrivate
74 : forcedTopLevel(
false ),
92 bool fallback_mode : 1;
94 bool forcedTopLevel : 1;
101 QTimer selection_timer;
103 static Atom makeSelectionAtom();
114 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( QX11Info::display()));
115 char nm2[] =
"_KDE_TOPMENU_MINSIZE";
116 char* names[ 2 ] = { nm, nm2 };
118 XInternAtoms( QX11Info::display(), names, 2, False, atoms );
124 Atom KMenuBar::KMenuBarPrivate::makeSelectionAtom()
136 :
QMenuBar(parent), d(new KMenuBarPrivate)
138 connect( &d->selection_timer, SIGNAL(
timeout()),
139 this, SLOT(selectionTimeout()));
141 connect( qApp->desktop(), SIGNAL(resized(
int)), SLOT(updateFallbackSize()));
157 d->forcedTopLevel = top_level;
158 setTopLevelMenuInternal( top_level );
161 void KMenuBar::setTopLevelMenuInternal(
bool top_level)
163 if (d->forcedTopLevel)
166 d->wasTopLevel = top_level;
168 && parentWidget()->topLevelWidget()->isFullScreen())
173 d->topLevel = top_level;
178 DefaultScreen( QX11Info::display()));
179 connect( d->selection, SIGNAL(newOwner(Window)),
180 this, SLOT(updateFallbackSize()));
181 connect( d->selection, SIGNAL(lostOwner()),
182 this, SLOT(updateFallbackSize()));
187 d->fallback_mode =
false;
188 bool wasShown = !isHidden();
189 setParent(parentWidget(), Qt::Window | Qt::Tool | Qt::FramelessWindowHint);
199 updateFallbackSize();
200 d->min_size =
QSize( 0, 0 );
201 if( parentWidget() && !parentWidget()->isTopLevel())
202 setVisible( parentWidget()->isVisible());
211 setAttribute(Qt::WA_NoSystemBackground,
false);
212 setBackgroundRole(QPalette::Button);
216 setMinimumSize( 0, 0 );
217 setMaximumSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
219 if ( parentWidget() )
220 setParent( parentWidget() );
233 setTopLevelMenuInternal( cg.
readEntry(
"macStyle",
false ) );
240 if ( parentWidget() && obj == parentWidget()->topLevelWidget() )
242 if( ev->type() == QEvent::Resize )
245 if ( ev->type() == QEvent::Accel || ev->type() == QEvent::AccelAvailable )
247 if ( QApplication::sendEvent( topLevelWidget(), ev ) )
257 if( parentWidget() && obj == parentWidget() && ev->type() == QEvent::ParentChange )
260 setVisible( parentWidget()->isTopLevel() || parentWidget()->isVisible());
262 if( parentWidget() && !parentWidget()->isTopLevel() && obj == parentWidget())
264 if( ev->type() == QEvent::Show )
269 if( ev->type() == QEvent::Hide )
275 if( parentWidget() && obj == parentWidget()->topLevelWidget())
277 if( ev->type() == QEvent::WindowStateChange
278 && !parentWidget()->topLevelWidget()->isFullScreen() )
279 setTopLevelMenuInternal( d->wasTopLevel );
286 void KMenuBar::updateFallbackSize()
291 if( d->selection->owner() !=
None )
295 d->selection_timer.stop();
296 if( d->fallback_mode )
298 d->fallback_mode =
false;
300 setMinimumSize( 0, 0 );
301 setMaximumSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
306 if( d->selection_timer.isActive())
308 d->selection_timer.setInterval(100);
309 d->selection_timer.setSingleShot(
true);
310 d->selection_timer.start();
313 void KMenuBar::selectionTimeout()
317 d->fallback_mode =
true;
319 int screen = xineramaConfig.readEntry(
"MenubarScreen",
320 QApplication::desktop()->screenNumber(
QPoint(0,0)) );
321 QRect area = QApplication::desktop()->screenGeometry(screen);
323 move(area.left() - margin, area.top() - margin);
324 setFixedSize(area.width() + 2* margin , heightForWidth( area.width() + 2 * margin ) );
326 int strut_height = height() - margin;
327 if( strut_height < 0 )
336 if( e->spontaneous() && d->topLevel && !d->fallback_mode )
348 setGeometry( r.x(), r.y(), r.width(), r.height() );
359 if( geometry() !=
QRect( x, y, w, h ))
368 if( size() !=
QSize( w, h ))
378 void KMenuBar::checkSize(
int& w,
int& h )
380 if( !d->topLevel || d->fallback_mode )
388 w = qMax( w, d->min_size.width());
389 h = qMax( h, d->min_size.height());
401 int h = heightForWidth( 1000000 );
404 while( heightForWidth( w + 12 ) > h )
406 while( heightForWidth( w + 4 ) > h )
408 while( heightForWidth( w ) > h )
411 return QSize( w, h );
417 if( ev->type == ClientMessage && ev->xclient.message_type ==
msg_type_atom
418 && ev->xclient.window == winId())
424 d->min_size =
QSize( ev->xclient.data.l[ 1 ], ev->xclient.data.l[ 2 ] );
433 void KMenuBar::updateMenuBarSize()
442 d->frameStyle = style;
450 d->lineWidth = width;
492 bool up_enabled = isUpdatesEnabled();
493 Qt::BackgroundMode bg_mode = backgroundMode();
494 BackgroundOrigin bg_origin = backgroundOrigin();
496 setUpdatesEnabled(
false);
497 setBackgroundMode(Qt::X11ParentRelative);
498 setBackgroundOrigin(WindowOrigin);
500 p.eraseRect( rect() );
503 QColorGroup g = colorGroup();
506 for (
int i=0; i<(int)count(); i++ )
508 QMenuItem *mi = findItem( idAt( i ) );
510 if ( !mi->text().isEmpty() || !mi->icon().isNull() )
512 QRect r = itemRect(i);
513 if(r.isEmpty() || !mi->isVisible())
516 e = mi->isEnabled() && mi->isVisible();
518 g = isEnabled() ? ( isActiveWindow() ? palette().active() :
519 palette().inactive() ) : palette().disabled();
521 g = palette().disabled();
523 bool item_active = ( activeAction() == mi );
529 QStyleOptionMenuItem miOpt;
532 miOpt.text = mi->text();
533 miOpt.icon = mi->icon();
536 QStyle::State flags = QStyle::State_None;
537 if (isEnabled() && e)
538 flags |= QStyle::State_Enabled;
540 flags |= QStyle::State_Active;
541 if ( item_active && actItemDown )
542 flags |= QStyle::State_Down;
543 flags |= QStyle::State_HasFocus;
548 style()->drawControl(QStyle::CE_MenuBarItem, &miOpt, &p,
this);
552 style()->drawItem(p, r, Qt::AlignCenter | Qt::AlignVCenter | Qt::TextShowMnemonic,
553 g, e, mi->pixmap(), mi->text());
558 setBackgroundOrigin(bg_origin);
559 setBackgroundMode(bg_mode);
560 setUpdatesEnabled(up_enabled);
565 #include "kmenubar.moc"