rootston: focus newly-created surfaces
Whenever a new surface is created, we have to update the cursor focus, even if there's no input event. So, we generate one motion event, and reuse the code to update the proper cursor focus. We need to do this for all surface roles - toplevels, popups, subsurfaces. Fixes #1162
This commit is contained in:
parent
f1b65b34a6
commit
2e6eb097b6
|
@ -80,4 +80,7 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor,
|
||||||
void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
|
void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
|
||||||
struct wlr_seat_pointer_request_set_cursor_event *event);
|
struct wlr_seat_pointer_request_set_cursor_event *event);
|
||||||
|
|
||||||
|
void roots_cursor_update_position(struct roots_cursor *cursor,
|
||||||
|
uint32_t time);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,4 +32,6 @@ struct roots_seat *input_get_seat(struct roots_input *input, char *name);
|
||||||
|
|
||||||
struct roots_seat *input_last_active_seat(struct roots_input *input);
|
struct roots_seat *input_last_active_seat(struct roots_input *input);
|
||||||
|
|
||||||
|
void input_update_cursor_focus(struct roots_input *input);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,6 +101,7 @@ static void seat_view_deco_button(struct roots_seat_view *view, double sx,
|
||||||
|
|
||||||
static void roots_passthrough_cursor(struct roots_cursor *cursor,
|
static void roots_passthrough_cursor(struct roots_cursor *cursor,
|
||||||
uint32_t time) {
|
uint32_t time) {
|
||||||
|
bool focus_changed;
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct roots_view *view = NULL;
|
struct roots_view *view = NULL;
|
||||||
struct roots_seat *seat = cursor->seat;
|
struct roots_seat *seat = cursor->seat;
|
||||||
|
@ -136,8 +137,11 @@ static void roots_passthrough_cursor(struct roots_cursor *cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface) {
|
if (surface) {
|
||||||
|
focus_changed = (seat->seat->pointer_state.focused_surface != surface);
|
||||||
wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy);
|
wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy);
|
||||||
|
if (!focus_changed) {
|
||||||
wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy);
|
wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
wlr_seat_pointer_clear_focus(seat->seat);
|
wlr_seat_pointer_clear_focus(seat->seat);
|
||||||
}
|
}
|
||||||
|
@ -148,8 +152,8 @@ static void roots_passthrough_cursor(struct roots_cursor *cursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void roots_cursor_update_position(
|
void roots_cursor_update_position(struct roots_cursor *cursor,
|
||||||
struct roots_cursor *cursor, uint32_t time) {
|
uint32_t time) {
|
||||||
struct roots_seat *seat = cursor->seat;
|
struct roots_seat *seat = cursor->seat;
|
||||||
struct roots_view *view;
|
struct roots_view *view;
|
||||||
switch (cursor->mode) {
|
switch (cursor->mode) {
|
||||||
|
@ -266,13 +270,7 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
|
||||||
cursor->mode = ROOTS_CURSOR_PASSTHROUGH;
|
cursor->mode = ROOTS_CURSOR_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
if (state == WLR_BUTTON_PRESSED) {
|
||||||
case WLR_BUTTON_RELEASED:
|
|
||||||
if (!is_touch) {
|
|
||||||
roots_cursor_update_position(cursor, time);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WLR_BUTTON_PRESSED:
|
|
||||||
if (view) {
|
if (view) {
|
||||||
roots_seat_set_focus(seat, view);
|
roots_seat_set_focus(seat, view);
|
||||||
}
|
}
|
||||||
|
@ -283,7 +281,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
|
||||||
roots_seat_set_focus_layer(seat, layer);
|
roots_seat_set_focus_layer(seat, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,6 +423,7 @@ struct roots_subsurface *subsurface_create(struct roots_view *view,
|
||||||
view_child_init(&subsurface->view_child, view, wlr_subsurface->surface);
|
view_child_init(&subsurface->view_child, view, wlr_subsurface->surface);
|
||||||
subsurface->destroy.notify = subsurface_handle_destroy;
|
subsurface->destroy.notify = subsurface_handle_destroy;
|
||||||
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
|
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
|
||||||
|
input_update_cursor_focus(view->desktop->server->input);
|
||||||
return subsurface;
|
return subsurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,6 +469,7 @@ void view_map(struct roots_view *view, struct wlr_surface *surface) {
|
||||||
|
|
||||||
wl_list_insert(&view->desktop->views, &view->link);
|
wl_list_insert(&view->desktop->views, &view->link);
|
||||||
view_damage_whole(view);
|
view_damage_whole(view);
|
||||||
|
input_update_cursor_focus(view->desktop->server->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_unmap(struct roots_view *view) {
|
void view_unmap(struct roots_view *view) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/backend/libinput.h>
|
#include <wlr/backend/libinput.h>
|
||||||
#include <wlr/config.h>
|
#include <wlr/config.h>
|
||||||
|
@ -126,3 +128,16 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int64_t timespec_to_msec(const struct timespec *a) {
|
||||||
|
return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void input_update_cursor_focus(struct roots_input *input) {
|
||||||
|
struct roots_seat *seat;
|
||||||
|
struct timespec now;
|
||||||
|
wl_list_for_each(seat, &input->seats, link) {
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
roots_cursor_update_position(seat->cursor, timespec_to_msec(&now));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -291,7 +291,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
static void handle_unmap(struct wl_listener *listener, void *data) {
|
static void handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
struct roots_layer_surface *layer = wl_container_of(
|
struct roots_layer_surface *layer = wl_container_of(
|
||||||
listener, layer, unmap);
|
listener, layer, unmap);
|
||||||
|
struct wlr_output *wlr_output = layer->layer_surface->output;
|
||||||
|
struct roots_output *output = wlr_output->data;
|
||||||
unmap(layer->layer_surface);
|
unmap(layer->layer_surface);
|
||||||
|
input_update_cursor_focus(output->desktop->server->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||||
|
@ -303,6 +306,7 @@ static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||||
int oy = popup->wlr_popup->geometry.y + layer->geo.y;
|
int oy = popup->wlr_popup->geometry.y + layer->geo.y;
|
||||||
output_damage_whole_local_surface(output, popup->wlr_popup->base->surface,
|
output_damage_whole_local_surface(output, popup->wlr_popup->base->surface,
|
||||||
ox, oy, 0);
|
ox, oy, 0);
|
||||||
|
input_update_cursor_focus(output->desktop->server->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <wlr/types/wlr_surface.h>
|
#include <wlr/types/wlr_surface.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#include "rootston/cursor.h"
|
||||||
#include "rootston/desktop.h"
|
#include "rootston/desktop.h"
|
||||||
#include "rootston/input.h"
|
#include "rootston/input.h"
|
||||||
#include "rootston/server.h"
|
#include "rootston/server.h"
|
||||||
|
@ -33,6 +34,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||||
struct roots_xdg_popup *popup = wl_container_of(listener, popup, map);
|
struct roots_xdg_popup *popup = wl_container_of(listener, popup, map);
|
||||||
view_damage_whole(popup->view_child.view);
|
view_damage_whole(popup->view_child.view);
|
||||||
|
input_update_cursor_focus(popup->view_child.view->desktop->server->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -34,6 +34,7 @@ static void popup_handle_map(struct wl_listener *listener, void *data) {
|
||||||
struct roots_xdg_popup_v6 *popup =
|
struct roots_xdg_popup_v6 *popup =
|
||||||
wl_container_of(listener, popup, map);
|
wl_container_of(listener, popup, map);
|
||||||
view_damage_whole(popup->view_child.view);
|
view_damage_whole(popup->view_child.view);
|
||||||
|
input_update_cursor_focus(popup->view_child.view->desktop->server->input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
static void popup_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
|
Loading…
Reference in New Issue