Keep monitor selection while pointer crosses gaps

5a678454a376396ecd42d1a5ac11a81b6384abb2
Alexis Sellier committed ago 1 parent 6fed400c
swm.c +9 -2
1967 1967
        remaining -= size;
1968 1968
    }
1969 1969
    expanded[i] = nullptr;
1970 1970
}
1971 1971
1972 +
/* Keep the selected display when the cursor is temporarily in a layout gap. */
1973 +
static monitor_t *pointer_selected_monitor(monitor_t *current, double x, double y) {
1974 +
    monitor_t *pointed = point_to_monitor(x, y);
1975 +
1976 +
    return pointed ? pointed : current;
1977 +
}
1978 +
1972 1979
/* Start every command in the configured autostart list. */
1973 1980
void autostart_exec(void) {
1974 1981
    /* Run each configured startup command. A nullptr separates commands, and
1975 1982
     * a second nullptr ends the list. */
1976 1983
    const char *const *p;
2033 2040
    case WL_POINTER_BUTTON_STATE_PRESSED:
2034 2041
        if (cursor_mode != CURSOR_NORMAL && cursor_mode != CURSOR_PRESSED)
2035 2042
            break;
2036 2043
        pressed_button = event->button;
2037 2044
        cursor_mode    = CURSOR_PRESSED;
2038 -
        selmon         = point_to_monitor(cursor->x, cursor->y);
2045 +
        selmon         = pointer_selected_monitor(selmon, cursor->x, cursor->y);
2039 2046
2040 2047
        if (locked)
2041 2048
            break;
2042 2049
2043 2050
        /* Focus a window when a button is pressed over it. */
4405 4412
        wlr_cursor_move(cursor, device, dx, dy);
4406 4413
        wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
4407 4414
4408 4415
        /* Update the selected display even while dragging a window. */
4409 4416
        if (sloppyfocus)
4410 -
            selmon = point_to_monitor(cursor->x, cursor->y);
4417 +
            selmon = pointer_selected_monitor(selmon, cursor->x, cursor->y);
4411 4418
    }
4412 4419
    /* Hit-test at the updated cursor position. */
4413 4420
    point_to_node(cursor->x, cursor->y, &surface, &c, nullptr, &sx, &sy);
4414 4421
4415 4422
    if (cursor_mode == CURSOR_PRESSED && !seat->drag &&
test/unit.c +2 -0
696 696
static void test_small_helpers(void) {
697 697
    client_t           client = { .geom = { -20, 100, 2, 2 }, .bw = 2 };
698 698
    struct wlr_box     bounds = { 0, 0, 80, 60 };
699 699
    static_listener_t *slot;
700 700
    struct wlr_seat    fake_seat = {};
701 +
    monitor_t          monitor   = {};
701 702
702 703
    apply_bounds(&client, &bounds);
703 704
    assert(client.geom.x == 0 && client.geom.y == 55);
704 705
    assert(client.geom.width == 5 && client.geom.height == 5);
705 706
    assert(serial_at_least(10, 10));
706 707
    assert(serial_at_least(11, 10));
707 708
    assert(!serial_at_least(9, 10));
708 709
    assert(serial_at_least(1, UINT32_MAX));
709 710
    assert(!serial_at_least(UINT32_MAX, 1));
710 711
    assert(pointer_event_time(0) != 0);
712 +
    assert(pointer_selected_monitor(&monitor, 10, 10) == &monitor);
711 713
    seat = &fake_seat;
712 714
    assert(shortcuts_inhibited() == 0);
713 715
    assert(focus_close(nullptr) == nullptr);
714 716
    slot = pool_take(&static_listener_pool);
715 717
    assert(slot);