2009-09-13 16:43:26 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2009-09-15 07:12:54 +00:00
|
|
|
// oxygendetectwidget.cpp
|
2009-09-13 16:43:26 +00:00
|
|
|
// Note: this class is a stripped down version of
|
|
|
|
// /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.cpp
|
|
|
|
// Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
|
|
|
|
// -------------------
|
|
|
|
//
|
|
|
|
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files (the "Software"), to
|
|
|
|
// deal in the Software without restriction, including without limitation the
|
|
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
// IN THE SOFTWARE.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2009-09-16 06:09:31 +00:00
|
|
|
#include "oxygendetectwidget.h"
|
|
|
|
#include "oxygendetectwidget.moc"
|
|
|
|
|
2009-09-13 16:43:26 +00:00
|
|
|
#include <cassert>
|
2009-09-20 07:42:03 +00:00
|
|
|
#include <QtGui/QButtonGroup>
|
|
|
|
#include <QtGui/QLayout>
|
|
|
|
#include <QtGui/QGroupBox>
|
|
|
|
#include <QtGui/QMouseEvent>
|
2009-09-13 16:43:26 +00:00
|
|
|
#include <KLocale>
|
|
|
|
|
2009-09-20 07:42:03 +00:00
|
|
|
#include <QtGui/QX11Info>
|
2009-09-13 16:43:26 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <fixx11h.h>
|
|
|
|
|
2009-09-15 07:12:54 +00:00
|
|
|
namespace Oxygen
|
2009-09-13 16:43:26 +00:00
|
|
|
{
|
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
DetectDialog::DetectDialog( QWidget* parent ):
|
|
|
|
KDialog( parent ),
|
|
|
|
grabber( 0 )
|
|
|
|
{
|
2009-10-29 02:55:41 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// define buttons
|
|
|
|
setButtons( Ok|Cancel );
|
|
|
|
showButtonSeparator( false );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
QWidget* local( new QWidget( this ) );
|
|
|
|
ui.setupUi( local );
|
|
|
|
ui.windowClassCheckBox->setChecked( true );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// central widget
|
|
|
|
setMainWidget( local );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
void DetectDialog::detect( WId window )
|
2009-09-13 16:43:26 +00:00
|
|
|
{
|
2010-05-02 18:34:08 +00:00
|
|
|
if( window == 0 ) selectWindow();
|
|
|
|
else readWindow( window );
|
2009-09-13 16:43:26 +00:00
|
|
|
}
|
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
void DetectDialog::readWindow( WId window )
|
2009-09-13 16:43:26 +00:00
|
|
|
{
|
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
if( window == 0 )
|
|
|
|
{
|
|
|
|
emit detectionDone( false );
|
|
|
|
return;
|
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
info = KWindowSystem::windowInfo( window, -1U, -1U );
|
|
|
|
if( !info.valid())
|
|
|
|
{
|
|
|
|
emit detectionDone( false );
|
|
|
|
return;
|
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
QString wmclass_class = info.windowClassClass();
|
|
|
|
QString wmclass_name = info.windowClassName();
|
|
|
|
QString title = info.name();
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
ui.windowClass->setText( wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ')' );
|
|
|
|
ui.windowTitle->setText( title );
|
|
|
|
emit detectionDone( exec() == KDialog::Accepted );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
return;
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
void DetectDialog::selectWindow()
|
|
|
|
{
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// use a dialog, so that all user input is blocked
|
|
|
|
// use WX11BypassWM and moving away so that it's not actually visible
|
|
|
|
// grab only mouse, so that keyboard can be used e.g. for switching windows
|
|
|
|
grabber = new KDialog( 0, Qt::X11BypassWindowManagerHint );
|
|
|
|
grabber->move( -1000, -1000 );
|
|
|
|
grabber->setModal( true );
|
|
|
|
grabber->show();
|
|
|
|
grabber->grabMouse( Qt::CrossCursor );
|
|
|
|
grabber->installEventFilter( this );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
bool DetectDialog::eventFilter( QObject* o, QEvent* e )
|
|
|
|
{
|
|
|
|
// check object and event type
|
|
|
|
if( o != grabber ) return false;
|
|
|
|
if( e->type() != QEvent::MouseButtonRelease ) return false;
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// delete old grabber
|
|
|
|
delete grabber;
|
|
|
|
grabber = 0;
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// check button
|
|
|
|
if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton ) return true;
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
// read window information
|
|
|
|
readWindow( findWindow() );
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
return true;
|
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
WId DetectDialog::findWindow()
|
2009-09-13 16:43:26 +00:00
|
|
|
{
|
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
Window root;
|
|
|
|
Window child;
|
|
|
|
uint mask;
|
|
|
|
int rootX, rootY, x, y;
|
|
|
|
Window parent = QX11Info::appRootWindow();
|
|
|
|
Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
|
|
|
|
|
|
|
|
// why is there a loop of only 10 here
|
|
|
|
for( int i = 0; i < 10; ++i )
|
|
|
|
{
|
|
|
|
XQueryPointer( QX11Info::display(), parent, &root, &child, &rootX, &rootY, &x, &y, &mask );
|
|
|
|
if( child == None ) return 0;
|
|
|
|
Atom type;
|
|
|
|
int format;
|
|
|
|
unsigned long nitems, after;
|
|
|
|
unsigned char* prop;
|
|
|
|
if( XGetWindowProperty(
|
|
|
|
QX11Info::display(), child, wm_state, 0, 0, False,
|
|
|
|
AnyPropertyType, &type, &format, &nitems, &after, &prop ) == Success )
|
|
|
|
{
|
|
|
|
if( prop != NULL ) XFree( prop );
|
|
|
|
if( type != None ) return child;
|
|
|
|
}
|
|
|
|
parent = child;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2009-09-13 16:43:26 +00:00
|
|
|
|
2010-05-02 18:34:08 +00:00
|
|
|
}
|
2009-09-13 16:43:26 +00:00
|
|
|
|
|
|
|
}
|