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 
00028 #include <X11/Xlib.h>
00029 #include <X11/Xatom.h>
00030 #include <X11/Xutil.h>
00031 #include <fixx11h.h>
00032 
00033 namespace KWinInternal
00034 {
00035 
00036 DetectWidget::DetectWidget( QWidget* parent, const char* name )
00037 : DetectWidgetBase( parent, name )
00038     {
00039     }
00040 
00041 DetectDialog::DetectDialog( QWidget* parent, const char* name )
00042 : KDialogBase( parent, name, true, "", Ok | Cancel )
00043 , grabber( NULL )
00044     {
00045     widget = new DetectWidget( this );
00046     setMainWidget( widget );
00047     }
00048 
00049 void DetectDialog::detect( WId window )
00050     {
00051     if( window == 0 )
00052         selectWindow();
00053     else
00054         readWindow( window );
00055     }
00056 
00057 void DetectDialog::readWindow( WId w )
00058     {
00059     if( w == 0 )
00060         {
00061         emit detectionDone( false );
00062         return;
00063         }
00064     info = KWin::windowInfo( w, -1U, -1U ); // read everything
00065     if( !info.valid())
00066         {
00067         emit detectionDone( false );
00068         return;
00069         }
00070     wmclass_class = info.windowClassClass();
00071     wmclass_name = info.windowClassName();
00072     role = info.windowRole();
00073     type = info.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask
00074         | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
00075         | NET::UtilityMask | NET::SplashMask );
00076     title = info.name();
00077     extrarole = ""; // TODO
00078     machine = info.clientMachine();
00079     executeDialog();
00080     }
00081 
00082 void DetectDialog::executeDialog()
00083     {
00084     static const char* const types[] =
00085         {
00086         I18N_NOOP( "Normal Window" ),
00087         I18N_NOOP( "Desktop" ),
00088         I18N_NOOP( "Dock (panel)" ),
00089         I18N_NOOP( "Toolbar" ),
00090         I18N_NOOP( "Torn-Off Menu" ),
00091         I18N_NOOP( "Dialog Window" ),
00092         I18N_NOOP( "Override Type" ),
00093         I18N_NOOP( "Standalone Menubar" ),
00094         I18N_NOOP( "Utility Window" ),
00095         I18N_NOOP( "Splash Screen" )
00096         };
00097     widget->class_label->setText( wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ")" );
00098     widget->role_label->setText( role );
00099     widget->use_role->setEnabled( !role.isEmpty());
00100     if( widget->use_role->isEnabled())
00101         widget->use_role->setChecked( true );
00102     else
00103         widget->use_whole_class->setChecked( true );
00104     if( type == NET::Unknown )
00105         widget->type_label->setText( i18n( "Unknown - will be treated as Normal Window" ));
00106     else
00107         widget->type_label->setText( i18n( types[ type ] ));
00108     widget->title_label->setText( title );
00109     widget->extrarole_label->setText( extrarole );
00110     widget->machine_label->setText( machine );
00111     emit detectionDone( exec() == QDialog::Accepted );
00112     }
00113 
00114 QCString DetectDialog::selectedClass() const
00115     {
00116     if( widget->use_class->isChecked() || widget->use_role->isChecked())
00117         return wmclass_class;
00118     return wmclass_name + ' ' + wmclass_class;
00119     }
00120 
00121 bool DetectDialog::selectedWholeClass() const
00122     {
00123     return widget->use_whole_class->isChecked();
00124     }
00125 
00126 QCString DetectDialog::selectedRole() const
00127     {
00128     if( widget->use_role->isChecked())
00129         return role;
00130     return "";
00131     }
00132 
00133 QString DetectDialog::selectedTitle() const
00134     {
00135     return title;
00136     }
00137 
00138 Rules::StringMatch DetectDialog::titleMatch() const
00139     {
00140 #if KDE_IS_VERSION( 3, 3, 90 )
00141 #warning Offer possibilities here
00142 #endif
00143     return Rules::UnimportantMatch;
00144     }
00145 
00146 bool DetectDialog::selectedWholeApp() const
00147     {
00148     return widget->use_class->isChecked();
00149     }
00150 
00151 NET::WindowType DetectDialog::selectedType() const
00152     {
00153     return type;
00154     }
00155 
00156 QCString DetectDialog::selectedMachine() const
00157     {
00158     return machine;
00159     }
00160 
00161 void DetectDialog::selectWindow()
00162     {
00163     // use a dialog, so that all user input is blocked
00164     // use WX11BypassWM and moving away so that it's not actually visible
00165     // grab only mouse, so that keyboard can be used e.g. for switching windows
00166     grabber = new QDialog( NULL, NULL, true, WX11BypassWM );
00167     grabber->move( -1000, -1000 );
00168     grabber->show();
00169     grabber->grabMouse( crossCursor );
00170     grabber->installEventFilter( this );
00171     }
00172 
00173 bool DetectDialog::eventFilter( QObject* o, QEvent* e )
00174     {
00175     if( o != grabber )
00176         return false;
00177     if( e->type() != QEvent::MouseButtonRelease )
00178         return false;
00179     delete grabber;
00180     grabber = NULL;
00181     if( static_cast< QMouseEvent* >( e )->button() != LeftButton )
00182         {
00183         emit detectionDone( false );
00184         return true;
00185         }
00186     readWindow( findWindow());
00187     return true;
00188     }
00189 
00190 WId DetectDialog::findWindow()
00191     {
00192     Window root;
00193     Window child;
00194     uint mask;
00195     int rootX, rootY, x, y;
00196     Window parent = qt_xrootwin();
00197     Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False );
00198     for( int i = 0;
00199          i < 10;
00200          ++i )
00201         {
00202         XQueryPointer( qt_xdisplay(), parent, &root, &child,
00203             &rootX, &rootY, &x, &y, &mask );
00204         if( child == None )
00205             return 0;
00206         Atom type;
00207         int format;
00208         unsigned long nitems, after;
00209         unsigned char* prop;
00210         if( XGetWindowProperty( qt_xdisplay(), child, wm_state, 0, 0, False, AnyPropertyType,
00211         &type, &format, &nitems, &after, &prop ) == Success )
00212             {
00213         if( prop != NULL )
00214             XFree( prop );
00215         if( type != None )
00216             return child;
00217             }
00218         parent = child;
00219         }
00220     return 0;
00221     }
00222 
00223 } // namespace
00224 
00225 #include "detectwidget.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 5 03:59:38 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003