-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sync titlebar toolbox with main window in position and size. demoing mpv event processing, key processing Change-Id: I5b2f7e801e697d0f805a330411c5ecf6ca4d9ac3
- Loading branch information
Showing
15 changed files
with
633 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- | ||
* -*- coding: utf-8 -*- | ||
* | ||
* Copyright (C) 2011 ~ 2017 Deepin, Inc. | ||
* 2011 ~ 2017 Wang Yong | ||
* | ||
* Author: Wang Yong <[email protected]> | ||
* Maintainer: Wang Yong <[email protected]> | ||
* | ||
* 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 3 of the License, or | ||
* 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "event_monitor.h" | ||
#include <X11/Xlibint.h> | ||
#include <X11/extensions/record.h> | ||
|
||
namespace dmr { | ||
|
||
EventMonitor::EventMonitor(QObject *parent) : QThread(parent) | ||
{ | ||
isPress = false; | ||
} | ||
|
||
void EventMonitor::run() | ||
{ | ||
Display* display = XOpenDisplay(0); | ||
if (display == 0) { | ||
fprintf(stderr, "unable to open display\n"); | ||
return; | ||
} | ||
|
||
// Receive from ALL clients, including future clients. | ||
//XRecordClientSpec clients = XRecordAllClients; | ||
XRecordClientSpec clients = XRecordCurrentClients; | ||
XRecordRange* range = XRecordAllocRange(); | ||
if (range == 0) { | ||
fprintf(stderr, "unable to allocate XRecordRange\n"); | ||
return; | ||
} | ||
|
||
// Receive KeyPress, KeyRelease, ButtonPress, ButtonRelease and MotionNotify events. | ||
memset(range, 0, sizeof(XRecordRange)); | ||
range->device_events.first = ButtonPress; | ||
range->device_events.last = MotionNotify; | ||
//range->delivered_events.first = KeyPress; | ||
//range->delivered_events.last = MotionNotify; | ||
|
||
// And create the XRECORD context. | ||
XRecordContext context = XRecordCreateContext (display, 0, &clients, 1, &range, 1); | ||
if (context == 0) { | ||
fprintf(stderr, "XRecordCreateContext failed\n"); | ||
return; | ||
} | ||
XFree(range); | ||
|
||
XSync(display, True); | ||
|
||
Display* display_datalink = XOpenDisplay(0); | ||
if (display_datalink == 0) { | ||
fprintf(stderr, "unable to open second display\n"); | ||
return; | ||
} | ||
|
||
if (!XRecordEnableContext(display_datalink, context, callback, (XPointer) this)) { | ||
fprintf(stderr, "XRecordEnableContext() failed\n"); | ||
return; | ||
} | ||
} | ||
|
||
void EventMonitor::callback(XPointer ptr, XRecordInterceptData* data) | ||
{ | ||
((EventMonitor *) ptr)->handleRecordEvent(data); | ||
} | ||
|
||
void EventMonitor::handleRecordEvent(XRecordInterceptData* data) | ||
{ | ||
if (data->category == XRecordFromServer) { | ||
xEvent * event = (xEvent *)data->data; | ||
switch (event->u.u.type) { | ||
case ButtonPress: | ||
if (event->u.u.detail != WheelUp && | ||
event->u.u.detail != WheelDown && | ||
event->u.u.detail != WheelLeft && | ||
event->u.u.detail != WheelRight) { | ||
isPress = true; | ||
emit buttonedPress(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); | ||
} | ||
break; | ||
case MotionNotify: | ||
if (isPress) { | ||
emit buttonedDrag(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); | ||
} | ||
break; | ||
case ButtonRelease: | ||
if (event->u.u.detail != WheelUp && | ||
event->u.u.detail != WheelDown && | ||
event->u.u.detail != WheelLeft && | ||
event->u.u.detail != WheelRight) { | ||
isPress = false; | ||
emit buttonedRelease(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
fflush(stdout); | ||
XRecordFreeData(data); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- | ||
* -*- coding: utf-8 -*- | ||
* | ||
* Copyright (C) 2011 ~ 2017 Deepin, Inc. | ||
* 2011 ~ 2017 Wang Yong | ||
* | ||
* Author: Wang Yong <[email protected]> | ||
* Maintainer: Wang Yong <[email protected]> | ||
* | ||
* 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 3 of the License, or | ||
* 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef EVENTMONITOR_H | ||
#define EVENTMONITOR_H | ||
|
||
#include <QThread> | ||
#include <X11/Xlib.h> | ||
#include <X11/extensions/record.h> | ||
|
||
namespace dmr { | ||
|
||
// Virtual button codes that are not defined by X11. | ||
//#define Button1 1 | ||
//#define Button2 2 | ||
//#define Button3 3 | ||
#define WheelUp 4 | ||
#define WheelDown 5 | ||
#define WheelLeft 6 | ||
#define WheelRight 7 | ||
//#define XButton1 8 | ||
//#define XButton2 9 | ||
|
||
class EventMonitor : public QThread | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
EventMonitor(QObject *parent = 0); | ||
static void callback(XPointer trash, XRecordInterceptData* data); | ||
void handleRecordEvent(XRecordInterceptData *); | ||
|
||
signals: | ||
void buttonedPress(int x, int y); | ||
void buttonedDrag(int x, int y); | ||
void buttonedRelease(int x, int y); | ||
|
||
protected: | ||
void run(); | ||
|
||
private: | ||
bool isPress; | ||
}; | ||
|
||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <xcb/xproto.h> | ||
#include <xcb/xcb_aux.h> | ||
|
||
#include <QtCore> | ||
#include <QX11Info> | ||
|
||
#include "event_relayer.h" | ||
|
||
namespace dmr { | ||
|
||
EventRelayer::EventRelayer(QWindow* src, QWindow *dest) | ||
:QObject(), QAbstractNativeEventFilter(), _source(src), _target(dest) { | ||
int screen = 0; | ||
xcb_screen_t *s = xcb_aux_get_screen (QX11Info::connection(), screen); | ||
const uint32_t data[] = { | ||
XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | ||
}; | ||
xcb_change_window_attributes (QX11Info::connection(), _source->winId(), | ||
XCB_CW_EVENT_MASK, data); | ||
|
||
qApp->installNativeEventFilter(this); | ||
} | ||
|
||
EventRelayer::~EventRelayer() { | ||
qApp->removeNativeEventFilter(this); | ||
} | ||
|
||
bool EventRelayer::nativeEventFilter(const QByteArray &eventType, void *message, long *) { | ||
if(Q_LIKELY(eventType == "xcb_generic_event_t")) { | ||
xcb_generic_event_t* event = static_cast<xcb_generic_event_t *>(message); | ||
switch (event->response_type & ~0x80) { | ||
case XCB_CONFIGURE_NOTIFY: { | ||
xcb_configure_notify_event_t *cne = (xcb_configure_notify_event_t*)event; | ||
if (cne->window != _source->winId()) | ||
return false; | ||
|
||
QPoint p(cne->x, cne->y); | ||
if (p != _target->framePosition()) { | ||
qDebug() << "cne: " << QRect(cne->x, cne->y, cne->width, cne->height) | ||
<< "origin: " << _source->framePosition() | ||
<< "dest: " << _target->framePosition(); | ||
emit targetNeedsUpdatePosition(QPoint(cne->x, cne->y)); | ||
} | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef _DMR_EVENT_RELAYER_H | ||
#define _DMR_EVENT_RELAYER_H | ||
|
||
#include <QWindow> | ||
#include <QAbstractNativeEventFilter> | ||
#include <QByteArray> | ||
#include <QObject> | ||
#include <QPoint> | ||
|
||
namespace dmr { | ||
|
||
class EventRelayer: public QObject, public QAbstractNativeEventFilter | ||
{ | ||
Q_OBJECT | ||
public: | ||
EventRelayer(QWindow* src, QWindow *dest); | ||
~EventRelayer(); | ||
|
||
signals: | ||
void targetNeedsUpdatePosition(const QPoint& p); | ||
|
||
protected: | ||
bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; | ||
|
||
private: | ||
QWindow *_source, *_target; | ||
}; | ||
|
||
} | ||
|
||
#endif /* ifndef _DMR_EVENT_RELAYER_H */ |
Oops, something went wrong.