add more spacing
[personal-kdebase.git] / workspace / kwin / kcmkwin / kwinrules / detectwidget.cpp
blobc117308ba7f4ee356ddf5ea9b0ff79bcc5603c50
1 /*
2 * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include <KDialog>
20 #include "detectwidget.h"
22 #include <kapplication.h>
23 #include <klocale.h>
24 #include <kdebug.h>
25 #include <kwindowsystem.h>
26 #include <QLabel>
27 #include <QRadioButton>
28 #include <QCheckBox>
29 //Added by qt3to4:
30 #include <QMouseEvent>
31 #include <QEvent>
32 #include <QByteArray>
34 #include <X11/Xlib.h>
35 #include <X11/Xatom.h>
36 #include <X11/Xutil.h>
37 #include <fixx11h.h>
38 #include <QX11Info>
40 namespace KWin
43 DetectWidget::DetectWidget( QWidget* parent )
44 : QWidget( parent )
46 setupUi( this );
49 DetectDialog::DetectDialog( QWidget* parent, const char* name )
50 : KDialog( parent ),
51 grabber( NULL )
53 setObjectName( name );
54 setModal( true );
55 setButtons( Ok | Cancel );
57 widget = new DetectWidget( this );
58 setMainWidget( widget );
61 void DetectDialog::detect( WId window )
63 if( window == 0 )
64 selectWindow();
65 else
66 readWindow( window );
69 void DetectDialog::readWindow( WId w )
71 if( w == 0 )
73 emit detectionDone( false );
74 return;
76 info = KWindowSystem::windowInfo( w, -1U, -1U ); // read everything
77 if( !info.valid())
79 emit detectionDone( false );
80 return;
82 wmclass_class = info.windowClassClass();
83 wmclass_name = info.windowClassName();
84 role = info.windowRole();
85 type = info.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask
86 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
87 | NET::UtilityMask | NET::SplashMask );
88 title = info.name();
89 extrarole = ""; // TODO
90 machine = info.clientMachine();
91 executeDialog();
94 void DetectDialog::executeDialog()
96 static const char* const types[] =
98 I18N_NOOP( "Normal Window" ),
99 I18N_NOOP( "Desktop" ),
100 I18N_NOOP( "Dock (panel)" ),
101 I18N_NOOP( "Toolbar" ),
102 I18N_NOOP( "Torn-Off Menu" ),
103 I18N_NOOP( "Dialog Window" ),
104 I18N_NOOP( "Override Type" ),
105 I18N_NOOP( "Standalone Menubar" ),
106 I18N_NOOP( "Utility Window" ),
107 I18N_NOOP( "Splash Screen" )
109 widget->class_label->setText( wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ')' );
110 widget->role_label->setText( role );
111 widget->use_role->setEnabled( !role.isEmpty());
112 if( widget->use_role->isEnabled())
113 widget->use_role->setChecked( true );
114 else
115 widget->use_whole_class->setChecked( true );
116 if( type == NET::Unknown )
117 widget->type_label->setText( i18n( "Unknown - will be treated as Normal Window" ));
118 else
119 widget->type_label->setText( i18n( types[ type ] ));
120 widget->title_label->setText( title );
121 widget->extrarole_label->setText( extrarole );
122 widget->machine_label->setText( machine );
123 emit detectionDone( exec() == KDialog::Accepted );
126 QByteArray DetectDialog::selectedClass() const
128 if( widget->use_class->isChecked() || widget->use_role->isChecked())
129 return wmclass_class;
130 return wmclass_name + ' ' + wmclass_class;
133 bool DetectDialog::selectedWholeClass() const
135 return widget->use_whole_class->isChecked();
138 QByteArray DetectDialog::selectedRole() const
140 if( widget->use_role->isChecked())
141 return role;
142 return "";
145 QString DetectDialog::selectedTitle() const
147 return title;
150 Rules::StringMatch DetectDialog::titleMatch() const
152 return widget->match_title->isChecked() ? Rules::ExactMatch : Rules::UnimportantMatch;
155 bool DetectDialog::selectedWholeApp() const
157 return widget->use_class->isChecked();
160 NET::WindowType DetectDialog::selectedType() const
162 return type;
165 QByteArray DetectDialog::selectedMachine() const
167 return machine;
170 void DetectDialog::selectWindow()
172 // use a dialog, so that all user input is blocked
173 // use WX11BypassWM and moving away so that it's not actually visible
174 // grab only mouse, so that keyboard can be used e.g. for switching windows
175 grabber = new KDialog( 0, Qt::X11BypassWindowManagerHint );
176 grabber->move( -1000, -1000 );
177 grabber->setModal( true );
178 grabber->show();
179 grabber->grabMouse( Qt::CrossCursor );
180 grabber->installEventFilter( this );
183 bool DetectDialog::eventFilter( QObject* o, QEvent* e )
185 if( o != grabber )
186 return false;
187 if( e->type() != QEvent::MouseButtonRelease )
188 return false;
189 delete grabber;
190 grabber = NULL;
191 if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton )
193 emit detectionDone( false );
194 return true;
196 readWindow( findWindow());
197 return true;
200 WId DetectDialog::findWindow()
202 Window root;
203 Window child;
204 uint mask;
205 int rootX, rootY, x, y;
206 Window parent = QX11Info::appRootWindow();
207 Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
208 for( int i = 0;
209 i < 10;
210 ++i )
212 XQueryPointer( QX11Info::display(), parent, &root, &child,
213 &rootX, &rootY, &x, &y, &mask );
214 if( child == None )
215 return 0;
216 Atom type;
217 int format;
218 unsigned long nitems, after;
219 unsigned char* prop;
220 if( XGetWindowProperty( QX11Info::display(), child, wm_state, 0, 0, False, AnyPropertyType,
221 &type, &format, &nitems, &after, &prop ) == Success )
223 if( prop != NULL )
224 XFree( prop );
225 if( type != None )
226 return child;
228 parent = child;
230 return 0;
233 } // namespace
235 #include "detectwidget.moc"