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.
20
#include "detectwidget.h"
22
#include <kapplication.h>
25
#include <kwindowsystem.h>
27
#include <QRadioButton>
30
#include <QMouseEvent>
36
#include <X11/Xatom.h>
37
#include <X11/Xutil.h>
44
DetectWidget::DetectWidget(QWidget* parent)
50
DetectDialog::DetectDialog(QWidget* parent, const char* name)
56
setButtons(Ok | Cancel);
58
widget = new DetectWidget(this);
59
setMainWidget(widget);
62
void DetectDialog::detect(WId window, int secs)
65
QTimer::singleShot(secs*1000, this, SLOT(selectWindow()));
70
void DetectDialog::readWindow(WId w)
73
emit detectionDone(false);
76
info = KWindowSystem::windowInfo(w, -1U, -1U); // read everything
78
emit detectionDone(false);
81
wmclass_class = info.windowClassClass();
82
wmclass_name = info.windowClassName();
83
role = info.windowRole();
84
type = info.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask
85
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask
86
| NET::UtilityMask | NET::SplashMask);
88
extrarole = ""; // TODO
89
machine = info.clientMachine();
93
void DetectDialog::executeDialog()
95
static const char* const types[] = {
96
I18N_NOOP("Normal Window"),
98
I18N_NOOP("Dock (panel)"),
100
I18N_NOOP("Torn-Off Menu"),
101
I18N_NOOP("Dialog Window"),
102
I18N_NOOP("Override Type"),
103
I18N_NOOP("Standalone Menubar"),
104
I18N_NOOP("Utility Window"),
105
I18N_NOOP("Splash Screen")
107
widget->class_label->setText(wmclass_class + " (" + wmclass_name + ' ' + wmclass_class + ')');
108
widget->role_label->setText(role);
109
widget->use_role->setEnabled(!role.isEmpty());
110
if (widget->use_role->isEnabled())
111
widget->use_role->setChecked(true);
113
widget->use_whole_class->setChecked(true);
114
if (type == NET::Unknown)
115
widget->type_label->setText(i18n("Unknown - will be treated as Normal Window"));
117
widget->type_label->setText(i18n(types[ type ]));
118
widget->title_label->setText(title);
119
widget->extrarole_label->setText(extrarole);
120
widget->machine_label->setText(machine);
121
widget->adjustSize();
123
if (width() < 4*height()/3)
124
resize(4*height()/3, height());
125
emit detectionDone(exec() == KDialog::Accepted);
128
QByteArray DetectDialog::selectedClass() const
130
if (widget->use_class->isChecked() || widget->use_role->isChecked())
131
return wmclass_class;
132
return wmclass_name + ' ' + wmclass_class;
135
bool DetectDialog::selectedWholeClass() const
137
return widget->use_whole_class->isChecked();
140
QByteArray DetectDialog::selectedRole() const
142
if (widget->use_role->isChecked())
147
QString DetectDialog::selectedTitle() const
152
Rules::StringMatch DetectDialog::titleMatch() const
154
return widget->match_title->isChecked() ? Rules::ExactMatch : Rules::UnimportantMatch;
157
bool DetectDialog::selectedWholeApp() const
159
return widget->use_class->isChecked();
162
NET::WindowType DetectDialog::selectedType() const
167
QByteArray DetectDialog::selectedMachine() const
172
void DetectDialog::selectWindow()
174
// use a dialog, so that all user input is blocked
175
// use WX11BypassWM and moving away so that it's not actually visible
176
// grab only mouse, so that keyboard can be used e.g. for switching windows
177
grabber = new KDialog(0, Qt::X11BypassWindowManagerHint);
178
grabber->move(-1000, -1000);
179
grabber->setModal(true);
181
grabber->grabMouse(Qt::CrossCursor);
182
grabber->installEventFilter(this);
185
bool DetectDialog::eventFilter(QObject* o, QEvent* e)
189
if (e->type() != QEvent::MouseButtonRelease)
193
if (static_cast< QMouseEvent* >(e)->button() != Qt::LeftButton) {
194
emit detectionDone(false);
197
readWindow(findWindow());
201
WId DetectDialog::findWindow()
206
int rootX, rootY, x, y;
207
Window parent = QX11Info::appRootWindow();
208
Atom wm_state = XInternAtom(QX11Info::display(), "WM_STATE", False);
212
XQueryPointer(QX11Info::display(), parent, &root, &child,
213
&rootX, &rootY, &x, &y, &mask);
218
unsigned long nitems, after;
220
if (XGetWindowProperty(QX11Info::display(), child, wm_state, 0, 0, False, AnyPropertyType,
221
&type, &format, &nitems, &after, &prop) == Success) {
234
#include "detectwidget.moc"