| 1566 | } |
| 1567 | |
| 1568 | void handle_events(fd_set *fdset) override |
| 1569 | { |
| 1570 | if (!FD_ISSET(display_fd, fdset)) |
| 1571 | return; |
| 1572 | |
| 1573 | while (XEventsQueued(display, QueuedAfterFlush) > 0) { |
| 1574 | XEvent event; |
| 1575 | XNextEvent(display, &event); |
| 1576 | |
| 1577 | switch (event.type) { |
| 1578 | case EnterNotify: |
| 1579 | if (xwayland && !motion_received) { |
| 1580 | // XWayland sends spurious EnterNotify events when the pointer is outside the |
| 1581 | // window at start but was inside it in a previous run due to a XWarpPointer() |
| 1582 | // or similar calls. Ignore those events until a MotionNotify is received first. |
| 1583 | break; |
| 1584 | } |
| 1585 | |
| 1586 | mouse_last_x = (s16)event.xcrossing.x; |
| 1587 | mouse_last_y = (s16)event.xcrossing.y; |
| 1588 | queue.push_axis_event(InputDeviceType::MOUSE |
| 1589 | , 0 |
| 1590 | , MouseAxis::CURSOR |
| 1591 | , event.xcrossing.x |
| 1592 | , event.xcrossing.y |
| 1593 | , 0 |
| 1594 | ); |
| 1595 | break; |
| 1596 | |
| 1597 | case LeaveNotify: |
| 1598 | cursor_inside_window = false; |
| 1599 | motion_received = false; |
| 1600 | break; |
| 1601 | |
| 1602 | case ClientMessage: |
| 1603 | if ((Atom)event.xclient.data.l[0] == wm_delete_window) |
| 1604 | queue.push_exit_event(); |
| 1605 | break; |
| 1606 | |
| 1607 | case ConfigureNotify: |
| 1608 | queue.push_resolution_event(event.xconfigure.width |
| 1609 | , event.xconfigure.height |
| 1610 | ); |
| 1611 | break; |
| 1612 | |
| 1613 | case ButtonPress: |
| 1614 | case ButtonRelease: { |
| 1615 | if (event.xbutton.button == Button4 || event.xbutton.button == Button5) { |
| 1616 | queue.push_axis_event(InputDeviceType::MOUSE |
| 1617 | , 0 |
| 1618 | , MouseAxis::WHEEL |
| 1619 | , 0 |
| 1620 | , event.xbutton.button == Button4 ? 1 : -1 |
| 1621 | , 0 |
| 1622 | ); |
| 1623 | break; |
| 1624 | } |
| 1625 |
no test coverage detected