From cebbfe3f6ffad753b5a0be27933ebea66b7dc223 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 15 Feb 2015 08:57:23 -0600 Subject: [PATCH 1/4] Add guiEvent handling for web backends --- lib/matplotlib/backends/backend_webagg_core.py | 15 ++++++++------- lib/matplotlib/backends/web_backend/mpl.js | 6 ++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index 531fce3ada7c..e83be9d2d1c0 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -290,6 +290,7 @@ def handle_event(self, event): # Javascript button numbers and matplotlib button numbers are # off by 1 button = event['button'] + 1 + guiEvent = event['guiEvent'] # The right mouse button pops up a context menu, which # doesn't work very well, so use the middle mouse button @@ -299,23 +300,23 @@ def handle_event(self, event): button = 3 if e_type == 'button_press': - self.button_press_event(x, y, button) + self.button_press_event(x, y, button, guiEvent=guiEvent) elif e_type == 'button_release': - self.button_release_event(x, y, button) + self.button_release_event(x, y, button, guiEvent=guiEvent) elif e_type == 'motion_notify': - self.motion_notify_event(x, y) + self.motion_notify_event(x, y, guiEvent=guiEvent) elif e_type == 'figure_enter': - self.enter_notify_event(xy=(x, y)) + self.enter_notify_event(xy=(x, y), guiEvent=guiEvent) elif e_type == 'figure_leave': self.leave_notify_event() elif e_type == 'scroll': - self.scroll_event(x, y, event['step']) + self.scroll_event(x, y, event['step'], guiEvent=guiEvent) elif e_type in ('key_press', 'key_release'): key = _handle_key(event['key']) if e_type == 'key_press': - self.key_press_event(key) + self.key_press_event(key, guiEvent=guiEvent) elif e_type == 'key_release': - self.key_release_event(key) + self.key_release_event(key, guiEvent=guiEvent) elif e_type == 'toolbar_button': # TODO: Be more suspicious of the input getattr(self.toolbar, event['name'])() diff --git a/lib/matplotlib/backends/web_backend/mpl.js b/lib/matplotlib/backends/web_backend/mpl.js index 246315084040..15bbbdbbc03c 100644 --- a/lib/matplotlib/backends/web_backend/mpl.js +++ b/lib/matplotlib/backends/web_backend/mpl.js @@ -467,7 +467,8 @@ mpl.figure.prototype.mouse_event = function(event, name) { var y = canvas_pos.y; this.send_message(name, {x: x, y: y, button: event.button, - step: event.step}); + step: event.step, + guiEvent: event}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want @@ -507,7 +508,8 @@ mpl.figure.prototype.key_event = function(event, name) { this._key_event_extra(event, name); - this.send_message(name, {key: value}); + this.send_message(name, {key: value, + guiEvent: event}); return false; } From a89ec047ded2c9d561e4428f5c38cc2309b070f3 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 15 Feb 2015 09:23:14 -0600 Subject: [PATCH 2/4] Fix handling of circular references --- lib/matplotlib/backends/backend_webagg_core.py | 3 ++- lib/matplotlib/backends/web_backend/mpl.js | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index e83be9d2d1c0..69088dcc3357 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -271,6 +271,8 @@ def get_renderer(self, cleared=None): def handle_event(self, event): e_type = event['type'] + guiEvent = event.get('guiEvent', None) + if e_type == 'ack': # Network latency tends to decrease if traffic is flowing # in both directions. Therefore, the browser sends back @@ -290,7 +292,6 @@ def handle_event(self, event): # Javascript button numbers and matplotlib button numbers are # off by 1 button = event['button'] + 1 - guiEvent = event['guiEvent'] # The right mouse button pops up a context menu, which # doesn't work very well, so use the middle mouse button diff --git a/lib/matplotlib/backends/web_backend/mpl.js b/lib/matplotlib/backends/web_backend/mpl.js index 15bbbdbbc03c..1897dfddbe6a 100644 --- a/lib/matplotlib/backends/web_backend/mpl.js +++ b/lib/matplotlib/backends/web_backend/mpl.js @@ -454,6 +454,18 @@ mpl.findpos = function(e) { return {"x": x, "y": y}; }; +/* + * return a copy of an object with only non-object keys + * we need this to avoid circular references + * http://stackoverflow.com/a/24161582/3208463 + */ +function simpleKeys (original) { + return Object.keys(original).reduce(function (obj, key) { + obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key]; + return obj; + }, {}); +} + mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) @@ -468,7 +480,7 @@ mpl.figure.prototype.mouse_event = function(event, name) { this.send_message(name, {x: x, y: y, button: event.button, step: event.step, - guiEvent: event}); + guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want @@ -509,7 +521,7 @@ mpl.figure.prototype.key_event = function(event, name) { this._key_event_extra(event, name); this.send_message(name, {key: value, - guiEvent: event}); + guiEvent: simpleKeys(event)}); return false; } From 8b24a30bf63c53e6478f39532328c82e0da51bcb Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 15 Feb 2015 09:29:55 -0600 Subject: [PATCH 3/4] Add the originalEvent info --- lib/matplotlib/backends/web_backend/mpl.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/web_backend/mpl.js b/lib/matplotlib/backends/web_backend/mpl.js index 1897dfddbe6a..8de0e4a137e6 100644 --- a/lib/matplotlib/backends/web_backend/mpl.js +++ b/lib/matplotlib/backends/web_backend/mpl.js @@ -477,10 +477,12 @@ mpl.figure.prototype.mouse_event = function(event, name) { var x = canvas_pos.x; var y = canvas_pos.y; + var guiEvent = simpleKeys(event); + guiEvent.originalEvent = simpleKeys(event.originalEvent); this.send_message(name, {x: x, y: y, button: event.button, step: event.step, - guiEvent: simpleKeys(event)}); + guiEvent: guiEvent}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want @@ -520,8 +522,12 @@ mpl.figure.prototype.key_event = function(event, name) { this._key_event_extra(event, name); + var guiEvent = simpleKeys(event); + + guiEvent.originalEvent = simpleKeys(event.originalEvent); + this.send_message(name, {key: value, - guiEvent: simpleKeys(event)}); + guiEvent: guiEvent}); return false; } From 0c3416d8a9edae7967d3cb167bea545cb061de49 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 15 Feb 2015 22:38:06 -0600 Subject: [PATCH 4/4] Remove all nested objects --- lib/matplotlib/backends/web_backend/mpl.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/backends/web_backend/mpl.js b/lib/matplotlib/backends/web_backend/mpl.js index 8de0e4a137e6..3a98aafaf9ec 100644 --- a/lib/matplotlib/backends/web_backend/mpl.js +++ b/lib/matplotlib/backends/web_backend/mpl.js @@ -461,7 +461,8 @@ mpl.findpos = function(e) { */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { - obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key]; + if (typeof original[key] !== 'object') + obj[key] = original[key] return obj; }, {}); } @@ -477,12 +478,10 @@ mpl.figure.prototype.mouse_event = function(event, name) { var x = canvas_pos.x; var y = canvas_pos.y; - var guiEvent = simpleKeys(event); - guiEvent.originalEvent = simpleKeys(event.originalEvent); this.send_message(name, {x: x, y: y, button: event.button, step: event.step, - guiEvent: guiEvent}); + guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want @@ -522,12 +521,8 @@ mpl.figure.prototype.key_event = function(event, name) { this._key_event_extra(event, name); - var guiEvent = simpleKeys(event); - - guiEvent.originalEvent = simpleKeys(event.originalEvent); - this.send_message(name, {key: value, - guiEvent: guiEvent}); + guiEvent: simpleKeys(event)}); return false; }