aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-07-15 15:20:21 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-07-15 22:08:26 +1000
commita120d4c79f9406a2f7cc38c60069d3183c98ea87 (patch)
tree87a568ff97fc94ca82b9ceb4abacb02ea86a9f71
parent53e3f35ba348d6285478ceb4a93b020e138c95c7 (diff)
downloadsway-a120d4c79f9406a2f7cc38c60069d3183c98ea87.zip
sway-a120d4c79f9406a2f7cc38c60069d3183c98ea87.tar.gz
sway-a120d4c79f9406a2f7cc38c60069d3183c98ea87.tar.bz2
Make focus part of transactions
Rather than maintain copies of the entire focus stack, this PR transactionises the focus by introducing two new properties to the container state and using those when rendering. * `bool focused` means this container has actual focus. Only one container should have this equalling true in its current state. * `struct sway_container *focus_inactive_child` points to the immediate child that was most recently focused (eg. for tabbed and stacked containers).
-rw-r--r--include/sway/input/seat.h11
-rw-r--r--include/sway/tree/container.h3
-rw-r--r--sway/commands.c2
-rw-r--r--sway/desktop/render.c61
-rw-r--r--sway/desktop/transaction.c18
-rw-r--r--sway/input/cursor.c3
-rw-r--r--sway/input/keyboard.c2
-rw-r--r--sway/input/seat.c24
-rw-r--r--sway/ipc-server.c2
-rw-r--r--sway/main.c2
10 files changed, 55 insertions, 73 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 0e44070..1f7792b 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -119,17 +119,6 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
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
* function on each.
*/
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 1178091..04e50fc 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -68,6 +68,9 @@ struct sway_container_state {
struct sway_container *parent;
list_t *children;
+ struct sway_container *focused_inactive_child;
+ bool focused;
+
// View properties
double view_x, view_y;
double view_width, view_height;
diff --git a/sway/commands.c b/sway/commands.c
index 50d949d..addd64a 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -9,7 +9,6 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/criteria.h"
-#include "sway/desktop/transaction.h"
#include "sway/security.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
@@ -323,7 +322,6 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
cleanup:
free(exec);
free(views);
- transaction_commit_dirty();
if (!results) {
results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 4bfc573..17fe823 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -543,9 +543,6 @@ static void render_container(struct sway_output *output,
static void render_container_simple(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
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) {
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 sway_container_state *state = &child->current;
- if (focus == child || parent_focused) {
+ if (state->focused || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_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;
title_texture = child->title_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);
} else {
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) {
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 *current = pstate->focused_inactive_child;
+ struct border_colors *current_colors = &config->border_colors.unfocused;
double width_gap_adjustment = 2 * pstate->current_gaps;
int tab_width =
@@ -613,11 +608,11 @@ static void render_container_tabbed(struct sway_output *output,
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
- if (focus == child || parent_focused) {
+ if (cstate->focused || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL;
- } else if (child == current) {
+ } else if (child == pstate->focused_inactive_child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
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
- if (current) {
- if (current->type == C_VIEW) {
- render_view(output, damage, current, current_colors);
- } else {
- render_container(output, damage, current,
- parent_focused || current == focus);
- }
+ if (current->type == C_VIEW) {
+ render_view(output, damage, current, current_colors);
+ } else {
+ render_container(output, damage, current,
+ parent_focused || current->current.focused);
}
}
@@ -663,11 +656,9 @@ static void render_container_stacked(struct sway_output *output,
if (!con->current.children->length) {
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 *current = pstate->focused_inactive_child;
+ struct border_colors *current_colors = &config->border_colors.unfocused;
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 *marks_texture;
- if (focus == child || parent_focused) {
+ if (cstate->focused || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL;
- } else if (child == current) {
+ } else if (child == pstate->focused_inactive_child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
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
- if (current) {
- if (current->type == C_VIEW) {
- render_view(output, damage, current, current_colors);
- } else {
- render_container(output, damage, current,
- parent_focused || current == focus);
- }
+ if (current->type == C_VIEW) {
+ render_view(output, damage, current, current_colors);
+ } else {
+ render_container(output, damage, current,
+ parent_focused || current->current.focused);
}
}
@@ -738,13 +727,11 @@ static void render_floating_container(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_container *con) {
if (con->type == C_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 wlr_texture *title_texture;
struct wlr_texture *marks_texture;
- if (focus == con) {
+ if (con->current.focused) {
colors = &config->border_colors.focused;
title_texture = con->title_focused;
marks_texture = view->marks_focused;
@@ -871,9 +858,7 @@ void output_render(struct sway_output *output, struct timespec *when,
render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
- struct sway_seat *seat = input_manager_current_seat(input_manager);
- struct sway_container *focus = seat_get_focus(seat);
- render_container(output, damage, workspace, focus == workspace);
+ render_container(output, damage, workspace, workspace->current.focused);
render_floating(output, damage);
render_unmanaged(output, damage,
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 0ae042d..fcfb0b5 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -139,6 +139,14 @@ static void copy_pending_state(struct sway_container *container,
state->children = create_list();
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,
@@ -195,10 +203,12 @@ static void transaction_apply(struct sway_transaction *transaction) {
.width = instruction->state.swayc_width,
.height = instruction->state.swayc_height,
};
- for (int j = 0; j < root_container.children->length; ++j) {
- struct sway_container *output = root_container.children->items[j];
- output_damage_box(output->sway_output, &old_box);
- output_damage_box(output->sway_output, &new_box);
+ for (int j = 0; j < root_container.current.children->length; ++j) {
+ struct sway_container *output = root_container.current.children->items[j];
+ if (output->sway_output) {
+ 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
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 307eedd..7a9f3ed 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -10,6 +10,7 @@
#include <wlr/types/wlr_idle.h>
#include "list.h"
#include "log.h"
+#include "sway/desktop/transaction.h"
#include "sway/input/cursor.h"
#include "sway/layers.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;
drag_icon_update_position(drag_icon);
}
+ transaction_commit_dirty();
}
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,
time_msec, button, state);
+ transaction_commit_dirty();
}
static void handle_cursor_button(struct wl_listener *listener, void *data) {
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 580c0d4..ede3851 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -3,6 +3,7 @@
#include <wlr/backend/multi.h>
#include <wlr/backend/session.h>
#include <wlr/types/wlr_idle.h>
+#include "sway/desktop/transaction.h"
#include "sway/input/seat.h"
#include "sway/input/keyboard.h"
#include "sway/input/input-manager.h"
@@ -126,6 +127,7 @@ static void keyboard_execute_command(struct sway_keyboard *keyboard,
binding->command);
config->handler_context.seat = keyboard->seat_device->sway_seat;
struct cmd_results *results = execute_command(binding->command, NULL);
+ transaction_commit_dirty();
if (results->status != CMD_SUCCESS) {
wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
binding->command, results->error);
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 5e65ca7..74f1375 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -661,9 +661,13 @@ void seat_set_focus_warp(struct sway_seat *seat,
if (last_focus) {
seat_send_unfocus(last_focus, 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.
@@ -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) {
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;
}
-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) {
if (!seat->has_focus) {
return NULL;
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index c5161a6..be70391 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -18,6 +18,7 @@
#include <wayland-server.h>
#include "sway/commands.h"
#include "sway/config.h"
+#include "sway/desktop/transaction.h"
#include "sway/ipc-json.h"
#include "sway/ipc-server.h"
#include "sway/output.h"
@@ -484,6 +485,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
case IPC_COMMAND:
{
struct cmd_results *results = execute_command(buf, NULL);
+ transaction_commit_dirty();
char *json = cmd_results_to_json(results);
int length = strlen(json);
client_valid = ipc_send_reply(client, json, (uint32_t)length);
diff --git a/sway/main.c b/sway/main.c
index 1d772b4..1a55b51 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -20,6 +20,7 @@
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/debug.h"
+#include "sway/desktop/transaction.h"
#include "sway/server.h"
#include "sway/tree/layout.h"
#include "sway/ipc-server.h"
@@ -441,6 +442,7 @@ int main(int argc, char **argv) {
free(line);
list_del(config->cmd_queue, 0);
}
+ transaction_commit_dirty();
if (!terminate_request) {
server_run(&server);