JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.15k stars 1.17k forks source link

Linux: PointerButtons.isBackPressed wrongly mapped #2058

Closed wgryglas closed 1 month ago

wgryglas commented 2 years ago

System: Elementary OS, based on Ubuntu 18.04LTS Compose: 1.1.1 Kotlin: 1.6.10 JVM: openjdk-18, java version 18.0.1


On my Linux and the mouse Logitech MX Master 3 the typical "Back" button is not recognized. However, when scrolling up with the mouse's horizontal scroll wheel (not the regular wheel one, but the additional) isBackPressed is fired.

Box(
    modifier = Modifier.mouseClickable {
        //it looks like it doesn't work with my mouse mx master 3 - side roller up causes back press
        if (buttons.isBackPressed) {
            ......
        }
    }
) 

It doesn't look like a system mapping problem, because both Chrome and the system file manager recognize this button click correctly.

When tested by my friend with another Logitech mouse (MX Vertical) on Windows the isBackPressed works as expected with the above code.

I have checked what button id is assigned when pressed in a Swing window:

fun main() {
    val frame = JFrame()
    frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
    val label = JLabel("Press any button")
    val panel = JPanel(BorderLayout()).apply {
        add(label, BorderLayout.CENTER)
    }
    panel.addMouseListener(object : MouseAdapter() {
        override fun mousePressed(e: MouseEvent) {
            label.text = "Pressed ${e.button}"
        }
    })
    frame.contentPane = panel
    frame.size = Dimension(600, 600)
    frame.isVisible = true
}

Below you can find the summary of my clicks:

  1. Regular Primary: Pressed 1
  2. Regular Secondary: Pressed 3
  3. Middle Scroll Down press: Pressed 2
  4. The horizontal roller "forward" (roll up): Pressed 4
  5. The horizontal roller "backward" (roll down): Pressed 5
  6. Back button: Pressed 6
  7. Forward button: Pressed 7

It looks like the this is potentially related rather to Swing, as Compse directly maps the number 4 to the "Back" button.

eygraber commented 1 year ago

I tried this in 1.3.0-beta03 on Ubuntu 22.04 with an MX Master 3 but using the onClick(matcher = ...) modifier.

Here's what I found:

onClick(matcher = PointerMatcher.mouse(PointerButton(0)), onClick = { println("Mouse Left") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(1)), onClick = { println("Mouse Right") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(2)), onClick = { println("Mouse Middle") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(3)), onClick = { println("Horizontal Scroll Right") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(4)), onClick = { println("Horizontal Scroll Left") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(5)), onClick = { println("Mouse Back") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(6)), onClick = { println("Mouse Front") })
    .onClick(matcher = PointerMatcher.mouse(PointerButton(7)), onClick = { println("Mouse Thumb") })
cjbrooks12 commented 1 year ago

I tried @eygraber 's longer snippet posted in the Kotlin slack threa, and here are some of my findings:

OS: Macos Monterey (12.6) Kotlin version: 1.7.20 Compose Desktop version: 1.2.1 Mouse: Logi MX Master 3, using Logi Options+ software, connected via Bluetooth Forward and back thumb buttons configured with default "Forward" and "Back" actions in Logi Options+

When clicking either the forward or back buttons on the mouse, I see an exception in native code, with the following stacktrace:

2022-12-02 10:57:34.732 java[95524:7042215] Bad JNI lookup handleGestureFromNative
2022-12-02 10:57:34.733 java[95524:7042215] (
    0   libawt_lwawt.dylib                  0x000000013f115ab4 -[AWTWindow_Normal postGesture:as:a:b:] + 963
    1   AppKit                              0x00007ff809fc02e8 forwardMethod + 204
    2   AppKit                              0x00007ff809f3bf56 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 7150
    3   AppKit                              0x00007ff809f3a14e -[NSWindow(NSEventRouting) sendEvent:] + 352
    4   libawt_lwawt.dylib                  0x000000013f1156e4 -[AWTWindow_Normal sendEvent:] + 86
    5   AppKit                              0x00007ff80a51efb4 routeGestureEvent + 389
    6   AppKit                              0x00007ff809f38efa -[NSApplication(NSEvent) sendEvent:] + 2870
    7   libosxapp.dylib                     0x000000010fbf28ab -[NSApplicationAWT sendEvent:] + 449
    8   AppKit                              0x00007ff80a1f118b -[NSApplication _handleEvent:] + 65
    9   AppKit                              0x00007ff809db9d3e -[NSApplication run] + 623
    10  libosxapp.dylib                     0x000000010fbf2519 +[NSApplicationAWT runAWTLoopWithApp:] + 269
    11  libawt_lwawt.dylib                  0x000000013f166967 +[AWTStarter starter:headless:] + 511
    12  libosxapp.dylib                     0x000000010fbf4059 +[ThreadUtilities invokeBlockCopy:] + 15
    13  Foundation                          0x00007ff80820e527 __NSThreadPerformPerform + 179
    14  CoreFoundation                      0x00007ff80739117b __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    15  CoreFoundation                      0x00007ff8073910e3 __CFRunLoopDoSource0 + 180
    16  CoreFoundation                      0x00007ff807390e5d __CFRunLoopDoSources0 + 242
    17  CoreFoundation                      0x00007ff80738f878 __CFRunLoopRun + 892
    18  CoreFoundation                      0x00007ff80738ee3c CFRunLoopRunSpecific + 562
    19  libjli.dylib                        0x000000010ef1864e CreateExecutionEnvironment + 398
    20  libjli.dylib                        0x000000010ef1485e JLI_Launch + 1322
    21  java                                0x000000010edf3807 main + 375
    22  dyld                                0x0000000113b1452e start + 462
)
Exception in thread "AppKit Thread" java.lang.NoSuchMethodError: handleGestureFromNative

If I configure the forward/back mouse buttons to other actions in Logi Options+ (for example, mapping them to a left, right, or middle mouse button click), they those actions are handled correctly in the Compose Desktop application.

eygraber commented 1 year ago

I tried the same thing without Logi Options+ on a Mac and the back and forward buttons triggered the horizontal scroll events.

eygraber commented 1 year ago

Here's a spreadsheet where I'm tracking the values on the different OSes (so far only have Logitech mice; trying to get some more).

eygraber commented 9 months ago

Just tried this again with Compose 1.6 alpha and Mouse Back and Mouse Forward are not fired on Linux.

eygraber commented 9 months ago

I can get codes for them using:

onPointerEvent(
  eventType = PointerEventType.Press,
  pass = PointerEventPass.Initial,
  onEvent = {}
)
eygraber commented 9 months ago

Update: I can get Mouse Back Forward and Thumb to fire if Mouse Left Right or Middle are being held down.

okushnikov commented 3 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.