mirror of
https://github.com/swaywm/sway.git
synced 2024-12-28 07:56:31 +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 *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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue