diff --git a/src/main.c b/src/main.c index 86052cb..fc89247 100644 --- a/src/main.c +++ b/src/main.c @@ -426,7 +426,7 @@ static void cleanup(GtkWidget *window, gpointer data) { g_object_unref(state->move_cursor); g_clear_object(&state->settings); #ifdef WITH_KANSHI - wd_store_config_if_dirty(state); + wd_save_kanshi_snapshot(state); #endif wd_state_destroy(state); } @@ -875,7 +875,7 @@ static void auto_apply_selected(GSimpleAction *action, GVariant *param, gpointer g_simple_action_set_state(action, param); #ifdef WITH_KANSHI if (!state->autoapply) { - wd_store_config_if_dirty(state); + wd_save_kanshi_snapshot(state); } #endif } @@ -925,7 +925,7 @@ static void save_kanshi_config_selected(GSimpleAction *action, GVariant *param, g_settings_set_boolean(state->settings, "save-kanshi-config", g_variant_get_boolean(param)); } state->save_kanshi_config = g_variant_get_boolean(param); - state->kanshi_dirty = false; + wd_drop_kanshi_snapshot(state); g_simple_action_set_state(action, param); } #endif diff --git a/src/outputs.c b/src/outputs.c index 9d0ce60..8d5662f 100644 --- a/src/outputs.c +++ b/src/outputs.c @@ -38,16 +38,38 @@ struct wd_pending_config { bool manual; }; -static void destroy_pending(struct wd_pending_config *pending) { +static void destroy_outputs(struct wl_list *outputs) { struct wd_head_config *output, *tmp; - wl_list_for_each_safe(output, tmp, pending->outputs, link) { + wl_list_for_each_safe(output, tmp, outputs, link) { wl_list_remove(&output->link); free(output); } - free(pending->outputs); + free(outputs); +} + +static void destroy_pending(struct wd_pending_config *pending) { + if (pending->outputs != NULL) { + destroy_outputs(pending->outputs); + } free(pending); } +#ifdef WITH_KANSHI +void wd_drop_kanshi_snapshot(struct wd_state *state) { + if (state->kanshi_snapshot != NULL) { + destroy_outputs(state->kanshi_snapshot); + state->kanshi_snapshot = NULL; + } +} + +void wd_save_kanshi_snapshot(struct wd_state *state) { + if (state->kanshi_snapshot != NULL) { + wd_store_config(state, state->kanshi_snapshot); + wd_drop_kanshi_snapshot(state); + } +} +#endif + static void config_handle_succeeded(void *data, struct zwlr_output_configuration_v1 *config) { struct wd_pending_config *pending = data; @@ -55,10 +77,13 @@ static void config_handle_succeeded(void *data, wd_ui_apply_done(pending->state, pending->outputs); #ifdef WITH_KANSHI if (pending->state->save_kanshi_config) { + wd_drop_kanshi_snapshot(pending->state); if (pending->manual) { wd_store_config(pending->state, pending->outputs); + } else { + pending->state->kanshi_snapshot = pending->outputs; + pending->outputs = NULL; } - pending->state->kanshi_dirty = !pending->manual; } #endif destroy_pending(pending); @@ -491,6 +516,9 @@ static void head_handle_finished(void *data, struct zwlr_output_head_v1 *wlr_head) { struct wd_head *head = data; struct wd_state *state = head->state; +#ifdef WITH_KANSHI + wd_save_kanshi_snapshot(state); +#endif wl_list_remove(&head->link); wd_head_destroy(head); @@ -526,6 +554,9 @@ static void output_manager_handle_head(void *data, struct zwlr_output_manager_v1 *manager, struct zwlr_output_head_v1 *wlr_head) { struct wd_state *state = data; +#ifdef WITH_KANSHI + wd_save_kanshi_snapshot(state); +#endif struct wd_head *head = calloc(1, sizeof(*head)); head->state = state; diff --git a/src/store.c b/src/store.c index 8b9fe8a..4e6a166 100644 --- a/src/store.c +++ b/src/store.c @@ -634,37 +634,6 @@ static void reload_kanshi(void) { } } -void wd_store_config_if_dirty(struct wd_state *state) { - if (!state->kanshi_dirty) { - return; - } - state->kanshi_dirty = false; - - struct wl_list outputs; - wl_list_init(&outputs); - struct wd_head *head; - wl_list_for_each(head, &state->heads, link) { - struct wd_head_config *output = g_new0(struct wd_head_config, 1); - output->head = head; - output->enabled = head->enabled; - output->width = head->mode != NULL ? head->mode->width : head->custom_mode.width; - output->height = head->mode != NULL ? head->mode->height : head->custom_mode.height; - output->refresh = head->mode != NULL ? head->mode->refresh : head->custom_mode.refresh; - output->x = head->x; - output->y = head->y; - output->scale = head->scale; - output->transform = head->transform; - wl_list_insert(&outputs, &output->link); - } - wd_store_config(state, &outputs); - - struct wd_head_config *output, *tmp; - wl_list_for_each_safe(output, tmp, &outputs, link) { - wl_list_remove(&output->link); - g_free(output); - } -} - void wd_store_config(struct wd_state *state, struct wl_list *outputs) { g_autofree char *path = get_config_path(); g_autoptr(GPtrArray) files = g_ptr_array_new_with_free_func(kanshi_file_free); diff --git a/src/wdisplays.h b/src/wdisplays.h index ffec9bf..90f039f 100644 --- a/src/wdisplays.h +++ b/src/wdisplays.h @@ -192,7 +192,7 @@ struct wd_state { bool capture; bool show_overlay; bool save_kanshi_config; - bool kanshi_dirty; + struct wl_list *kanshi_snapshot; double zoom; unsigned int apply_idle; @@ -355,10 +355,15 @@ void wd_destroy_overlay(struct wd_output *output); void wd_store_config(struct wd_state *state, struct wl_list *outputs); /* - * Saves the current layout to the kanshi config if auto-apply changed it - * since the last save. + * Saves the layout of the last auto-apply to the kanshi config, unless it + * has been saved or dropped already. */ -void wd_store_config_if_dirty(struct wd_state *state); +void wd_save_kanshi_snapshot(struct wd_state *state); + +/* + * Forgets the layout of the last auto-apply without saving it. + */ +void wd_drop_kanshi_snapshot(struct wd_state *state); #endif // SPDX-SnippetEnd #endif