Skip to content

Commit

Permalink
Changes: Change the EventEater window to an InputOnly window
Browse files Browse the repository at this point in the history
RevBy: Vesa Halttunen
  • Loading branch information
Matti Vuorela committed Dec 16, 2010
1 parent 24b4c24 commit a7d18e6
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 71 deletions.
1 change: 1 addition & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ system-ui (0.19.5~1) unstable; urgency=low

* [UNRELEASED]
* Fixes: NB#209416 - MNotificationGroup::remove() call takes long time
* Fixes: A compositing artifact when the display is dimmed due to an idle timeout

-- Vesa Halttunen <[email protected]> Wed, 15 Dec 2010 18:56:27 +0200

Expand Down
64 changes: 43 additions & 21 deletions src/systemui/screenlock/eventeater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
****************************************************************************/

#include "eventeater.h"
#include <QMouseEvent>
#include <QX11Info>
#include <QAbstractEventDispatcher>
#include "x11wrapper.h"

// Event eater instance that listens input events
static EventEater *eventEaterListenerInstance = NULL;
Expand All @@ -42,21 +38,42 @@ static bool eventEaterEventFilter(void *message)

EventEater::EventEater()
{
setWindowTitle("EventEater");
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_X11NetWmWindowTypeDialog);
setAttribute(Qt::WA_X11DoNotAcceptFocus);
setObjectName("EventEater");
setProperty("NoMStyle", true);

if (previousEventFilter == NULL)
previousEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventEaterEventFilter);

Display *dpy = QX11Info::display();
int scr = DefaultScreen(dpy);

XSetWindowAttributes attr;
attr.override_redirect = True;

window = X11Wrapper::XCreateWindow(dpy, DefaultRootWindow(dpy),
0, 0,
DisplayWidth(dpy, scr), DisplayHeight(dpy, scr),
0,
CopyFromParent,
InputOnly,
CopyFromParent,
CWOverrideRedirect,
&attr);

X11Wrapper::XSelectInput(dpy, window, ButtonPressMask|ButtonReleaseMask|KeyPressMask);
X11Wrapper::XStoreName(dpy, window, const_cast<char*>("EventEater"));

// Set the stacking layer
Atom stackingLayerAtom = X11Wrapper::XInternAtom(dpy, "_MEEGO_STACKING_LAYER", False);
if (stackingLayerAtom != None) {
long layer = 6;
X11Wrapper::XChangeProperty(dpy, window, stackingLayerAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &layer, 1);
}

eventEaterListenerInstance = this;
}

EventEater::~EventEater()
{
X11Wrapper::XDestroyWindow(QX11Info::display(), window);

// If destroying effective instance, then set static instance and filter pointers to NULL and restore previous event filter
if (this == eventEaterListenerInstance) {
eventEaterListenerInstance = NULL;
Expand All @@ -65,23 +82,28 @@ EventEater::~EventEater()
}
}

void EventEater::showEvent(QShowEvent *event)
void EventEater::show()
{
QWidget::showEvent(event);
Display *dpy = QX11Info::display();

// Set the stacking layer
Display *display = QX11Info::display();
Atom stackingLayerAtom = X11Wrapper::XInternAtom(display, "_MEEGO_STACKING_LAYER", False);
if (stackingLayerAtom != None) {
long layer = 6;
X11Wrapper::XChangeProperty(display, winId(), stackingLayerAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &layer, 1);
}
X11Wrapper::XMapRaised(dpy, window);

// Grab is released automatically at unmap
X11Wrapper::XGrabKeyboard(dpy, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
}

void EventEater::hide()
{
X11Wrapper::XUnmapWindow(QX11Info::display(), window);
}

bool EventEater::eventFilter(XEvent *event)
{
bool handled = false;
if (isVisible() && event->xany.window == winId() && (event->type == ButtonPress || event->type == ButtonRelease)) {

if ((event->xany.window == window) &&
(event->type == ButtonPress || event->type == KeyPress)) {

handled = true;
emit inputEventReceived();
}
Expand Down
27 changes: 17 additions & 10 deletions src/systemui/screenlock/eventeater.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,41 @@
#ifndef EVENTEATER_H
#define EVENTEATER_H

#include <QWidget>
#include <QObject>
#include <QAbstractEventDispatcher>

class QShowEvent;
#include <QX11Info>
#include "x11wrapper.h"

/*!
* An EventEater window interrupts X press and release events. On event received EventEater hides it window.
* An EventEater window interrupts X pointer and key press events. On event received EventEater hides its window.
*
* When creating an EventEater instance, it becomes the effective EventEater instance. Only effective instance interrupts
* events. There can be only one effective instance, so when EventEater is created any previous instances become obsolete
* and don't interrupt events any more.
*/
class EventEater : public QWidget {
class EventEater : public QObject {
Q_OBJECT
public:

//! Creates a new EventEater instance and its window. This EventEater becomes the effective instance.
EventEater();

//! Destroys the EventEater and its window.
virtual ~EventEater();

/*! Event filter method to handle input events.
*/
bool eventFilter(XEvent *event);

protected:
/*!
* Sets the _MEEGO_STACKING_LAYER window property to 6.
*/
virtual void showEvent(QShowEvent *event);
/*! Show the event eater window */
void show();

/*! Hide the event eater window */
void hide();

private:

Window window;

signals:
//! Emitted when input event is received for the window.
Expand Down
7 changes: 2 additions & 5 deletions src/systemui/screenlock/screenlockbusinesslogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,9 @@ void ScreenLockBusinessLogic::toggleEventEater(bool toggle)
connect(eventEaterWindow, SIGNAL(inputEventReceived()), this, SLOT(hideEventEater()));
}

if (!eventEaterWindow->isVisible()) {
eventEaterWindow->show();
eventEaterWindow->showFullScreen();
}
eventEaterWindow->show();
} else {
if (eventEaterWindow != NULL && eventEaterWindow->isVisible()) {
if (eventEaterWindow != NULL) {
eventEaterWindow->hide();
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/systemui/x11wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,33 @@ Status X11Wrapper::XSendEvent(Display *display, Window w, Bool propagate, long e
{
return ::XSendEvent(display, w, propagate, event_mask, event_send);
}

Window X11Wrapper::XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class_, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes)
{
return ::XCreateWindow(display, parent, x, y, width, height, border_width, depth, class_, visual, valuemask, attributes);
}

int X11Wrapper::XDestroyWindow(Display *display, Window w)
{
return ::XDestroyWindow(display, w);
}

int X11Wrapper::XMapRaised(Display *display, Window w)
{
return ::XMapRaised(display, w);
}

int X11Wrapper::XUnmapWindow(Display *display, Window w)
{
return ::XUnmapWindow(display, w);
}

int X11Wrapper::XStoreName(Display *display, Window w, char *window_name)
{
return ::XStoreName(display, w, window_name);
}

int X11Wrapper::XGrabKeyboard(Display *display, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time)
{
return ::XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, time);
}
6 changes: 6 additions & 0 deletions src/systemui/x11wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class X11Wrapper
static XErrorHandler XSetErrorHandler(XErrorHandler handler);
static int XChangeProperty(Display *display, Window w, Atom property, Atom type, int format, int mode, unsigned char *data, int nelements);
static Status XSendEvent(Display *display, Window w, Bool propagate, long event_mask, XEvent *event_send);
static Window XCreateWindow(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int class_, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes);
static int XDestroyWindow(Display *display, Window w);
static int XMapRaised(Display *display, Window w);
static int XUnmapWindow(Display *display, Window w);
static int XStoreName(Display *display, Window w, char *window_name);
static int XGrabKeyboard(Display *display, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode, Time time);
};

#endif /* X11WRAPPER_H_ */
6 changes: 5 additions & 1 deletion tests/common/xchecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ XChecker::pr (

/*!
* \param WindowID The current window ID for the recursion.
* \param WMName The "_NET_WM_NAME" value for the windows to check.
* \param WMName The "_NET_WM_NAME" or "WM_NAME" value for the windows to check.
*/
bool
XChecker::check_window_rec (
Expand All @@ -323,6 +323,10 @@ XChecker::check_window_rec (
attrs.map_state = IsUnmapped;

wmname = get_utf8_prop (dpy, WindowID, name_atom);

if (!wmname)
wmname = get_str_prop (dpy, WindowID, name_atom2);

XGetWindowAttributes(dpy, WindowID, &attrs);

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Ft_LockScreenBusinessLogic::testLockScreenBusinessLogic ()
SYS_DEBUG ("***************************************************");
m_LockScreenBusinessLogic->toggleEventEater (true);
QTest::qWait (WMDelay);
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->internalWinId();
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->window;

QVERIFY (m_XChecker.checkWindow (
EventEaterWindowID,
Expand All @@ -134,7 +134,7 @@ Ft_LockScreenBusinessLogic::testLockScreenBusinessLogic ()
SYS_DEBUG ("***************************************************");
m_LockScreenBusinessLogic->toggleEventEater (false);
QTest::qWait (WMDelay);
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->internalWinId();
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->window;

QVERIFY (m_XChecker.checkWindow(
EventEaterWindowID,
Expand Down Expand Up @@ -211,7 +211,7 @@ Ft_LockScreenBusinessLogic::testLockScreenBusinessLogicWithMainWindow ()
SYS_DEBUG ("***************************************************");
m_LockScreenBusinessLogic->toggleEventEater (true);
QTest::qWait (WMDelay);
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->internalWinId();
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->window;

QVERIFY (m_XChecker.checkWindow(
EventEaterWindowID,
Expand All @@ -230,7 +230,7 @@ Ft_LockScreenBusinessLogic::testLockScreenBusinessLogicWithMainWindow ()
SYS_DEBUG ("***************************************************");
m_LockScreenBusinessLogic->toggleEventEater (false);
QTest::qWait (WMDelay);
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->internalWinId();
EventEaterWindowID = m_LockScreenBusinessLogic->eventEaterWindow->window;

QVERIFY (m_XChecker.checkWindow(
EventEaterWindowID,
Expand Down
22 changes: 15 additions & 7 deletions tests/stubs/eventeater_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class EventEaterStub : public StubBase {
public:
virtual void EventEaterConstructor();
virtual void EventEaterDestructor();
virtual void showEvent(QShowEvent *event);
virtual void show();
virtual void hide();
virtual bool eventFilter(XEvent *event);
};

Expand All @@ -39,10 +40,12 @@ void EventEaterStub::EventEaterConstructor() {
void EventEaterStub::EventEaterDestructor() {
}

void EventEaterStub::showEvent(QShowEvent *event) {
QList<ParameterBase*> params;
params.append( new Parameter<QShowEvent * >(event));
stubMethodEntered("showEvent",params);
void EventEaterStub::show() {
stubMethodEntered("show");
}

void EventEaterStub::hide() {
stubMethodEntered("hide");
}

bool EventEaterStub::eventFilter(XEvent *event) {
Expand All @@ -64,8 +67,13 @@ EventEater::EventEater() {
EventEater::~EventEater() {
gEventEaterStub->EventEaterDestructor();
}
void EventEater::showEvent(QShowEvent *event) {
gEventEaterStub->showEvent(event);

void EventEater::show() {
gEventEaterStub->show();
}

void EventEater::hide() {
gEventEaterStub->hide();
}

bool EventEater::eventFilter(XEvent *event) {
Expand Down
Loading

0 comments on commit a7d18e6

Please sign in to comment.