00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 );
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 = "";
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
00164
00165
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 }
00224
00225 #include "detectwidget.moc"