-
-
Notifications
You must be signed in to change notification settings - Fork 76
Description
Describe the bug
In pure VTK, mouse press/release events are triggered regardless of whether another mouse button is currently pressed. For example, a "LeftButtonPressEvent", "RightButtonPressEvent", "LeftButtonReleaseEvent", and "RightButtonReleaseEvent" can all be recorded in sequence. However, when using a VTK render window within Trame, button press/release events are not triggered if another mouse button is currently pressed. In the above example, the "RightButtonPressEvent" is not triggered (since the left button is pressed), the "LeftButtonReleaseEvent" is not triggered (since the right button is pressed), and the "RightButtonReleaseEvent" is not triggered (presumably since the right press was never registered).
To Reproduce
- I'm using a freshly created
uvenvironment; version bounds from mypyproject.tomlas follows:
dependencies = [
"trame-vtk>=2.9.1",
"trame-vuetify>=3.0.3",
"trame>=3.12.0",
"vtk>=9.5.1",
]- Run the script copied below passing "trame" as the argument:
./test_multibutton_comparison.py trame- In the VTK render window that opens within the browser, press the left button, drag, press the right button, drag, release the left button, drag, release the right button, drag. You will get an output similar to the following, with the mouse left in the "drag" state, though no buttons are depressed:
LEFT BUTTON PRESS
DRAG: L=True R=False delta=[0,0]
DRAG: L=True R=False delta=[113,237]
DRAG: L=True R=False delta=[0,0]
DRAG: L=True R=False delta=[-1,0]
DRAG: L=True R=False delta=[-2,0]
DRAG: L=True R=False delta=[-1,-1]
DRAG: L=True R=False delta=[0,0]
DRAG: L=True R=False delta=[-1,0]
DRAG: L=True R=False delta=[-3,-1]
DRAG: L=True R=False delta=[-9,-8]
DRAG: L=True R=False delta=[-1,-2]
DRAG: L=True R=False delta=[-2,-4]
DRAG: L=True R=False delta=[-2,-3]In order to "release" the mouse, you need to press and release the left mouse button again.
Code
#!/usr/bin/env python3
"""
Multi-button test comparison: VTK vs Trame
Usage:
./test_multibutton_comparison.py vtk # Native VTK (multi-button works)
./test_multibutton_comparison.py trame # Trame/web (multi-button blocked)
"""
import sys
import vtk
class MultiButtonInteractor(vtk.vtkInteractorStyle):
def __init__(self):
super().__init__()
self.left_button_down = False
self.right_button_down = False
self.last_mouse_pos = [0, 0]
self.AddObserver("LeftButtonPressEvent", self.on_left_press)
self.AddObserver("LeftButtonReleaseEvent", self.on_left_release)
self.AddObserver("RightButtonPressEvent", self.on_right_press)
self.AddObserver("RightButtonReleaseEvent", self.on_right_release)
self.AddObserver("MouseMoveEvent", self.on_mouse_move)
def on_left_press(self, obj, event):
print("LEFT BUTTON PRESS")
self.left_button_down = True
interactor = self.GetInteractor()
if interactor:
self.last_mouse_pos = list(interactor.GetEventPosition())
def on_left_release(self, obj, event):
print("LEFT BUTTON RELEASE")
self.left_button_down = False
def on_right_press(self, obj, event):
print("RIGHT BUTTON PRESS")
self.right_button_down = True
interactor = self.GetInteractor()
if interactor:
self.last_mouse_pos = list(interactor.GetEventPosition())
def on_right_release(self, obj, event):
print("RIGHT BUTTON RELEASE")
self.right_button_down = False
def on_mouse_move(self, obj, event):
if self.left_button_down or self.right_button_down:
interactor = self.GetInteractor()
if interactor:
current_pos = list(interactor.GetEventPosition())
dx = current_pos[0] - self.last_mouse_pos[0]
dy = current_pos[1] - self.last_mouse_pos[1]
self.last_mouse_pos = current_pos
print(
f"DRAG: L={self.left_button_down} R={self.right_button_down} delta=[{dx},{dy}]"
)
if self.left_button_down and self.right_button_down:
print(" *** LEFT+RIGHT COMBINATION DETECTED! ***")
def create_vtk_scene():
"""Shared VTK scene setup"""
renderer = vtk.vtkRenderer()
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)
style = MultiButtonInteractor()
interactor.SetInteractorStyle(style)
return renderer, render_window, interactor
def run_mode(mode):
if mode == "vtk":
print("=== VTK MODE (Native) ===")
print("Multi-button combinations SHOULD work")
print("Try: Left-drag, then add Right button while dragging")
print("")
renderer, render_window, interactor = create_vtk_scene()
render_window.SetWindowName("VTK Mode - Multi-button should work")
interactor.Initialize()
render_window.Render()
interactor.Start()
elif mode == "trame":
print("=== TRAME MODE (Web) ===")
print("Multi-button combinations should be BLOCKED")
print("Try: Left-drag, then add Right button while dragging")
print("Opening browser...")
print("")
from trame.app import get_server
from trame.ui.vuetify3 import SinglePageLayout
from trame.widgets import vtk as vtk_widgets
server = get_server()
renderer, render_window, interactor = create_vtk_scene()
render_window.SetOffScreenRendering(True)
with SinglePageLayout(server) as layout:
layout.title.set_text("Trame Mode - Multi-button should be blocked")
with layout.content:
vtk_widgets.VtkRemoteView(render_window)
server.start()
def main():
if len(sys.argv) != 2 or sys.argv[1] not in ['vtk', 'trame']:
print("Usage:")
print(" python test_multibutton_comparison.py vtk # Native VTK")
print(" python test_multibutton_comparison.py trame # Trame/web")
print("")
print("This demonstrates the difference in multi-button behavior:")
print(" VTK: Multi-button combinations work")
print(" Trame: Multi-button combinations blocked by browser")
sys.exit(1)
mode = sys.argv[1]
run_mode(mode)
if __name__ == "__main__":
main()Expected behavior
- To see the expected behavior, run the pure VTK version of the same script by passing the "vtk" argument:
./test_multibutton_comparison.py vtk- In the VTK render window that opens, follow the same steps: press the left button, drag, press the right button, drag, release the left button, drag, release the right button, drag. You will get the expected output similar to the following:
LEFT BUTTON PRESS
DRAG: L=True R=False delta=[0,0]
DRAG: L=True R=False delta=[0,-1]
RIGHT BUTTON PRESS
DRAG: L=True R=True delta=[0,-1]
*** LEFT+RIGHT COMBINATION DETECTED! ***
DRAG: L=True R=True delta=[0,-1]
*** LEFT+RIGHT COMBINATION DETECTED! ***
LEFT BUTTON RELEASE
DRAG: L=False R=True delta=[0,0]
DRAG: L=False R=True delta=[0,-1]
RIGHT BUTTON RELEASEScreenshots
N/A
Platform:
Device:
- Desktop
- Mobile => Not tested
OS:
- Windows => Not tested
- MacOS
- Linux
- Android => Not tested
- iOS => Not tested
Browsers Affected:
- Chrome
- Firefox
- Microsoft Edge => Not tested
- Safari
- Opera => Not tested
- Brave
- IE 11 => Not tested