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
|
|
@ -16,43 +16,6 @@ enum pending_change {
|
|||
CW_PENDING_WS_REMOVE = 1 << 3,
|
||||
};
|
||||
|
||||
struct transaction {
|
||||
uint32_t change;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct transaction_workspace {
|
||||
struct transaction base;
|
||||
struct lab_cosmic_workspace *workspace;
|
||||
};
|
||||
|
||||
struct transaction_group {
|
||||
struct transaction base;
|
||||
struct lab_cosmic_workspace_group *group;
|
||||
char *new_workspace_name;
|
||||
};
|
||||
|
||||
struct session_context {
|
||||
int ref_count;
|
||||
struct wl_list transactions;
|
||||
};
|
||||
|
||||
struct wl_resource_addon {
|
||||
struct session_context *ctx;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct wl_resource_addon *resource_addon_create(struct session_context *ctx);
|
||||
|
||||
void transaction_add_workspace_ev(struct lab_cosmic_workspace *ws,
|
||||
struct wl_resource *resource, enum pending_change change);
|
||||
|
||||
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);
|
||||
|
||||
void resource_addon_destroy(struct wl_resource_addon *addon);
|
||||
|
||||
void group_output_send_initial_state(struct lab_cosmic_workspace_group *group,
|
||||
struct wl_resource *group_resource);
|
||||
|
||||
|
|
|
|||
84
include/protocols/transaction-addon.h
Normal file
84
include/protocols/transaction-addon.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef LABWC_PROTOCOLS_TRANSACTION_ADDON_H
|
||||
#define LABWC_PROTOCOLS_TRANSACTION_ADDON_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
struct lab_transaction_op {
|
||||
uint32_t change;
|
||||
void *src;
|
||||
void *data;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
// Private
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct lab_transaction_session_context {
|
||||
int ref_count;
|
||||
struct wl_list transaction_ops;
|
||||
};
|
||||
|
||||
struct lab_wl_resource_addon {
|
||||
struct lab_transaction_session_context *ctx;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new addon which can be attached to a wl_resource via
|
||||
* wl_resource_set_user_data() and retrieved via wl_resource_get_user_data().
|
||||
*
|
||||
* Usually the ctx argument should be addon->ctx of the parent wl_resource.
|
||||
* If it is NULL it will be created automatically which can be used for top
|
||||
* level wl_resources (when a client binds a wl_global from the registry).
|
||||
*
|
||||
* The context refcount is increased by one after this call.
|
||||
*/
|
||||
struct lab_wl_resource_addon *lab_resource_addon_create(
|
||||
struct lab_transaction_session_context *ctx);
|
||||
|
||||
/*
|
||||
* A generic transaction operation attached to
|
||||
* a session context transaction operation list.
|
||||
*
|
||||
* All arguments other than the context are user defined.
|
||||
* Use of an enum for pending_change is suggested.
|
||||
*
|
||||
* The client is responsible for eventually freeing the data
|
||||
* passed in the void *src and *data arguments by listening
|
||||
* to the events.destroy signal. The transaction operations can be
|
||||
* looped through by using lab_transaction_for_each(trans_op, ctx).
|
||||
*/
|
||||
struct lab_transaction_op *lab_transaction_op_add(
|
||||
struct lab_transaction_session_context *ctx,
|
||||
uint32_t pending_change, void *src, void *data);
|
||||
|
||||
/*
|
||||
* Removes the transaction operation from the ctx list and frees it.
|
||||
*
|
||||
* Does *not* free any passed in src or data arguments.
|
||||
* Use the events.destroy signal for that if necessary.
|
||||
*/
|
||||
void lab_transaction_op_destroy(struct lab_transaction_op *transaction_op);
|
||||
|
||||
/*
|
||||
* Destroys the addon.
|
||||
*
|
||||
* The context refcount is decreased by one. If it reaches
|
||||
* zero the context will be free'd alongside the addon itself.
|
||||
* If the context is destroyed all pending transaction operations
|
||||
* are destroyed as well.
|
||||
*/
|
||||
void lab_resource_addon_destroy(struct lab_wl_resource_addon *addon);
|
||||
|
||||
/* Convinience wrappers for looping through the pending transaction ops of a ctx */
|
||||
#define lab_transaction_for_each(transaction_op, ctx) \
|
||||
wl_list_for_each(transaction_op, &(ctx)->transaction_ops, link)
|
||||
|
||||
#define lab_transaction_for_each_safe(trans_op, trans_op_tmp, ctx) \
|
||||
wl_list_for_each_safe(trans_op, trans_op_tmp, &(ctx)->transaction_ops, link)
|
||||
|
||||
#endif /* LABWC_PROTOCOLS_TRANSACTIONS_ADDON_H */
|
||||
|
|
@ -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