kwin Library API Documentation

detectwidget.cpp

00001 /*
00002  * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 #include "detectwidget.h"
00020 
00021 #include <kapplication.h>
00022 #include <klocale.h>
00023 #include <kdebug.h>
00024 #include <kwin.h>
00025 #include <qlabel.h>
00026 #include <qradiobutton.h>
00027 #include <qcheckbox.h>
00028 
00029 #include <X11/Xlib.h>
00030 #include <X11/Xatom.h>
00031 #include <X11/Xutil.h>
00032 #include <fixx11h.h>
00033 
00034 namespace KWinInternal
00035 {
00036 
00037 DetectWidget::DetectWidget( QWidget* parent, const char* name )
00038 : DetectWidgetBase( parent, name )
00039     {
00040     }
00041 
00042 DetectDialog::DetectDialog( QWidget* parent, const char* name )
00043 : KDialogBase( parent, name, true, "", Ok | Cancel )
00044 , grabber( NULL )
00045     {
00046     widget = new DetectWidget( this );
00047     setMainWidget( widget );
00048     }
00049 
00050 void DetectDialog::detect( WId window )
00051     {
00052     if( window == 0 )
00053         selectWindow();
00054     else
00055         readWindow( window );
00056     }
00057 
00058 void DetectDialog::readWindow( WId w )
00059     {
00060     if( w == 0 )
00061         {
00062         emit detectionDone( false );
00063         return;
00064         }
00065     info = KWin::windowInfo( w, -1U, -1U ); // read everything
00066     if( !info.valid())
00067         {
00068         emit detectionDone( false );
00069         return;
00070         }
00071     wmclass_class = info.windowClassClass();
00072     wmclass_name = info.windowClassName();
00073     role = info.windowRole();
00074     type = info.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask
00075         | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00076         | NET::UtilityMask | NET::SplashMask );
00077     title = info.name();
00078     extrarole = ""; // TODO
00079     machine = info.clientMachine();
00080     executeDialog();
00081     }
00082 
00083 void DetectDialog::executeDialog()
00084     {
00085     static const char* const types[] =
00086         {
00087         I18N_NOOP( "Normal Window" ),
00088         I18N_NOOP( "Desktop" ),
00089         I18N_NOOP( "Dock (panel)" ),
00090         I18N_NOOP( "Toolbar" ),
00091         I18N_NOOP( "Torn-Off Menu" ),
00092         I18N_NOOP( "Dialog Window" ),
00093         I18N_NOOP( "Override Type" ),
00094         I18N_NOOP( "Standalone Menubar" ),
00095         I18N_NOOP( "Utility Window" ),
00096         I18N_NOOP( "Splash Screen" )
00097         };
00098     widget->class_label->setText( wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ")" );
00099     widget->role_label->setText( role );
00100     widget->use_role->setEnabled( !role.isEmpty());
00101     if( widget->use_role->isEnabled())
00102         widget->use_role->setChecked( true );
00103     else
00104         widget->use_whole_class->setChecked( true );
00105     if( type == NET::Unknown )
00106         widget->type_label->setText( i18n( "Unknown - will be treated as Normal Window" ));
00107     else
00108         widget->type_label->setText( i18n( types[ type ] ));
00109     widget->title_label->setText( title );
00110     widget->extrarole_label->setText( extrarole );
00111     widget->machine_label->setText( machine );
00112     emit detectionDone( exec() == QDialog::Accepted );
00113     }
00114 
00115 QCString DetectDialog::selectedClass() const
00116     {
00117     if( widget->use_class->isChecked() || widget->use_role->isChecked())
00118         return wmclass_class;
00119     return wmclass_name + ' ' + wmclass_class;
00120     }
00121 
00122 bool DetectDialog::selectedWholeClass() const
00123     {
00124     return widget->use_whole_class->isChecked();
00125     }
00126 
00127 QCString DetectDialog::selectedRole() const
00128     {
00129     if( widget->use_role->isChecked())
00130         return role;
00131     return "";
00132     }
00133 
00134 QString DetectDialog::selectedTitle() const
00135     {
00136     return title;
00137     }
00138 
00139 Rules::StringMatch DetectDialog::titleMatch() const
00140     {
00141     return widget->match_title->isChecked() ? Rules::ExactMatch : Rules::UnimportantMatch;
00142     }
00143 
00144 bool DetectDialog::selectedWholeApp() const
00145     {
00146     return widget->use_class->isChecked();
00147     }
00148 
00149 NET::WindowType DetectDialog::selectedType() const
00150     {
00151     return type;
00152     }
00153 
00154 QCString DetectDialog::selectedMachine() const
00155     {
00156     return machine;
00157     }
00158 
00159 void DetectDialog::selectWindow()
00160     {
00161     // use a dialog, so that all user input is blocked
00162     // use WX11BypassWM and moving away so that it's not actually visible
00163     // grab only mouse, so that keyboard can be used e.g. for switching windows
00164     grabber = new QDialog( NULL, NULL, true, WX11BypassWM );
00165     grabber->move( -1000, -1000 );
00166     grabber->show();
00167     grabber->grabMouse( crossCursor );
00168     grabber->installEventFilter( this );
00169     }
00170 
00171 bool DetectDialog::eventFilter( QObject* o, QEvent* e )
00172     {
00173     if( o != grabber )
00174         return false;
00175     if( e->type() != QEvent::MouseButtonRelease )
00176         return false;
00177     delete grabber;
00178     grabber = NULL;
00179     if( static_cast< QMouseEvent* >( e )->button() != LeftButton )
00180         {
00181         emit detectionDone( false );
00182         return true;
00183         }
00184     readWindow( findWindow());
00185     return true;
00186     }
00187 
00188 WId DetectDialog::findWindow()
00189     {
00190     Window root;
00191     Window child;
00192     uint mask;
00193     int rootX, rootY, x, y;
00194     Window parent = qt_xrootwin();
00195     Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False );
00196     for( int i = 0;
00197          i < 10;
00198          ++i )
00199         {
00200         XQueryPointer( qt_xdisplay(), parent, &root, &child,
00201             &rootX, &rootY, &x, &y, &mask );
00202         if( child == None )
00203             return 0;
00204         Atom type;
00205         int format;
00206         unsigned long nitems, after;
00207         unsigned char* prop;
00208         if( XGetWindowProperty( qt_xdisplay(), child, wm_state, 0, 0, False, AnyPropertyType,
00209         &type, &format, &nitems, &after, &prop ) == Success )
00210             {
00211         if( prop != NULL )
00212             XFree( prop );
00213         if( type != None )
00214             return child;
00215             }
00216         parent = child;
00217         }
00218     return 0;
00219     }
00220 
00221 } // namespace
00222 
00223 #include "detectwidget.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jun 14 01:19:56 2006 by doxygen 1.4.0 written by Dimitri van Heesch, © 1997-2003