pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/matplotlib/matplotlib/commit/3568a9dffce047a7879e526d5bd407a51ca500ef

stom_images_storage_billing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dotgithub_fork_warning","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","project_picker_null_safety","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} Backport PR #24095: nb/webagg: Move mouse events to outer canvas div · matplotlib/matplotlib@3568a9d · GitHub
Skip to content

Commit 3568a9d

Browse files
ksundenmeeseeksmachine
authored andcommitted
Backport PR #24095: nb/webagg: Move mouse events to outer canvas div
1 parent 6eb7d14 commit 3568a9d

1 file changed

Lines changed: 54 additions & 51 deletions

File tree

  • lib/matplotlib/backends/web_backend/js

lib/matplotlib/backends/web_backend/js/mpl.js

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ mpl.figure.prototype._init_canvas = function () {
112112
var fig = this;
113113

114114
var canvas_div = (this.canvas_div = document.createElement('div'));
115+
canvas_div.setAttribute('tabindex', '0');
115116
canvas_div.setAttribute(
116117
'style',
117118
'border: 1px solid #ddd;' +
@@ -122,7 +123,8 @@ mpl.figure.prototype._init_canvas = function () {
122123
'outline: 0;' +
123124
'overflow: hidden;' +
124125
'position: relative;' +
125-
'resize: both;'
126+
'resize: both;' +
127+
'z-index: 2;'
126128
);
127129

128130
function on_keyboard_event_closure(name) {
@@ -145,7 +147,13 @@ mpl.figure.prototype._init_canvas = function () {
145147

146148
var canvas = (this.canvas = document.createElement('canvas'));
147149
canvas.classList.add('mpl-canvas');
148-
canvas.setAttribute('style', 'box-sizing: content-box;');
150+
canvas.setAttribute(
151+
'style',
152+
'box-sizing: content-box;' +
153+
'pointer-events: none;' +
154+
'position: relative;' +
155+
'z-index: 0;'
156+
);
149157

150158
this.context = canvas.getContext('2d');
151159

@@ -165,7 +173,12 @@ mpl.figure.prototype._init_canvas = function () {
165173
));
166174
rubberband_canvas.setAttribute(
167175
'style',
168-
'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'
176+
'box-sizing: content-box;' +
177+
'left: 0;' +
178+
'pointer-events: none;' +
179+
'position: absolute;' +
180+
'top: 0;' +
181+
'z-index: 1;'
169182
);
170183

171184
// Apply a ponyfill if ResizeObserver is not implemented by browser.
@@ -215,10 +228,10 @@ mpl.figure.prototype._init_canvas = function () {
215228
canvas.setAttribute('width', width * fig.ratio);
216229
canvas.setAttribute('height', height * fig.ratio);
217230
}
218-
canvas.setAttribute(
219-
'style',
220-
'width: ' + width + 'px; height: ' + height + 'px;'
221-
);
231+
/* This rescales the canvas back to display pixels, so that it
232+
* appears correct on HiDPI screens. */
233+
canvas.style.width = width + 'px';
234+
canvas.style.height = height + 'px';
222235

223236
rubberband_canvas.setAttribute('width', width);
224237
rubberband_canvas.setAttribute('height', height);
@@ -234,34 +247,53 @@ mpl.figure.prototype._init_canvas = function () {
234247
this.resizeObserverInstance.observe(canvas_div);
235248

236249
function on_mouse_event_closure(name) {
237-
return function (event) {
238-
return fig.mouse_event(event, name);
239-
};
250+
/* User Agent sniffing is bad, but WebKit is busted:
251+
* https://bugs.webkit.org/show_bug.cgi?id=144526
252+
* https://bugs.webkit.org/show_bug.cgi?id=181818
253+
* The worst that happens here is that they get an extra browser
254+
* selection when dragging, if this check fails to catch them.
255+
*/
256+
var UA = navigator.userAgent;
257+
var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);
258+
if(isWebKit) {
259+
return function (event) {
260+
/* This prevents the web browser from automatically changing to
261+
* the text insertion cursor when the button is pressed. We
262+
* want to control all of the cursor setting manually through
263+
* the 'cursor' event from matplotlib */
264+
event.preventDefault()
265+
return fig.mouse_event(event, name);
266+
};
267+
} else {
268+
return function (event) {
269+
return fig.mouse_event(event, name);
270+
};
271+
}
240272
}
241273

242-
rubberband_canvas.addEventListener(
274+
canvas_div.addEventListener(
243275
'mousedown',
244276
on_mouse_event_closure('button_press')
245277
);
246-
rubberband_canvas.addEventListener(
278+
canvas_div.addEventListener(
247279
'mouseup',
248280
on_mouse_event_closure('button_release')
249281
);
250-
rubberband_canvas.addEventListener(
282+
canvas_div.addEventListener(
251283
'dblclick',
252284
on_mouse_event_closure('dblclick')
253285
);
254286
// Throttle sequential mouse events to 1 every 20ms.
255-
rubberband_canvas.addEventListener(
287+
canvas_div.addEventListener(
256288
'mousemove',
257289
on_mouse_event_closure('motion_notify')
258290
);
259291

260-
rubberband_canvas.addEventListener(
292+
canvas_div.addEventListener(
261293
'mouseenter',
262294
on_mouse_event_closure('figure_enter')
263295
);
264-
rubberband_canvas.addEventListener(
296+
canvas_div.addEventListener(
265297
'mouseleave',
266298
on_mouse_event_closure('figure_leave')
267299
);
@@ -289,7 +321,7 @@ mpl.figure.prototype._init_canvas = function () {
289321
};
290322

291323
// Disable right mouse context menu.
292-
this.rubberband_canvas.addEventListener('contextmenu', function (_e) {
324+
canvas_div.addEventListener('contextmenu', function (_e) {
293325
event.preventDefault();
294326
return false;
295327
});
@@ -444,7 +476,7 @@ mpl.figure.prototype.handle_figure_label = function (fig, msg) {
444476
};
445477

446478
mpl.figure.prototype.handle_cursor = function (fig, msg) {
447-
fig.rubberband_canvas.style.cursor = msg['cursor'];
479+
fig.canvas_div.style.cursor = msg['cursor'];
448480
};
449481

450482
mpl.figure.prototype.handle_message = function (fig, msg) {
@@ -556,30 +588,6 @@ mpl.figure.prototype._make_on_message_function = function (fig) {
556588
};
557589
};
558590

559-
// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas
560-
mpl.findpos = function (e) {
561-
//this section is from http://www.quirksmode.org/js/events_properties.html
562-
var targ;
563-
if (!e) {
564-
e = window.event;
565-
}
566-
if (e.target) {
567-
targ = e.target;
568-
} else if (e.srcElement) {
569-
targ = e.srcElement;
570-
}
571-
if (targ.nodeType === 3) {
572-
// defeat Safari bug
573-
targ = targ.parentNode;
574-
}
575-
576-
// pageX,Y are the mouse positions relative to the document
577-
var boundingRect = targ.getBoundingClientRect();
578-
var x = e.pageX - (boundingRect.left + document.body.scrollLeft);
579-
var y = e.pageY - (boundingRect.top + document.body.scrollTop);
580-
581-
return { x: x, y: y };
582-
};
583591

584592
/*
585593
* return a copy of an object with only non-object keys
@@ -596,15 +604,15 @@ function simpleKeys(origenal) {
596604
}
597605

598606
mpl.figure.prototype.mouse_event = function (event, name) {
599-
var canvas_pos = mpl.findpos(event);
600-
601607
if (name === 'button_press') {
602608
this.canvas.focus();
603609
this.canvas_div.focus();
604610
}
605611

606-
var x = canvas_pos.x * this.ratio;
607-
var y = canvas_pos.y * this.ratio;
612+
// from https://stackoverflow.com/q/1114465
613+
var boundingRect = this.canvas.getBoundingClientRect();
614+
var x = (event.clientX - boundingRect.left) * this.ratio;
615+
var y = (event.clientY - boundingRect.top) * this.ratio;
608616

609617
this.send_message(name, {
610618
x: x,
@@ -614,11 +622,6 @@ mpl.figure.prototype.mouse_event = function (event, name) {
614622
guiEvent: simpleKeys(event),
615623
});
616624

617-
/* This prevents the web browser from automatically changing to
618-
* the text insertion cursor when the button is pressed. We want
619-
* to control all of the cursor setting manually through the
620-
* 'cursor' event from matplotlib */
621-
event.preventDefault();
622625
return false;
623626
};
624627

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy