Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mousemove events not emitted after shift+mousedown with button 1 in Jupyter Lab #74

Open
edwardwkrohne opened this issue Oct 7, 2022 · 4 comments

Comments

@edwardwkrohne
Copy link

edwardwkrohne commented Oct 7, 2022

I'm trying to allow the user to "draw" a line across a widget, and have the shift key have special meaning. I check mousemove events with button 1 depressed to do regular drawing, but for shift+draw, no events are emitted by ipyevents.

The following code has been modified from the example notebook.

from ipywidgets import Label, HTML, HBox, Image, VBox, Box, HBox
from ipyevents import Event 
from IPython.display import display

l = Label('Move the mouse across me!')
l.layout.border = '2px solid red'

h = HTML('Event info')
d = Event(source=l, watched_events=['mousemove'])

def handle_event(event):
    lines = ['{}: {}'.format(k, v) for k, v in event.items()]
    content = '<br>'.join(lines)
    h.value = content

d.on_dom_event(handle_event)
                            
display(l, h)

In Jupyter Lab,

  • Mouse moves with no buttons depressed are displayed.
  • Mouse moves with mouse button 1 depressed are displayed.
  • Mouse moves with the shift key depressed are displayed.
  • Mouse moves with shift and button 1 depressed, where shift went down before button 1, are not displayed. Releasing the shift key while leaving the mouse button down does not make mouse moves visible.
  • Mouse moves with shift and button 1 depressed, where the mouse button went down before shift are displayed.
  • Mouse moves with mouse button 2 depressed are displayed irrespective of the shift key.

In Jupyter Notebook, all events I just listed are displayed appropriately. Adding prevent_default_action=True had no effect.

!jupyter --version

produces

Selected Jupyter core packages...
IPython          : 8.3.0
ipykernel        : 6.13.0
ipywidgets       : 7.7.0
jupyter_client   : 7.3.1
jupyter_core     : 4.10.0
jupyter_server   : 1.17.0
jupyterlab       : 3.5.0b0
nbclient         : 0.6.3
nbconvert        : 6.5.0
nbformat         : 5.4.0
notebook         : 6.4.11
qtconsole        : 5.3.0
traitlets        : 5.2.1.post0

and

import ipyevents
ipyevents.__version__

produces

'2.0.1'

I upgraded from JupyterLab 3.4.0 to make this report; I got identical behavior in both versions.

@mwcraig
Copy link
Owner

mwcraig commented Oct 18, 2022

Thanks for the report @edwardwkrohne -- I'm hoping to fix it this week while I'm at a workshop with some jupyterlab devs.

@mwcraig
Copy link
Owner

mwcraig commented Oct 19, 2022

With some help from Afshin Darian I found the root cause of this. It turns out the notebook in JupyterLab captures mousemove events when

  • the shift key is pressed and
  • the cursor is not over an input cell and
  • the left mouse button is pressed.

This happens on the mousedown event, which is why the order of pressing the shift key matters: if you are not holding the shift key when you press the left mouse button then the event capture does not happen. If you have selected some text before pushing the shift key it also doesn't happen.

There is not a great workaround, though Darian said jupyterlab might be willing to add an API for turning off the event capture in this case.

I'm not sure why jupyterlab grabs this case beyond this comment.

I'll try to think of a workaround in ipyevents, though it would be a little hacky and I'm not sure I can actually get it to work, or what it might break...

@edwardwkrohne
Copy link
Author

Thank you! This is great to know.

Since you've read the code surrounding this already, what do you think my odds would be if I were to make a source install of JupyterLab and comment out that one line? Would it be sufficient to do shift+draw? Would it have unpleasant consequences? Looking at the blame and the PR the line was written at, it was added to address things like browser context menus showing up when the Jupyter one needed to be shown.

@mwcraig
Copy link
Owner

mwcraig commented Oct 24, 2022

With the caveat that I'm not an expert in this code base, I think the line that prevents the event from getting to ipyevents is here: https://github.com/jupyterlab/jupyterlab/blob/4b8f2de55ee74754920c675140153d51ded985ab/packages/notebook/src/widget.ts#L2217

That said, commenting out the stopPropagation might well break drag-and-drop of notebook tabs and stuff.

One thought would be to move the stopPopagation inside the switch statement.

Another thought, which would mean not having to modify jupyterlab itself, would be to select some text in the output cell whenever the mouse enters the element that ipyevents is attached to. If something is selected when this conditional is hit, then that branch is not entered, and the mousemove listener that stops propagation isn't added.

I don't of a great way to make that selection happen, though I think it will have to be on the js side, not the python side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants