X11 backend: timers and custom events

This commit is contained in:
Vadim Lopatin 2015-12-02 11:19:26 +03:00
parent 5b9b130143
commit f691ec7bb3
1 changed files with 73 additions and 1 deletions

View File

@ -137,7 +137,7 @@ class X11Window : DWindow {
*/ */
XSelectInput(x11display, _win, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | XSelectInput(x11display, _win, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ExposureMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ExposureMask | VisibilityChangeMask |
FocusChangeMask | KeymapStateMask); FocusChangeMask | KeymapStateMask | StructureNotifyMask);
/* create the Graphics Context */ /* create the Graphics Context */
_gc = createGC(x11display, _win); _gc = createGC(x11display, _win);
@ -616,8 +616,48 @@ class X11Window : DWindow {
return res; return res;
} }
private long _nextExpectedTimerTs;
/// schedule timer for interval in milliseconds - call window.onTimer when finished
override protected void scheduleSystemTimer(long intervalMillis) {
if (intervalMillis < 10)
intervalMillis = 10;
long nextts = currentTimeMillis + intervalMillis;
if (!_nextExpectedTimerTs || _nextExpectedTimerTs > nextts)
_nextExpectedTimerTs = nextts;
} }
bool handleTimer() {
if (!_nextExpectedTimerTs)
return false;
long ts = currentTimeMillis;
if (ts >= _nextExpectedTimerTs) {
_nextExpectedTimerTs = 0;
onTimer();
return true;
}
return false;
}
/// post event to handle in UI thread (this method can be used from background thread)
override void postEvent(CustomEvent event) {
super.postEvent(event);
XEvent ev;
ev.type = ClientMessage;
ev.xclient.window = _win;
ev.xclient.format = CUSTOM_EVENT;
ev.xclient.data.l[0] = event.uniqueId;
XSendEvent(x11display, _win, false, StructureNotifyMask, &ev);
// SDL_Event sdlevent;
// sdlevent.user.type = USER_EVENT_ID;
// sdlevent.user.code = cast(int)event.uniqueId;
// sdlevent.user.windowID = windowId;
// SDL_PushEvent(&sdlevent);
}
}
private immutable int CUSTOM_EVENT = 32;
class X11Platform : Platform { class X11Platform : Platform {
this() { this() {
@ -659,12 +699,29 @@ class X11Platform : Platform {
_windowMap.remove((cast(X11Window)w)._win); _windowMap.remove((cast(X11Window)w)._win);
} }
bool handleTimers() {
bool handled = false;
bool needRestart = true;
while (needRestart) {
needRestart = false;
foreach(w; _windowMap) {
if (w.handleTimer()) {
needRestart = true;
handled = true;
break;
}
}
}
return handled;
}
/** /**
* Starts application message loop. * Starts application message loop.
* *
* When returned from this method, application is shutting down. * When returned from this method, application is shutting down.
*/ */
override int enterMessageLoop() { override int enterMessageLoop() {
import core.thread;
XEvent event; /* the XEvent declaration !!! */ XEvent event; /* the XEvent declaration !!! */
KeySym key; /* a dealie-bob to handle KeyPress Events */ KeySym key; /* a dealie-bob to handle KeyPress Events */
char[255] text; /* a char buffer for KeyPress Events */ char[255] text; /* a char buffer for KeyPress Events */
@ -677,6 +734,10 @@ class X11Platform : Platform {
/* get the next event and stuff it into our event variable. /* get the next event and stuff it into our event variable.
Note: only events we set the mask for are detected! Note: only events we set the mask for are detected!
*/ */
if (!XPending(x11display) && !handleTimers()) {
Thread.sleep(dur!("msecs")(10));
continue;
}
XNextEvent(x11display, &event); XNextEvent(x11display, &event);
switch (event.type) { switch (event.type) {
@ -872,6 +933,17 @@ class X11Platform : Platform {
Log.e("Window not found"); Log.e("Window not found");
} }
break; break;
case ClientMessage:
Log.d("X11: ClientMessage event");
X11Window w = findWindow(event.xclient.window);
if (w) {
if (event.xclient.format == CUSTOM_EVENT) {
w.handlePostedEvent(cast(uint)event.xclient.data.l[0]);
}
} else {
Log.e("Window not found");
}
break;
default: default:
break; break;
} }