mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	cosmic-workspaces: abstract transaction-addon
This allows to use it for a future ext-workspace implementation. It is also more generalized so can be used for other protocol implementation in the future in case the protocols require some kind of transaction management.
This commit is contained in:
		
							parent
							
								
									afe416f04e
								
							
						
					
					
						commit
						63dc609085
					
				
					 7 changed files with 258 additions and 176 deletions
				
			
		| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#include "cosmic-workspace-unstable-v1-protocol.h"
 | 
			
		||||
#include "protocols/cosmic-workspaces.h"
 | 
			
		||||
#include "protocols/cosmic-workspaces-internal.h"
 | 
			
		||||
#include "protocols/transaction-addon.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *	.--------------------.
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +50,13 @@ enum workspace_state {
 | 
			
		|||
	CW_WS_STATE_INVALID = 1 << 31,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ws_create_workspace_event {
 | 
			
		||||
	char *name;
 | 
			
		||||
	struct {
 | 
			
		||||
		struct wl_listener transaction_op_destroy;
 | 
			
		||||
	} on;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_caps(struct wl_array *caps_arr, uint32_t caps)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -79,37 +87,40 @@ workspace_handle_destroy(struct wl_client *client, struct wl_resource *resource)
 | 
			
		|||
static void
 | 
			
		||||
workspace_handle_activate(struct wl_client *client, struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		/* workspace was destroyed from the compositor side */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct lab_cosmic_workspace *workspace = addon->data;
 | 
			
		||||
	transaction_add_workspace_ev(workspace, resource, CW_PENDING_WS_ACTIVATE);
 | 
			
		||||
	lab_transaction_op_add(addon->ctx, CW_PENDING_WS_ACTIVATE,
 | 
			
		||||
		workspace, /*data*/ NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
workspace_handle_deactivate(struct wl_client *client, struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		/* Workspace was destroyed from the compositor side */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct lab_cosmic_workspace *workspace = addon->data;
 | 
			
		||||
	transaction_add_workspace_ev(workspace, resource, CW_PENDING_WS_DEACTIVATE);
 | 
			
		||||
	lab_transaction_op_add(addon->ctx, CW_PENDING_WS_DEACTIVATE,
 | 
			
		||||
		workspace, /*data*/ NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
workspace_handle_remove(struct wl_client *client, struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		/* workspace was destroyed from the compositor side */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct lab_cosmic_workspace *workspace = addon->data;
 | 
			
		||||
	transaction_add_workspace_ev(workspace, resource, CW_PENDING_WS_REMOVE);
 | 
			
		||||
	lab_transaction_op_add(addon->ctx, CW_PENDING_WS_REMOVE,
 | 
			
		||||
		workspace, /*data*/ NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct zcosmic_workspace_handle_v1_interface workspace_impl = {
 | 
			
		||||
| 
						 | 
				
			
			@ -122,9 +133,9 @@ static const struct zcosmic_workspace_handle_v1_interface workspace_impl = {
 | 
			
		|||
static void
 | 
			
		||||
workspace_instance_resource_destroy(struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (addon) {
 | 
			
		||||
		resource_addon_destroy(addon);
 | 
			
		||||
		lab_resource_addon_destroy(addon);
 | 
			
		||||
		wl_resource_set_user_data(resource, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +144,7 @@ workspace_instance_resource_destroy(struct wl_resource *resource)
 | 
			
		|||
 | 
			
		||||
static struct wl_resource *
 | 
			
		||||
workspace_resource_create(struct lab_cosmic_workspace *workspace,
 | 
			
		||||
		struct wl_resource *group_resource, struct session_context *ctx)
 | 
			
		||||
		struct wl_resource *group_resource, struct lab_transaction_session_context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_client *client = wl_resource_get_client(group_resource);
 | 
			
		||||
	struct wl_resource *resource = wl_resource_create(client,
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +155,7 @@ workspace_resource_create(struct lab_cosmic_workspace *workspace,
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource_addon *addon = resource_addon_create(ctx);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx);
 | 
			
		||||
	addon->data = workspace;
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &workspace_impl, addon,
 | 
			
		||||
| 
						 | 
				
			
			@ -212,17 +223,35 @@ workspace_set_state(struct lab_cosmic_workspace *workspace,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* Group */
 | 
			
		||||
static void
 | 
			
		||||
ws_create_workspace_handle_transaction_op_destroy(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct ws_create_workspace_event *ev =
 | 
			
		||||
		wl_container_of(listener, ev, on.transaction_op_destroy);
 | 
			
		||||
	wl_list_remove(&ev->on.transaction_op_destroy.link);
 | 
			
		||||
	free(ev->name);
 | 
			
		||||
	free(ev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
group_handle_create_workspace(struct wl_client *client,
 | 
			
		||||
		struct wl_resource *resource, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct lab_cosmic_workspace_group *group = addon->data;
 | 
			
		||||
	transaction_add_workspace_group_ev(group, resource, CW_PENDING_WS_CREATE, name);
 | 
			
		||||
	struct ws_create_workspace_event *ev = znew(*ev);
 | 
			
		||||
	ev->name = xstrdup(name);
 | 
			
		||||
 | 
			
		||||
	struct lab_transaction_op *transaction_op = lab_transaction_op_add(
 | 
			
		||||
		addon->ctx, CW_PENDING_WS_CREATE, group, ev);
 | 
			
		||||
 | 
			
		||||
	ev->on.transaction_op_destroy.notify =
 | 
			
		||||
		ws_create_workspace_handle_transaction_op_destroy;
 | 
			
		||||
	wl_signal_add(&transaction_op->events.destroy, &ev->on.transaction_op_destroy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -239,9 +268,9 @@ static const struct zcosmic_workspace_group_handle_v1_interface group_impl = {
 | 
			
		|||
static void
 | 
			
		||||
group_instance_resource_destroy(struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (addon) {
 | 
			
		||||
		resource_addon_destroy(addon);
 | 
			
		||||
		lab_resource_addon_destroy(addon);
 | 
			
		||||
		wl_resource_set_user_data(resource, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	wl_list_remove(wl_resource_get_link(resource));
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +278,7 @@ group_instance_resource_destroy(struct wl_resource *resource)
 | 
			
		|||
 | 
			
		||||
static struct wl_resource *
 | 
			
		||||
group_resource_create(struct lab_cosmic_workspace_group *group,
 | 
			
		||||
		struct wl_resource *manager_resource, struct session_context *ctx)
 | 
			
		||||
		struct wl_resource *manager_resource, struct lab_transaction_session_context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_client *client = wl_resource_get_client(manager_resource);
 | 
			
		||||
	struct wl_resource *resource = wl_resource_create(client,
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +289,7 @@ group_resource_create(struct lab_cosmic_workspace_group *group,
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource_addon *addon = resource_addon_create(ctx);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx);
 | 
			
		||||
	addon->data = group;
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &group_impl, addon,
 | 
			
		||||
| 
						 | 
				
			
			@ -284,40 +313,38 @@ group_send_state(struct lab_cosmic_workspace_group *group, struct wl_resource *r
 | 
			
		|||
static void
 | 
			
		||||
manager_handle_commit(struct wl_client *client, struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct transaction_group *trans_grp;
 | 
			
		||||
	struct transaction_workspace *trans_ws;
 | 
			
		||||
	struct transaction *trans, *trans_tmp;
 | 
			
		||||
	wl_list_for_each_safe(trans, trans_tmp, &addon->ctx->transactions, link) {
 | 
			
		||||
		switch (trans->change) {
 | 
			
		||||
	struct lab_cosmic_workspace *workspace;
 | 
			
		||||
	struct lab_cosmic_workspace_group *group;
 | 
			
		||||
	struct lab_transaction_op *trans_op, *trans_op_tmp;
 | 
			
		||||
	lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) {
 | 
			
		||||
		switch (trans_op->change) {
 | 
			
		||||
		case CW_PENDING_WS_CREATE:
 | 
			
		||||
			trans_grp = wl_container_of(trans, trans_grp, base);
 | 
			
		||||
			wl_signal_emit_mutable(
 | 
			
		||||
				&trans_grp->group->events.create_workspace,
 | 
			
		||||
				trans_grp->new_workspace_name);
 | 
			
		||||
			free(trans_grp->new_workspace_name);
 | 
			
		||||
			group = trans_op->src;
 | 
			
		||||
			struct ws_create_workspace_event *ev = trans_op->data;
 | 
			
		||||
			wl_signal_emit_mutable(&group->events.create_workspace, ev->name);
 | 
			
		||||
			break;
 | 
			
		||||
		case CW_PENDING_WS_ACTIVATE:
 | 
			
		||||
			trans_ws = wl_container_of(trans, trans_ws, base);
 | 
			
		||||
			wl_signal_emit_mutable(&trans_ws->workspace->events.activate, NULL);
 | 
			
		||||
			workspace = trans_op->src;
 | 
			
		||||
			wl_signal_emit_mutable(&workspace->events.activate, NULL);
 | 
			
		||||
			break;
 | 
			
		||||
		case CW_PENDING_WS_DEACTIVATE:
 | 
			
		||||
			trans_ws = wl_container_of(trans, trans_ws, base);
 | 
			
		||||
			wl_signal_emit_mutable(&trans_ws->workspace->events.deactivate, NULL);
 | 
			
		||||
			workspace = trans_op->src;
 | 
			
		||||
			wl_signal_emit_mutable(&workspace->events.deactivate, NULL);
 | 
			
		||||
			break;
 | 
			
		||||
		case CW_PENDING_WS_REMOVE:
 | 
			
		||||
			trans_ws = wl_container_of(trans, trans_ws, base);
 | 
			
		||||
			wl_signal_emit_mutable(&trans_ws->workspace->events.remove, NULL);
 | 
			
		||||
			workspace = trans_op->src;
 | 
			
		||||
			wl_signal_emit_mutable(&workspace->events.remove, NULL);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			wlr_log(WLR_ERROR, "Invalid transaction state: %u", trans->change);
 | 
			
		||||
			wlr_log(WLR_ERROR, "Invalid transaction state: %u", trans_op->change);
 | 
			
		||||
		}
 | 
			
		||||
		wl_list_remove(&trans->link);
 | 
			
		||||
		free(trans);
 | 
			
		||||
 | 
			
		||||
		lab_transaction_op_destroy(trans_op);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -336,9 +363,9 @@ static const struct zcosmic_workspace_manager_v1_interface manager_impl = {
 | 
			
		|||
static void
 | 
			
		||||
manager_instance_resource_destroy(struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (addon) {
 | 
			
		||||
		resource_addon_destroy(addon);
 | 
			
		||||
		lab_resource_addon_destroy(addon);
 | 
			
		||||
		wl_resource_set_user_data(resource, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -358,7 +385,7 @@ manager_handle_bind(struct wl_client *client, void *data,
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource_addon *addon = resource_addon_create(/* session context*/ NULL);
 | 
			
		||||
	struct lab_wl_resource_addon *addon = lab_resource_addon_create(/* session context*/ NULL);
 | 
			
		||||
	addon->data = manager;
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &manager_impl,
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +522,7 @@ lab_cosmic_workspace_group_create(struct lab_cosmic_workspace_manager *manager)
 | 
			
		|||
 | 
			
		||||
	struct wl_resource *resource, *tmp;
 | 
			
		||||
	wl_resource_for_each_safe(resource, tmp, &manager->resources) {
 | 
			
		||||
		struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		assert(addon && addon->ctx);
 | 
			
		||||
		struct wl_resource *group_resource =
 | 
			
		||||
			group_resource_create(group, resource, addon->ctx);
 | 
			
		||||
| 
						 | 
				
			
			@ -522,9 +549,9 @@ lab_cosmic_workspace_group_destroy(struct lab_cosmic_workspace_group *group)
 | 
			
		|||
 | 
			
		||||
	struct wl_resource *resource, *res_tmp;
 | 
			
		||||
	wl_resource_for_each_safe(resource, res_tmp, &group->resources) {
 | 
			
		||||
		struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		if (addon) {
 | 
			
		||||
			resource_addon_destroy(addon);
 | 
			
		||||
			lab_resource_addon_destroy(addon);
 | 
			
		||||
			wl_resource_set_user_data(resource, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		zcosmic_workspace_group_handle_v1_send_remove(resource);
 | 
			
		||||
| 
						 | 
				
			
			@ -532,6 +559,20 @@ lab_cosmic_workspace_group_destroy(struct lab_cosmic_workspace_group *group)
 | 
			
		|||
		wl_list_init(wl_resource_get_link(resource));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Cancel pending transaction operations involving this group */
 | 
			
		||||
	struct lab_transaction_op *trans_op, *trans_op_tmp;
 | 
			
		||||
	wl_resource_for_each(resource, &group->manager->resources) {
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		if (!addon) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) {
 | 
			
		||||
			if (trans_op->src == group) {
 | 
			
		||||
				lab_transaction_op_destroy(trans_op);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&group->link);
 | 
			
		||||
	wl_array_release(&group->capabilities);
 | 
			
		||||
	free(group);
 | 
			
		||||
| 
						 | 
				
			
			@ -569,7 +610,7 @@ lab_cosmic_workspace_create(struct lab_cosmic_workspace_group *group)
 | 
			
		|||
	/* Notify clients */
 | 
			
		||||
	struct wl_resource *group_resource;
 | 
			
		||||
	wl_resource_for_each(group_resource, &group->resources) {
 | 
			
		||||
		struct wl_resource_addon *addon = wl_resource_get_user_data(group_resource);
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(group_resource);
 | 
			
		||||
		assert(addon && addon->ctx);
 | 
			
		||||
		struct wl_resource *workspace_resource =
 | 
			
		||||
			workspace_resource_create(workspace, group_resource, addon->ctx);
 | 
			
		||||
| 
						 | 
				
			
			@ -642,9 +683,9 @@ lab_cosmic_workspace_destroy(struct lab_cosmic_workspace *workspace)
 | 
			
		|||
 | 
			
		||||
	struct wl_resource *resource, *tmp;
 | 
			
		||||
	wl_resource_for_each_safe(resource, tmp, &workspace->resources) {
 | 
			
		||||
		struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		if (addon) {
 | 
			
		||||
			resource_addon_destroy(addon);
 | 
			
		||||
			lab_resource_addon_destroy(addon);
 | 
			
		||||
			wl_resource_set_user_data(resource, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		zcosmic_workspace_handle_v1_send_remove(resource);
 | 
			
		||||
| 
						 | 
				
			
			@ -653,6 +694,20 @@ lab_cosmic_workspace_destroy(struct lab_cosmic_workspace *workspace)
 | 
			
		|||
	}
 | 
			
		||||
	manager_schedule_done_event(workspace->group->manager);
 | 
			
		||||
 | 
			
		||||
	/* Cancel pending transaction operations involving this workspace */
 | 
			
		||||
	struct lab_transaction_op *trans_op, *trans_op_tmp;
 | 
			
		||||
	wl_resource_for_each(resource, &workspace->group->manager->resources) {
 | 
			
		||||
		struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
		if (!addon) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) {
 | 
			
		||||
			if (trans_op->src == workspace) {
 | 
			
		||||
				lab_transaction_op_destroy(trans_op);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&workspace->link);
 | 
			
		||||
	wl_array_release(&workspace->coordinates);
 | 
			
		||||
	wl_array_release(&workspace->capabilities);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,4 @@
 | 
			
		|||
labwc_sources += files(
 | 
			
		||||
  'cosmic-workspaces.c',
 | 
			
		||||
  'transactions.c',
 | 
			
		||||
  'output.c',
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,93 +0,0 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <wayland-server-core.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
#include "common/list.h"
 | 
			
		||||
#include "common/mem.h"
 | 
			
		||||
#include "protocols/cosmic-workspaces-internal.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
transactions_destroy(struct wl_list *list)
 | 
			
		||||
{
 | 
			
		||||
	struct transaction_group *group;
 | 
			
		||||
	struct transaction *trans, *trans_tmp;
 | 
			
		||||
	wl_list_for_each_safe(trans, trans_tmp, list, link) {
 | 
			
		||||
		if (trans->change == CW_PENDING_WS_CREATE) {
 | 
			
		||||
			group = wl_container_of(trans, group, base);
 | 
			
		||||
			free(group->new_workspace_name);
 | 
			
		||||
		}
 | 
			
		||||
		wl_list_remove(&trans->link);
 | 
			
		||||
		free(trans);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
resource_addon_destroy(struct wl_resource_addon *addon)
 | 
			
		||||
{
 | 
			
		||||
	assert(addon);
 | 
			
		||||
	assert(addon->ctx);
 | 
			
		||||
 | 
			
		||||
	addon->ctx->ref_count--;
 | 
			
		||||
	assert(addon->ctx->ref_count >= 0);
 | 
			
		||||
 | 
			
		||||
	wlr_log(WLR_DEBUG, "New refcount for session %p: %d",
 | 
			
		||||
		addon->ctx, addon->ctx->ref_count);
 | 
			
		||||
	if (!addon->ctx->ref_count) {
 | 
			
		||||
		wlr_log(WLR_DEBUG, "Destroying session context");
 | 
			
		||||
		transactions_destroy(&addon->ctx->transactions);
 | 
			
		||||
		free(addon->ctx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(addon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wl_resource_addon *
 | 
			
		||||
resource_addon_create(struct session_context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = znew(*addon);
 | 
			
		||||
	if (!ctx) {
 | 
			
		||||
		ctx = znew(*ctx);
 | 
			
		||||
		wl_list_init(&ctx->transactions);
 | 
			
		||||
	}
 | 
			
		||||
	addon->ctx = ctx;
 | 
			
		||||
	addon->ctx->ref_count++;
 | 
			
		||||
	return addon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
transaction_add_workspace_ev(struct lab_cosmic_workspace *ws,
 | 
			
		||||
		struct wl_resource *resource, enum pending_change change)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "Failed to find manager addon for workspace transaction");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(change != CW_PENDING_WS_CREATE);
 | 
			
		||||
 | 
			
		||||
	struct transaction_workspace *trans_ws = znew(*trans_ws);
 | 
			
		||||
	trans_ws->workspace = ws;
 | 
			
		||||
	trans_ws->base.change = change;
 | 
			
		||||
	wl_list_append(&addon->ctx->transactions, &trans_ws->base.link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
transaction_add_workspace_group_ev(struct lab_cosmic_workspace_group *group,
 | 
			
		||||
		struct wl_resource *resource, enum pending_change change,
 | 
			
		||||
		const char *new_workspace_name)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_resource_addon *addon = wl_resource_get_user_data(resource);
 | 
			
		||||
	if (!addon) {
 | 
			
		||||
		wlr_log(WLR_ERROR, "Failed to find manager addon for group transaction");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(change == CW_PENDING_WS_CREATE);
 | 
			
		||||
 | 
			
		||||
	struct transaction_group *trans_grp = znew(*trans_grp);
 | 
			
		||||
	trans_grp->group = group;
 | 
			
		||||
	trans_grp->base.change = change;
 | 
			
		||||
	trans_grp->new_workspace_name = xstrdup(new_workspace_name);
 | 
			
		||||
	wl_list_append(&addon->ctx->transactions, &trans_grp->base.link);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1,5 @@
 | 
			
		|||
labwc_sources += files(
 | 
			
		||||
  'transaction-addon.c',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
subdir('cosmic_workspaces')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										70
									
								
								src/protocols/transaction-addon.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/protocols/transaction-addon.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <wayland-server-core.h>
 | 
			
		||||
#include "common/list.h"
 | 
			
		||||
#include "common/mem.h"
 | 
			
		||||
#include "protocols/transaction-addon.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lab_transaction_op_destroy(struct lab_transaction_op *trans_op)
 | 
			
		||||
{
 | 
			
		||||
	wl_signal_emit_mutable(&trans_op->events.destroy, trans_op);
 | 
			
		||||
	wl_list_remove(&trans_op->link);
 | 
			
		||||
	free(trans_op);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
transaction_destroy(struct wl_list *list)
 | 
			
		||||
{
 | 
			
		||||
	struct lab_transaction_op *trans_op, *trans_op_tmp;
 | 
			
		||||
	wl_list_for_each_safe(trans_op, trans_op_tmp, list, link) {
 | 
			
		||||
		lab_transaction_op_destroy(trans_op);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lab_resource_addon_destroy(struct lab_wl_resource_addon *addon)
 | 
			
		||||
{
 | 
			
		||||
	assert(addon);
 | 
			
		||||
	assert(addon->ctx);
 | 
			
		||||
 | 
			
		||||
	addon->ctx->ref_count--;
 | 
			
		||||
	assert(addon->ctx->ref_count >= 0);
 | 
			
		||||
 | 
			
		||||
	if (!addon->ctx->ref_count) {
 | 
			
		||||
		transaction_destroy(&addon->ctx->transaction_ops);
 | 
			
		||||
		free(addon->ctx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(addon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct lab_wl_resource_addon *
 | 
			
		||||
lab_resource_addon_create(struct lab_transaction_session_context *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct lab_wl_resource_addon *addon = znew(*addon);
 | 
			
		||||
	if (!ctx) {
 | 
			
		||||
		ctx = znew(*ctx);
 | 
			
		||||
		wl_list_init(&ctx->transaction_ops);
 | 
			
		||||
	}
 | 
			
		||||
	addon->ctx = ctx;
 | 
			
		||||
	addon->ctx->ref_count++;
 | 
			
		||||
	return addon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct lab_transaction_op *
 | 
			
		||||
lab_transaction_op_add(struct lab_transaction_session_context *ctx,
 | 
			
		||||
		uint32_t pending_change, void *src, void *data)
 | 
			
		||||
{
 | 
			
		||||
	assert(ctx);
 | 
			
		||||
 | 
			
		||||
	struct lab_transaction_op *trans_op = znew(*trans_op);
 | 
			
		||||
	trans_op->change = pending_change;
 | 
			
		||||
	trans_op->src = src;
 | 
			
		||||
	trans_op->data = data;
 | 
			
		||||
 | 
			
		||||
	wl_signal_init(&trans_op->events.destroy);
 | 
			
		||||
	wl_list_append(&ctx->transaction_ops, &trans_op->link);
 | 
			
		||||
 | 
			
		||||
	return trans_op;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue