summaryrefslogtreecommitdiffstats
path: root/kwin/kcmkwin/kwinrules/detectwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/kcmkwin/kwinrules/detectwidget.cpp')
-rw-r--r--kwin/kcmkwin/kwinrules/detectwidget.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/kwin/kcmkwin/kwinrules/detectwidget.cpp b/kwin/kcmkwin/kwinrules/detectwidget.cpp
new file mode 100644
index 000000000..1a8fa5af5
--- /dev/null
+++ b/kwin/kcmkwin/kwinrules/detectwidget.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "detectwidget.h"
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kwin.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <fixx11h.h>
+
+namespace KWinInternal
+{
+
+DetectWidget::DetectWidget( QWidget* parent, const char* name )
+: DetectWidgetBase( parent, name )
+ {
+ }
+
+DetectDialog::DetectDialog( QWidget* parent, const char* name )
+: KDialogBase( parent, name, true, "", Ok | Cancel )
+, grabber( NULL )
+ {
+ widget = new DetectWidget( this );
+ setMainWidget( widget );
+ }
+
+void DetectDialog::detect( WId window )
+ {
+ if( window == 0 )
+ selectWindow();
+ else
+ readWindow( window );
+ }
+
+void DetectDialog::readWindow( WId w )
+ {
+ if( w == 0 )
+ {
+ emit detectionDone( false );
+ return;
+ }
+ info = KWin::windowInfo( w, -1U, -1U ); // read everything
+ if( !info.valid())
+ {
+ emit detectionDone( false );
+ return;
+ }
+ wmclass_class = info.windowClassClass();
+ wmclass_name = info.windowClassName();
+ role = info.windowRole();
+ type = info.windowType( NET::NormalMask | NET::DesktopMask | NET::DockMask
+ | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
+ | NET::UtilityMask | NET::SplashMask );
+ title = info.name();
+ extrarole = ""; // TODO
+ machine = info.clientMachine();
+ executeDialog();
+ }
+
+void DetectDialog::executeDialog()
+ {
+ static const char* const types[] =
+ {
+ I18N_NOOP( "Normal Window" ),
+ I18N_NOOP( "Desktop" ),
+ I18N_NOOP( "Dock (panel)" ),
+ I18N_NOOP( "Toolbar" ),
+ I18N_NOOP( "Torn-Off Menu" ),
+ I18N_NOOP( "Dialog Window" ),
+ I18N_NOOP( "Override Type" ),
+ I18N_NOOP( "Standalone Menubar" ),
+ I18N_NOOP( "Utility Window" ),
+ I18N_NOOP( "Splash Screen" )
+ };
+ widget->class_label->setText( wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ")" );
+ widget->role_label->setText( role );
+ widget->use_role->setEnabled( !role.isEmpty());
+ if( widget->use_role->isEnabled())
+ widget->use_role->setChecked( true );
+ else
+ widget->use_whole_class->setChecked( true );
+ if( type == NET::Unknown )
+ widget->type_label->setText( i18n( "Unknown - will be treated as Normal Window" ));
+ else
+ widget->type_label->setText( i18n( types[ type ] ));
+ widget->title_label->setText( title );
+ widget->extrarole_label->setText( extrarole );
+ widget->machine_label->setText( machine );
+ emit detectionDone( exec() == QDialog::Accepted );
+ }
+
+QCString DetectDialog::selectedClass() const
+ {
+ if( widget->use_class->isChecked() || widget->use_role->isChecked())
+ return wmclass_class;
+ return wmclass_name + ' ' + wmclass_class;
+ }
+
+bool DetectDialog::selectedWholeClass() const
+ {
+ return widget->use_whole_class->isChecked();
+ }
+
+QCString DetectDialog::selectedRole() const
+ {
+ if( widget->use_role->isChecked())
+ return role;
+ return "";
+ }
+
+QString DetectDialog::selectedTitle() const
+ {
+ return title;
+ }
+
+Rules::StringMatch DetectDialog::titleMatch() const
+ {
+ return widget->match_title->isChecked() ? Rules::ExactMatch : Rules::UnimportantMatch;
+ }
+
+bool DetectDialog::selectedWholeApp() const
+ {
+ return widget->use_class->isChecked();
+ }
+
+NET::WindowType DetectDialog::selectedType() const
+ {
+ return type;
+ }
+
+QCString DetectDialog::selectedMachine() const
+ {
+ return machine;
+ }
+
+void DetectDialog::selectWindow()
+ {
+ // use a dialog, so that all user input is blocked
+ // use WX11BypassWM and moving away so that it's not actually visible
+ // grab only mouse, so that keyboard can be used e.g. for switching windows
+ grabber = new QDialog( NULL, NULL, true, WX11BypassWM );
+ grabber->move( -1000, -1000 );
+ grabber->show();
+ grabber->grabMouse( crossCursor );
+ grabber->installEventFilter( this );
+ }
+
+bool DetectDialog::eventFilter( QObject* o, QEvent* e )
+ {
+ if( o != grabber )
+ return false;
+ if( e->type() != QEvent::MouseButtonRelease )
+ return false;
+ delete grabber;
+ grabber = NULL;
+ if( static_cast< QMouseEvent* >( e )->button() != LeftButton )
+ {
+ emit detectionDone( false );
+ return true;
+ }
+ readWindow( findWindow());
+ return true;
+ }
+
+WId DetectDialog::findWindow()
+ {
+ Window root;
+ Window child;
+ uint mask;
+ int rootX, rootY, x, y;
+ Window parent = qt_xrootwin();
+ Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False );
+ for( int i = 0;
+ i < 10;
+ ++i )
+ {
+ XQueryPointer( qt_xdisplay(), parent, &root, &child,
+ &rootX, &rootY, &x, &y, &mask );
+ if( child == None )
+ return 0;
+ Atom type;
+ int format;
+ unsigned long nitems, after;
+ unsigned char* prop;
+ if( XGetWindowProperty( qt_xdisplay(), child, wm_state, 0, 0, False, AnyPropertyType,
+ &type, &format, &nitems, &after, &prop ) == Success )
+ {
+ if( prop != NULL )
+ XFree( prop );
+ if( type != None )
+ return child;
+ }
+ parent = child;
+ }
+ return 0;
+ }
+
+} // namespace
+
+#include "detectwidget.moc"