mirror of
https://github.com/swaywm/sway.git
synced 2024-12-30 17:06:40 +01:00
Merge pull request #2275 from RyanDwyer/transactionise-focus
Make focus part of transactions
This commit is contained in:
commit
8e05fb7826
10 changed files with 55 additions and 73 deletions
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 == focus);
|
parent_focused || current->current.focused);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 == focus);
|
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) {
|
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,
|
||||||
|
|
|
@ -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,11 +203,13 @@ 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];
|
||||||
|
if (output->sway_output) {
|
||||||
output_damage_box(output->sway_output, &old_box);
|
output_damage_box(output->sway_output, &old_box);
|
||||||
output_damage_box(output->sway_output, &new_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
|
||||||
// container's current state and the container's pending state
|
// container's current state and the container's pending state
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue