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 #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 );
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 = "";
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
00162
00163
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 }
00222
00223 #include "detectwidget.moc"