diff options
Diffstat (limited to 'kcontrol/randr/krandrpassivepopup.cpp')
-rw-r--r-- | kcontrol/randr/krandrpassivepopup.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/kcontrol/randr/krandrpassivepopup.cpp b/kcontrol/randr/krandrpassivepopup.cpp new file mode 100644 index 000000000..858014014 --- /dev/null +++ b/kcontrol/randr/krandrpassivepopup.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krandrpassivepopup.h" + +#include <kapplication.h> + +// this class is just like KPassivePopup, but it keeps track of the widget +// it's supposed to be positioned next to, and adjust its position if that +// widgets moves (needed because after a resolution switch Kicker will +// reposition itself, causing normal KPassivePopup to stay at weird places) + +KRandrPassivePopup::KRandrPassivePopup( QWidget *parent, const char *name, WFlags f ) + : KPassivePopup( parent, name, f ) + { + connect( &update_timer, SIGNAL( timeout()), SLOT( slotPositionSelf())); + } + +KRandrPassivePopup* KRandrPassivePopup::message( const QString &caption, const QString &text, + const QPixmap &icon, QWidget *parent, const char *name, int timeout ) + { + KRandrPassivePopup *pop = new KRandrPassivePopup( parent, name ); + pop->setAutoDelete( true ); + pop->setView( caption, text, icon ); + pop->setTimeout( timeout ); + pop->show(); + pop->startWatchingWidget( parent ); + return pop; + } + +void KRandrPassivePopup::startWatchingWidget( QWidget* widget_P ) + { + static Atom wm_state = XInternAtom( qt_xdisplay() , "WM_STATE", False ); + Window win = widget_P->winId(); + bool x11_events = false; + for(;;) + { + Window root, parent; + Window* children; + unsigned int nchildren; + XQueryTree( qt_xdisplay(), win, &root, &parent, &children, &nchildren ); + if( children != NULL ) + XFree( children ); + if( win == root ) // huh? + break; + win = parent; + + QWidget* widget = QWidget::find( win ); + if( widget != NULL ) + { + widget->installEventFilter( this ); + watched_widgets.append( widget ); + } + else + { + XWindowAttributes attrs; + XGetWindowAttributes( qt_xdisplay(), win, &attrs ); + XSelectInput( qt_xdisplay(), win, attrs.your_event_mask | StructureNotifyMask ); + watched_windows.append( win ); + x11_events = true; + } + Atom type; + int format; + unsigned long nitems, after; + unsigned char* data; + if( XGetWindowProperty( qt_xdisplay(), win, wm_state, 0, 0, False, AnyPropertyType, + &type, &format, &nitems, &after, &data ) == Success ) + { + if( data != NULL ) + XFree( data ); + if( type != None ) // toplevel window + break; + } + } + if( x11_events ) + kapp->installX11EventFilter( this ); + } + +bool KRandrPassivePopup::eventFilter( QObject* o, QEvent* e ) + { + if( e->type() == QEvent::Move && o->isWidgetType() + && watched_widgets.contains( static_cast< QWidget* >( o ))) + QTimer::singleShot( 0, this, SLOT( slotPositionSelf())); + return false; + } + +bool KRandrPassivePopup::x11Event( XEvent* e ) + { + if( e->type == ConfigureNotify && watched_windows.contains( e->xconfigure.window )) + { + if( !update_timer.isActive()) + update_timer.start( 10, true ); + return false; + } + return KPassivePopup::x11Event( e ); + } + +void KRandrPassivePopup::slotPositionSelf() + { + positionSelf(); + } + +#include "krandrpassivepopup.moc" |