Skip to content

Commit

Permalink
Basic demo
Browse files Browse the repository at this point in the history
Sync titlebar toolbox with main window in position and size.
demoing mpv event processing, key processing

Change-Id: I5b2f7e801e697d0f805a330411c5ecf6ca4d9ac3
  • Loading branch information
sonald committed Apr 19, 2017
1 parent 0075ed3 commit fb690c9
Show file tree
Hide file tree
Showing 15 changed files with 633 additions and 91 deletions.
4 changes: 2 additions & 2 deletions .ycm_extra_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
#compilation_database_folder = '/home/sonald/stage/deepin-movie-reborn/build'
compilation_database_folder = ''
compilation_database_folder = '/home/sonald/stage/deepin-movie-reborn/build'
#compilation_database_folder = ''

if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
Expand Down
5 changes: 3 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ pkg_check_modules(Mpv REQUIRED IMPORTED_TARGET mpv)
pkg_check_modules(Xcb REQUIRED IMPORTED_TARGET xcb xcb-aux)

add_executable(${CMD_NAME} main.cpp mainwindow.cpp mpv_proxy.cpp
dmr_titlebar.cpp titlebar_proxy.cpp actions.cpp xutil.cpp)
dmr_titlebar.cpp titlebar_proxy.cpp actions.cpp xutil.cpp
event_monitor.cpp toolbox_proxy.cpp event_relayer.cpp)
target_include_directories(${CMD_NAME} PUBLIC ${PROJECT_INCLUDE})

target_link_libraries(${CMD_NAME} X11 Xext PkgConfig::Xcb
target_link_libraries(${CMD_NAME} X11 Xext Xtst PkgConfig::Xcb
Qt5::Widgets Qt5::X11Extras PkgConfig::Dtk PkgConfig::Mpv)

10 changes: 2 additions & 8 deletions src/dmr_titlebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,8 @@ void DMRTitlebar::mousePressEvent(QMouseEvent *event)
D_D(DMRTitlebar);
d->mousePressed = (event->buttons() == Qt::LeftButton);

#ifdef Q_OS_WIN
emit mousePosPressed(event->buttons(), event->globalPos());
#endif
emit mousePressed(event->buttons());
QWidget::mousePressEvent(event);
}

void DMRTitlebar::mouseReleaseEvent(QMouseEvent *event)
Expand All @@ -246,6 +244,7 @@ void DMRTitlebar::mouseReleaseEvent(QMouseEvent *event)
if (event->buttons() == Qt::LeftButton) {
d->mousePressed = false;
}
QWidget::mouseReleaseEvent(event);
}

bool DMRTitlebar::eventFilter(QObject *obj, QEvent *event)
Expand Down Expand Up @@ -407,11 +406,6 @@ void DMRTitlebar::mouseMoveEvent(QMouseEvent *event)
emit mouseMoving(button);
}

#ifdef Q_OS_WIN
if (d->mousePressed) {
emit mousePosMoving(button, event->globalPos());
}
#endif
QWidget::mouseMoveEvent(event);
}

Expand Down
123 changes: 123 additions & 0 deletions src/event_monitor.cpp
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);
}
}

66 changes: 66 additions & 0 deletions src/event_monitor.h
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
55 changes: 55 additions & 0 deletions src/event_relayer.cpp
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;
}

}

31 changes: 31 additions & 0 deletions src/event_relayer.h
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 */
Loading

0 comments on commit fb690c9

Please sign in to comment.