Handle layer surfaces below shell surfaces

This commit is contained in:
Drew DeVault 2018-04-02 17:00:09 -04:00
parent a94f4d0edc
commit 37036df822
4 changed files with 23 additions and 10 deletions

View file

@ -17,7 +17,7 @@ struct roots_seat {
double touch_x, touch_y;
// If the focused layer is set, views cannot receive keyboard focus
struct roots_layer_surface *focused_layer;
struct wlr_layer_surface *focused_layer;
struct wl_list views; // roots_seat_view::link
bool has_focus;
@ -105,7 +105,7 @@ struct roots_view *roots_seat_get_focus(struct roots_seat *seat);
void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view);
void roots_seat_set_focus_layer(struct roots_seat *seat,
struct roots_layer_surface *layer);
struct wlr_layer_surface *layer);
void roots_seat_cycle_focus(struct roots_seat *seat);

View file

@ -271,6 +271,12 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
break;
case WLR_BUTTON_PRESSED:
roots_seat_set_focus(seat, view);
if (surface && !view) {
struct wlr_layer_surface *layer = surface->role_data;
if (layer->current.keyboard_interactive) {
roots_seat_set_focus_layer(seat, layer);
}
}
break;
}
}

View file

@ -218,7 +218,8 @@ void arrange_layers(struct roots_output *output) {
struct roots_input *input = output->desktop->server->input;
struct roots_seat *seat;
wl_list_for_each(seat, &input->seats, link) {
roots_seat_set_focus_layer(seat, topmost);
roots_seat_set_focus_layer(seat,
topmost ? topmost->layer_surface : NULL);
}
}

View file

@ -804,26 +804,33 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) {
}
}
/**
* Focus semantics of layer surfaces are somewhat detached from the normal focus
* flow. For layers above the shell layer, for example, you cannot unfocus them.
* You also cannot alt-tab between layer surfaces and shell surfaces.
*/
void roots_seat_set_focus_layer(struct roots_seat *seat,
struct roots_layer_surface *layer) {
struct wlr_layer_surface *layer) {
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->seat);
seat->focused_layer = layer;
if (!layer) {
wlr_seat_keyboard_clear_focus(seat->seat);
seat->focused_layer = NULL;
return;
}
if (seat->has_focus) {
struct roots_view *prev_focus = roots_seat_get_focus(seat);
wlr_seat_keyboard_clear_focus(seat->seat);
view_activate(prev_focus, false);
}
seat->has_focus = false;
struct wlr_layer_surface *layer_surface = layer->layer_surface;
if (layer->layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
seat->focused_layer = layer;
}
if (keyboard != NULL) {
wlr_seat_keyboard_notify_enter(seat->seat, layer_surface->surface,
wlr_seat_keyboard_notify_enter(seat->seat, layer->surface,
keyboard->keycodes, keyboard->num_keycodes,
&keyboard->modifiers);
} else {
wlr_seat_keyboard_notify_enter(seat->seat, layer_surface->surface,
wlr_seat_keyboard_notify_enter(seat->seat, layer->surface,
NULL, 0, NULL);
}
}
@ -854,7 +861,6 @@ void roots_seat_cycle_focus(struct roots_seat *seat) {
}
void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) {
wlr_log(L_DEBUG, "begin move");
struct roots_cursor *cursor = seat->cursor;
cursor->mode = ROOTS_CURSOR_MOVE;
cursor->offs_x = cursor->cursor->x;