Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_window.c')
-rw-r--r--source/blender/windowmanager/intern/wm_window.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 4f7e5ab75b3..98766f35006 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1097,6 +1097,76 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
return 1;
}
+/**
+ * #KM_DBL_CLICK is set in wm_event_clicktype_init (wm_event_system.c)
+ * Normally, this should be there too, but for #KM_CLICK/#KM_HOLD, we need a
+ * time precision of a few milliseconds, which we can't get from there
+ */
+static void wm_window_event_clicktype_init(const bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ if (wm->winactive) {
+ wmWindow *win = wm->winactive;
+ wmEvent *event = win->eventstate;
+ short click_type = event->click_type;
+
+ BLI_assert(event != NULL);
+
+ if ((event->type == EVENT_NONE) ||
+ ((event->val == KM_NOTHING) && (event->is_key_pressed == false)))
+ {
+ /* nothing needs to be done here */
+ return;
+ }
+
+ /* we always want click_type of last clicked button (to enable
+ * use with modifier keys) - unnecessary for mouse though */
+ if (!ISMOUSE(event->type) &&
+ event->val == KM_PRESS &&
+ event->type != event->keymodifier)
+ {
+ event->is_key_pressed = false;
+ }
+ else if (event->val == KM_PRESS && !event->is_key_pressed) {
+ event->is_key_pressed = true;
+ event->click_time = PIL_check_seconds_timer();
+ }
+ else if (event->val == KM_RELEASE && event->is_key_pressed) {
+ event->is_key_pressed = false;
+ }
+ else if (event->is_key_pressed == false) {
+ return;
+ }
+
+ /* the actual test */
+ if ((PIL_check_seconds_timer() - event->click_time) * 1000 <= U.click_timeout) {
+ /* for any reason some X11 systems send two release events triggering two KM_CLICK
+ * events - making the rules more strict by checking for prevval resolves this */
+ if (event->val == KM_RELEASE && event->prevval != KM_RELEASE) {
+ click_type = KM_CLICK;
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS)) {
+ printf("%s Send click event\n", __func__);
+ }
+ }
+ }
+ else if (event->is_key_pressed) {
+ click_type = KM_HOLD;
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS)) {
+ printf("%s Send hold event\n", __func__);
+ }
+
+ /* the event we send in this case is a "dummy" event - don't send value */
+ event->val = KM_NOTHING;
+ }
+
+ /* send event with new click_type */
+ if (event->click_type != click_type) {
+ event->click_type = click_type;
+ wm_event_add(win, event);
+ }
+ }
+}
/* This timer system only gives maximum 1 timer event per redraw cycle,
* to prevent queues to get overloaded.
@@ -1156,7 +1226,11 @@ void wm_window_process_events(const bContext *C)
if (hasevent)
GHOST_DispatchEvents(g_system);
-
+
+ /* not nice to have this here, but it's the only place
+ * that can call it with the needed time precision */
+ wm_window_event_clicktype_init(C);
+
hasevent |= wm_window_timer(C);
/* no event, we sleep 5 milliseconds */