Merge pull request #2275 from RyanDwyer/transactionise-focus

Make focus part of transactions
This commit is contained in:
Drew DeVault 2018-07-15 06:49:29 -07:00 committed by GitHub
commit 8e05fb7826
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 55 additions and 73 deletions

View file

@ -118,17 +118,6 @@ struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
struct sway_container *seat_get_active_child(struct sway_seat *seat, struct sway_container *seat_get_active_child(struct sway_seat *seat,
struct sway_container *container); struct sway_container *container);
/**
* Return the immediate child of container which was most recently focused, with
* fallback to selecting the child in the parent's `current` (rendered) children
* list.
*
* This is useful for when a tabbed container and its children are destroyed but
* still being rendered, and we have to render an appropriate child.
*/
struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
struct sway_container *container);
/** /**
* Iterate over the focus-inactive children of the container calling the * Iterate over the focus-inactive children of the container calling the
* function on each. * function on each.

View file

@ -68,6 +68,9 @@ struct sway_container_state {
struct sway_container *parent; struct sway_container *parent;
list_t *children; list_t *children;
struct sway_container *focused_inactive_child;
bool focused;
// View properties // View properties
double view_x, view_y; double view_x, view_y;
double view_width, view_height; double view_width, view_height;

View file

@ -9,7 +9,6 @@
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/criteria.h" #include "sway/criteria.h"
#include "sway/desktop/transaction.h"
#include "sway/security.h" #include "sway/security.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
@ -323,7 +322,6 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
cleanup: cleanup:
free(exec); free(exec);
free(views); free(views);
transaction_commit_dirty();
if (!results) { if (!results) {
results = cmd_results_new(CMD_SUCCESS, NULL, NULL); results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -543,9 +543,6 @@ static void render_container(struct sway_output *output,
static void render_container_simple(struct sway_output *output, static void render_container_simple(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) { bool parent_focused) {
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
for (int i = 0; i < con->current.children->length; ++i) { for (int i = 0; i < con->current.children->length; ++i) {
struct sway_container *child = con->current.children->items[i]; struct sway_container *child = con->current.children->items[i];
@ -556,11 +553,11 @@ static void render_container_simple(struct sway_output *output,
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
struct sway_container_state *state = &child->current; struct sway_container_state *state = &child->current;
if (focus == child || parent_focused) { if (state->focused || parent_focused) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = view->marks_focused; marks_texture = view->marks_focused;
} else if (seat_get_focus_inactive(seat, con) == child) { } else if (con->current.focused_inactive_child == child) {
colors = &config->border_colors.focused_inactive; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = view->marks_focused_inactive; marks_texture = view->marks_focused_inactive;
@ -580,7 +577,7 @@ static void render_container_simple(struct sway_output *output,
render_view(output, damage, child, colors); render_view(output, damage, child, colors);
} else { } else {
render_container(output, damage, child, render_container(output, damage, child,
parent_focused || focus == child); parent_focused || child->current.focused);
} }
} }
} }
@ -594,11 +591,9 @@ static void render_container_tabbed(struct sway_output *output,
if (!con->current.children->length) { if (!con->current.children->length) {
return; return;
} }
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct sway_container *current = seat_get_active_current_child(seat, con);
struct border_colors *current_colors = &config->border_colors.unfocused;
struct sway_container_state *pstate = &con->current; struct sway_container_state *pstate = &con->current;
struct sway_container *current = pstate->focused_inactive_child;
struct border_colors *current_colors = &config->border_colors.unfocused;
double width_gap_adjustment = 2 * pstate->current_gaps; double width_gap_adjustment = 2 * pstate->current_gaps;
int tab_width = int tab_width =
@ -613,11 +608,11 @@ static void render_container_tabbed(struct sway_output *output,
struct wlr_texture *title_texture; struct wlr_texture *title_texture;
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
if (focus == child || parent_focused) { if (cstate->focused || parent_focused) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL; marks_texture = view ? view->marks_focused : NULL;
} else if (child == current) { } else if (child == pstate->focused_inactive_child) {
colors = &config->border_colors.focused_inactive; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = view ? view->marks_focused_inactive : NULL; marks_texture = view ? view->marks_focused_inactive : NULL;
@ -644,13 +639,11 @@ static void render_container_tabbed(struct sway_output *output,
} }
// Render surface and left/right/bottom borders // Render surface and left/right/bottom borders
if (current) { if (current->type == C_VIEW) {
if (current->type == C_VIEW) { render_view(output, damage, current, current_colors);
render_view(output, damage, current, current_colors); } else {
} else { render_container(output, damage, current,
render_container(output, damage, current, parent_focused || current->current.focused);
parent_focused || current == focus);
}
} }
} }
@ -663,11 +656,9 @@ static void render_container_stacked(struct sway_output *output,
if (!con->current.children->length) { if (!con->current.children->length) {
return; return;
} }
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct sway_container *current = seat_get_active_current_child(seat, con);
struct border_colors *current_colors = &config->border_colors.unfocused;
struct sway_container_state *pstate = &con->current; struct sway_container_state *pstate = &con->current;
struct sway_container *current = pstate->focused_inactive_child;
struct border_colors *current_colors = &config->border_colors.unfocused;
size_t titlebar_height = container_titlebar_height(); size_t titlebar_height = container_titlebar_height();
@ -680,11 +671,11 @@ static void render_container_stacked(struct sway_output *output,
struct wlr_texture *title_texture; struct wlr_texture *title_texture;
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
if (focus == child || parent_focused) { if (cstate->focused || parent_focused) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = child->title_focused; title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL; marks_texture = view ? view->marks_focused : NULL;
} else if (child == current) { } else if (child == pstate->focused_inactive_child) {
colors = &config->border_colors.focused_inactive; colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive; title_texture = child->title_focused_inactive;
marks_texture = view ? view->marks_focused_inactive : NULL; marks_texture = view ? view->marks_focused_inactive : NULL;
@ -704,13 +695,11 @@ static void render_container_stacked(struct sway_output *output,
} }
// Render surface and left/right/bottom borders // Render surface and left/right/bottom borders
if (current) { if (current->type == C_VIEW) {
if (current->type == C_VIEW) { render_view(output, damage, current, current_colors);
render_view(output, damage, current, current_colors); } else {
} else { render_container(output, damage, current,
render_container(output, damage, current, parent_focused || current->current.focused);
parent_focused || current == focus);
}
} }
} }
@ -738,13 +727,11 @@ static void render_floating_container(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_container *con) { pixman_region32_t *damage, struct sway_container *con) {
if (con->type == C_VIEW) { if (con->type == C_VIEW) {
struct sway_view *view = con->sway_view; struct sway_view *view = con->sway_view;
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct border_colors *colors; struct border_colors *colors;
struct wlr_texture *title_texture; struct wlr_texture *title_texture;
struct wlr_texture *marks_texture; struct wlr_texture *marks_texture;
if (focus == con) { if (con->current.focused) {
colors = &config->border_colors.focused; colors = &config->border_colors.focused;
title_texture = con->title_focused; title_texture = con->title_focused;
marks_texture = view->marks_focused; marks_texture = view->marks_focused;
@ -871,9 +858,7 @@ void output_render(struct sway_output *output, struct timespec *when,
render_layer(output, damage, render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
struct sway_seat *seat = input_manager_current_seat(input_manager); render_container(output, damage, workspace, workspace->current.focused);
struct sway_container *focus = seat_get_focus(seat);
render_container(output, damage, workspace, focus == workspace);
render_floating(output, damage); render_floating(output, damage);
render_unmanaged(output, damage, render_unmanaged(output, damage,

View file

@ -139,6 +139,14 @@ static void copy_pending_state(struct sway_container *container,
state->children = create_list(); state->children = create_list();
list_cat(state->children, container->children); list_cat(state->children, container->children);
} }
struct sway_seat *seat = input_manager_current_seat(input_manager);
state->focused = seat_get_focus(seat) == container;
if (container->type != C_VIEW) {
state->focused_inactive_child =
seat_get_active_child(seat, container);
}
} }
static void transaction_add_container(struct sway_transaction *transaction, static void transaction_add_container(struct sway_transaction *transaction,
@ -195,10 +203,12 @@ static void transaction_apply(struct sway_transaction *transaction) {
.width = instruction->state.swayc_width, .width = instruction->state.swayc_width,
.height = instruction->state.swayc_height, .height = instruction->state.swayc_height,
}; };
for (int j = 0; j < root_container.children->length; ++j) { for (int j = 0; j < root_container.current.children->length; ++j) {
struct sway_container *output = root_container.children->items[j]; struct sway_container *output = root_container.current.children->items[j];
output_damage_box(output->sway_output, &old_box); if (output->sway_output) {
output_damage_box(output->sway_output, &new_box); output_damage_box(output->sway_output, &old_box);
output_damage_box(output->sway_output, &new_box);
}
} }
// There are separate children lists for each instruction state, the // There are separate children lists for each instruction state, the

View file

@ -10,6 +10,7 @@
#include <wlr/types/wlr_idle.h> #include <wlr/types/wlr_idle.h>
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
#include "sway/desktop/transaction.h"
#include "sway/input/cursor.h" #include "sway/input/cursor.h"
#include "sway/layers.h" #include "sway/layers.h"
#include "sway/output.h" #include "sway/output.h"
@ -219,6 +220,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
struct sway_drag_icon *drag_icon = wlr_drag_icon->data; struct sway_drag_icon *drag_icon = wlr_drag_icon->data;
drag_icon_update_position(drag_icon); drag_icon_update_position(drag_icon);
} }
transaction_commit_dirty();
} }
static void handle_cursor_motion(struct wl_listener *listener, void *data) { static void handle_cursor_motion(struct wl_listener *listener, void *data) {
@ -278,6 +280,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, wlr_seat_pointer_notify_button(cursor->seat->wlr_seat,
time_msec, button, state); time_msec, button, state);
transaction_commit_dirty();
} }
static void handle_cursor_button(struct wl_listener *listener, void *data) { static void handle_cursor_button(struct wl_listener *listener, void *data) {

View file

@ -3,6 +3,7 @@
#include <wlr/backend/multi.h> #include <wlr/backend/multi.h>
#include <wlr/backend/session.h> #include <wlr/backend/session.h>
#include <wlr/types/wlr_idle.h> #include <wlr/types/wlr_idle.h>
#include "sway/desktop/transaction.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/input/keyboard.h" #include "sway/input/keyboard.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
@ -126,6 +127,7 @@ static void keyboard_execute_command(struct sway_keyboard *keyboard,
binding->command); binding->command);
config->handler_context.seat = keyboard->seat_device->sway_seat; config->handler_context.seat = keyboard->seat_device->sway_seat;
struct cmd_results *results = execute_command(binding->command, NULL); struct cmd_results *results = execute_command(binding->command, NULL);
transaction_commit_dirty();
if (results->status != CMD_SUCCESS) { if (results->status != CMD_SUCCESS) {
wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
binding->command, results->error); binding->command, results->error);

View file

@ -661,9 +661,13 @@ void seat_set_focus_warp(struct sway_seat *seat,
if (last_focus) { if (last_focus) {
seat_send_unfocus(last_focus, seat); seat_send_unfocus(last_focus, seat);
} }
seat_send_focus(container, seat); seat_send_focus(container, seat);
container_damage_whole(container->parent);
container_set_dirty(container);
container_set_dirty(container->parent); // for focused_inactive_child
if (last_focus) {
container_set_dirty(last_focus);
}
} }
// If we've focused a floating container, bring it to the front. // If we've focused a floating container, bring it to the front.
@ -717,10 +721,6 @@ void seat_set_focus_warp(struct sway_seat *seat,
} }
} }
if (last_focus) {
container_damage_whole(last_focus);
}
if (last_workspace && last_workspace != new_workspace) { if (last_workspace && last_workspace != new_workspace) {
cursor_send_pointer_motion(seat->cursor, 0, true); cursor_send_pointer_motion(seat->cursor, 0, true);
} }
@ -840,18 +840,6 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
return NULL; return NULL;
} }
struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
struct sway_container *container) {
struct sway_seat_container *current = NULL;
wl_list_for_each(current, &seat->focus_stack, link) {
if (current->container->current.parent == container &&
current->container->current.layout != L_FLOATING) {
return current->container;
}
}
return NULL;
}
struct sway_container *seat_get_focus(struct sway_seat *seat) { struct sway_container *seat_get_focus(struct sway_seat *seat) {
if (!seat->has_focus) { if (!seat->has_focus) {
return NULL; return NULL;

View file

@ -18,6 +18,7 @@
#include <wayland-server.h> #include <wayland-server.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/desktop/transaction.h"
#include "sway/ipc-json.h" #include "sway/ipc-json.h"
#include "sway/ipc-server.h" #include "sway/ipc-server.h"
#include "sway/output.h" #include "sway/output.h"
@ -484,6 +485,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
case IPC_COMMAND: case IPC_COMMAND:
{ {
struct cmd_results *results = execute_command(buf, NULL); struct cmd_results *results = execute_command(buf, NULL);
transaction_commit_dirty();
char *json = cmd_results_to_json(results); char *json = cmd_results_to_json(results);
int length = strlen(json); int length = strlen(json);
client_valid = ipc_send_reply(client, json, (uint32_t)length); client_valid = ipc_send_reply(client, json, (uint32_t)length);

View file

@ -20,6 +20,7 @@
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/debug.h" #include "sway/debug.h"
#include "sway/desktop/transaction.h"
#include "sway/server.h" #include "sway/server.h"
#include "sway/tree/layout.h" #include "sway/tree/layout.h"
#include "sway/ipc-server.h" #include "sway/ipc-server.h"
@ -441,6 +442,7 @@ int main(int argc, char **argv) {
free(line); free(line);
list_del(config->cmd_queue, 0); list_del(config->cmd_queue, 0);
} }
transaction_commit_dirty();
if (!terminate_request) { if (!terminate_request) {
server_run(&server); server_run(&server);