forked from enlightenment/enlightenment
implement wl client session recovery
another small feature patch brought to you by insomnia #SamsungFeatures
This commit is contained in:
parent
e0d1a572a1
commit
ef1772b8cb
|
@ -221,7 +221,6 @@ src/bin/e_zone.h
|
||||||
|
|
||||||
if HAVE_WAYLAND
|
if HAVE_WAYLAND
|
||||||
ENLIGHTENMENTHEADERS += \
|
ENLIGHTENMENTHEADERS += \
|
||||||
src/bin/e_uuid_store.h \
|
|
||||||
src/bin/e_comp_wl_data.h \
|
src/bin/e_comp_wl_data.h \
|
||||||
src/bin/e_comp_wl_input.h \
|
src/bin/e_comp_wl_input.h \
|
||||||
src/bin/e_comp_wl.h
|
src/bin/e_comp_wl.h
|
||||||
|
@ -394,11 +393,10 @@ endif
|
||||||
|
|
||||||
if HAVE_WAYLAND
|
if HAVE_WAYLAND
|
||||||
enlightenment_src += \
|
enlightenment_src += \
|
||||||
src/bin/e_uuid_store.c \
|
|
||||||
src/bin/generated/www-protocol.c \
|
src/bin/generated/www-protocol.c \
|
||||||
src/bin/generated/www-protocol.h \
|
src/bin/generated/www-protocol.h \
|
||||||
src/bin/generated/session-recovery-protocol.c \
|
src/bin/generated/session-recovery.c \
|
||||||
src/bin/generated/session-recovery-server-protocol.h \
|
src/bin/generated/session-recovery.h \
|
||||||
src/bin/generated/e_comp_wl_screenshooter_server.c \
|
src/bin/generated/e_comp_wl_screenshooter_server.c \
|
||||||
src/bin/generated/e_comp_wl_screenshooter_server.h \
|
src/bin/generated/e_comp_wl_screenshooter_server.h \
|
||||||
src/bin/e_comp_wl_data.c \
|
src/bin/e_comp_wl_data.c \
|
||||||
|
|
|
@ -133,7 +133,6 @@ void *alloca (size_t);
|
||||||
|
|
||||||
# ifdef HAVE_WAYLAND
|
# ifdef HAVE_WAYLAND
|
||||||
# include <Ecore_Wl2.h>
|
# include <Ecore_Wl2.h>
|
||||||
# include <uuid.h>
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef E_API
|
# ifdef E_API
|
||||||
|
|
|
@ -554,6 +554,7 @@ _e_client_free(E_Client *ec)
|
||||||
eina_stringshare_replace(&ec->netwm.icon_name, NULL);
|
eina_stringshare_replace(&ec->netwm.icon_name, NULL);
|
||||||
eina_stringshare_replace(&ec->internal_icon, NULL);
|
eina_stringshare_replace(&ec->internal_icon, NULL);
|
||||||
eina_stringshare_replace(&ec->internal_icon_key, NULL);
|
eina_stringshare_replace(&ec->internal_icon_key, NULL);
|
||||||
|
eina_stringshare_replace(&ec->uuid, NULL);
|
||||||
|
|
||||||
focus_stack = eina_list_remove(focus_stack, ec);
|
focus_stack = eina_list_remove(focus_stack, ec);
|
||||||
raise_stack = eina_list_remove(raise_stack, ec);
|
raise_stack = eina_list_remove(raise_stack, ec);
|
||||||
|
@ -570,10 +571,6 @@ _e_client_free(E_Client *ec)
|
||||||
evas_object_del(ec->frame);
|
evas_object_del(ec->frame);
|
||||||
E_OBJECT(ec)->references--;
|
E_OBJECT(ec)->references--;
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
|
||||||
e_uuid_store_entry_del(ec->uuid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(ec);
|
free(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2346,10 +2343,6 @@ e_client_new(E_Pixmap *cp, int first_map, int internal)
|
||||||
if (!ec) return NULL;
|
if (!ec) return NULL;
|
||||||
e_object_del_func_set(E_OBJECT(ec), E_OBJECT_CLEANUP_FUNC(_e_client_del));
|
e_object_del_func_set(E_OBJECT(ec), E_OBJECT_CLEANUP_FUNC(_e_client_del));
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
|
||||||
uuid_generate(ec->uuid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ec->focus_policy_override = E_FOCUS_LAST;
|
ec->focus_policy_override = E_FOCUS_LAST;
|
||||||
ec->w = 1;
|
ec->w = 1;
|
||||||
ec->h = 1;
|
ec->h = 1;
|
||||||
|
|
|
@ -686,9 +686,7 @@ struct E_Client
|
||||||
|
|
||||||
E_Focus_Policy focus_policy_override;
|
E_Focus_Policy focus_policy_override;
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
Eina_Stringshare *uuid;
|
||||||
uuid_t uuid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Eina_Bool override : 1;
|
Eina_Bool override : 1;
|
||||||
Eina_Bool input_only : 1;
|
Eina_Bool input_only : 1;
|
||||||
|
|
|
@ -1603,15 +1603,13 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_reso
|
||||||
|
|
||||||
ec = e_client_new(ep, 0, 0);
|
ec = e_client_new(ep, 0, 0);
|
||||||
}
|
}
|
||||||
if (ec)
|
if (ec->new_client)
|
||||||
{
|
e_comp->new_clients--;
|
||||||
if (ec->new_client)
|
ec->new_client = 0;
|
||||||
e_comp->new_clients--;
|
if ((!ec->client.w) && (ec->client.h))
|
||||||
ec->new_client = 0;
|
ec->client.w = ec->client.h = 1;
|
||||||
if ((!ec->client.w) && (ec->client.h))
|
ec->comp_data->surface = res;
|
||||||
ec->client.w = ec->client.h = 1;
|
ec->netwm.pid = pid;
|
||||||
ec->comp_data->surface = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set reference to pixmap so we can fetch it later */
|
/* set reference to pixmap so we can fetch it later */
|
||||||
DBG("\tUsing Client: %p", ec);
|
DBG("\tUsing Client: %p", ec);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#define E_COMP_WL
|
#define E_COMP_WL
|
||||||
#include "e.h"
|
#include "e.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <uuid.h>
|
||||||
#include "e_comp_wl_screenshooter_server.h"
|
#include "e_comp_wl_screenshooter_server.h"
|
||||||
#include "session-recovery-server-protocol.h"
|
#include "session-recovery.h"
|
||||||
#include "www-protocol.h"
|
#include "www-protocol.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -24,9 +26,62 @@ _e_comp_wl_extensions_client_move_end(void *d EINA_UNUSED, E_Client *ec)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_comp_wl_sr_cb_provide_uuid(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, const char *uuid)
|
_e_comp_wl_session_recovery_get_uuid(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *surface)
|
||||||
{
|
{
|
||||||
DBG("Provide UUID callback called for UUID: %s", uuid);
|
E_Client *ec;
|
||||||
|
uuid_t u;
|
||||||
|
char uuid[37];
|
||||||
|
|
||||||
|
ec = wl_resource_get_user_data(surface);
|
||||||
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
||||||
|
if (ec->internal || ec->uuid) return;
|
||||||
|
uuid_generate(u);
|
||||||
|
uuid_unparse_lower(u, uuid);
|
||||||
|
eina_stringshare_replace(&ec->uuid, uuid);
|
||||||
|
zwp_e_session_recovery_send_create_uuid(resource, surface, uuid);
|
||||||
|
if (ec->remember)
|
||||||
|
e_remember_unuse(ec->remember);
|
||||||
|
ec->remember = e_remember_new();
|
||||||
|
e_remember_use(ec->remember);
|
||||||
|
ec->remember->apply = E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_DESKTOP |
|
||||||
|
E_REMEMBER_APPLY_LAYER | E_REMEMBER_APPLY_ZONE | E_REMEMBER_APPLY_UUID;
|
||||||
|
e_remember_update(ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_session_recovery_set_uuid(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *surface, const char *uuid)
|
||||||
|
{
|
||||||
|
E_Client *ec;
|
||||||
|
E_Remember *rem;
|
||||||
|
|
||||||
|
ec = wl_resource_get_user_data(surface);
|
||||||
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
||||||
|
if (ec->internal || ec->uuid) return; //FIXME: error
|
||||||
|
eina_stringshare_replace(&ec->uuid, uuid);
|
||||||
|
rem = e_remember_find_usable(ec);
|
||||||
|
if ((!rem) || (rem == ec->remember)) return;
|
||||||
|
if (ec->remember)
|
||||||
|
e_remember_unuse(ec->remember);
|
||||||
|
ec->remember = rem;
|
||||||
|
e_remember_use(rem);
|
||||||
|
e_remember_apply(rem, ec);
|
||||||
|
ec->re_manage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_comp_wl_session_recovery_destroy_uuid(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *surface, const char *uuid)
|
||||||
|
{
|
||||||
|
E_Client *ec;
|
||||||
|
|
||||||
|
ec = wl_resource_get_user_data(surface);
|
||||||
|
if (!eina_streq(ec->uuid, uuid)) return; //FIXME: error
|
||||||
|
eina_stringshare_replace(&ec->uuid, NULL);
|
||||||
|
e_remember_unuse(ec->remember);
|
||||||
|
e_remember_del(ec->remember);
|
||||||
|
ec->remember = e_remember_find_usable(ec);
|
||||||
|
if (!ec->remember) return;
|
||||||
|
e_remember_use(ec->remember);
|
||||||
|
e_remember_apply(ec->remember, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -145,7 +200,9 @@ _e_comp_wl_www_cb_create(struct wl_client *client, struct wl_resource *resource,
|
||||||
|
|
||||||
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
|
||||||
{
|
{
|
||||||
_e_comp_wl_sr_cb_provide_uuid,
|
_e_comp_wl_session_recovery_get_uuid,
|
||||||
|
_e_comp_wl_session_recovery_set_uuid,
|
||||||
|
_e_comp_wl_session_recovery_destroy_uuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct screenshooter_interface _e_screenshooter_interface =
|
static const struct screenshooter_interface _e_screenshooter_interface =
|
||||||
|
|
|
@ -384,6 +384,8 @@ _e_config_edd_init(Eina_Bool old)
|
||||||
E_CONFIG_VAL(D, T, prop.desktop_file, STR);
|
E_CONFIG_VAL(D, T, prop.desktop_file, STR);
|
||||||
E_CONFIG_VAL(D, T, prop.offer_resistance, UCHAR);
|
E_CONFIG_VAL(D, T, prop.offer_resistance, UCHAR);
|
||||||
E_CONFIG_VAL(D, T, prop.opacity, UCHAR);
|
E_CONFIG_VAL(D, T, prop.opacity, UCHAR);
|
||||||
|
E_CONFIG_VAL(D, T, uuid, STR);
|
||||||
|
E_CONFIG_VAL(D, T, pid, INT);
|
||||||
|
|
||||||
_e_config_color_class_edd = E_CONFIG_DD_NEW("E_Color_Class", E_Color_Class);
|
_e_config_color_class_edd = E_CONFIG_DD_NEW("E_Color_Class", E_Color_Class);
|
||||||
#undef T
|
#undef T
|
||||||
|
|
|
@ -157,5 +157,4 @@
|
||||||
# include "e_comp_wl.h"
|
# include "e_comp_wl.h"
|
||||||
# include "e_comp_wl_data.h"
|
# include "e_comp_wl_data.h"
|
||||||
# include "e_comp_wl_input.h"
|
# include "e_comp_wl_input.h"
|
||||||
# include "e_uuid_store.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -536,19 +536,6 @@ main(int argc, char **argv)
|
||||||
_e_main_shutdown_push(e_alert_shutdown);
|
_e_main_shutdown_push(e_alert_shutdown);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
//#ifdef HAVE_WAYLAND
|
|
||||||
/* init uuid store for window/surface properties */
|
|
||||||
TS("E_UUID_Store Init");
|
|
||||||
if (!e_uuid_store_init())
|
|
||||||
{
|
|
||||||
e_error_message_show(_("Enlightenment cannot initialize its UUID store.\n"));
|
|
||||||
_e_main_shutdown(-1);
|
|
||||||
}
|
|
||||||
TS("E_UUID_Store Init Done");
|
|
||||||
_e_main_shutdown_push(e_uuid_store_shutdown);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TS("E Directories Init");
|
TS("E Directories Init");
|
||||||
/* setup directories we will be using for configurations storage etc. */
|
/* setup directories we will be using for configurations storage etc. */
|
||||||
if (!_e_main_dirs_init())
|
if (!_e_main_dirs_init())
|
||||||
|
|
|
@ -268,411 +268,10 @@ e_remember_del(E_Remember *rem)
|
||||||
_e_remember_free(rem);
|
_e_remember_free(rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
E_API E_Remember *
|
|
||||||
e_remember_find_usable(E_Client *ec)
|
|
||||||
{
|
|
||||||
E_Remember *rem;
|
|
||||||
|
|
||||||
rem = _e_remember_find(ec, 1);
|
|
||||||
return rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
E_API E_Remember *
|
|
||||||
e_remember_find(E_Client *ec)
|
|
||||||
{
|
|
||||||
E_Remember *rem;
|
|
||||||
|
|
||||||
rem = _e_remember_find(ec, 0);
|
|
||||||
return rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
E_API void
|
E_API void
|
||||||
e_remember_match_update(E_Remember *rem)
|
e_remember_apply(E_Remember *rem, E_Client *ec)
|
||||||
{
|
{
|
||||||
int max_count = 0;
|
|
||||||
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_NAME) max_count += 2;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_CLASS) max_count += 2;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TITLE) max_count += 2;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_ROLE) max_count += 2;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TYPE) max_count += 2;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TRANSIENT) max_count += 2;
|
|
||||||
if (rem->apply_first_only) max_count++;
|
|
||||||
|
|
||||||
if (max_count != rem->max_score)
|
|
||||||
{
|
|
||||||
/* The number of matches for this remember has changed so we
|
|
||||||
* need to remove from list and insert back into the appropriate
|
|
||||||
* location. */
|
|
||||||
Eina_List *l = NULL;
|
|
||||||
E_Remember *r;
|
|
||||||
|
|
||||||
rem->max_score = max_count;
|
|
||||||
e_config->remembers = eina_list_remove(e_config->remembers, rem);
|
|
||||||
|
|
||||||
EINA_LIST_FOREACH(e_config->remembers, l, r)
|
|
||||||
{
|
|
||||||
if (r->max_score <= rem->max_score) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l)
|
|
||||||
e_config->remembers = eina_list_prepend_relative_list(e_config->remembers, rem, l);
|
|
||||||
else
|
|
||||||
e_config->remembers = eina_list_append(e_config->remembers, rem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
E_API int
|
|
||||||
e_remember_default_match_set(E_Remember *rem, E_Client *ec)
|
|
||||||
{
|
|
||||||
const char *title, *clasz, *name, *role;
|
|
||||||
int match;
|
|
||||||
|
|
||||||
eina_stringshare_replace(&rem->name, NULL);
|
|
||||||
eina_stringshare_replace(&rem->class, NULL);
|
|
||||||
eina_stringshare_replace(&rem->title, NULL);
|
|
||||||
eina_stringshare_replace(&rem->role, NULL);
|
|
||||||
|
|
||||||
name = ec->icccm.name;
|
|
||||||
if (!name || name[0] == 0) name = NULL;
|
|
||||||
clasz = ec->icccm.class;
|
|
||||||
if (!clasz || clasz[0] == 0) clasz = NULL;
|
|
||||||
role = ec->icccm.window_role;
|
|
||||||
if (!role || role[0] == 0) role = NULL;
|
|
||||||
|
|
||||||
match = E_REMEMBER_MATCH_TRANSIENT;
|
|
||||||
if (ec->icccm.transient_for != 0)
|
|
||||||
rem->transient = 1;
|
|
||||||
else
|
|
||||||
rem->transient = 0;
|
|
||||||
|
|
||||||
if (name && clasz)
|
|
||||||
{
|
|
||||||
match |= E_REMEMBER_MATCH_NAME | E_REMEMBER_MATCH_CLASS;
|
|
||||||
rem->name = eina_stringshare_ref(name);
|
|
||||||
rem->class = eina_stringshare_ref(clasz);
|
|
||||||
}
|
|
||||||
else if ((title = e_client_util_name_get(ec)) && title[0])
|
|
||||||
{
|
|
||||||
match |= E_REMEMBER_MATCH_TITLE;
|
|
||||||
rem->title = eina_stringshare_ref(title);
|
|
||||||
}
|
|
||||||
if (role)
|
|
||||||
{
|
|
||||||
match |= E_REMEMBER_MATCH_ROLE;
|
|
||||||
rem->role = eina_stringshare_ref(role);
|
|
||||||
}
|
|
||||||
if (ec->netwm.type != E_WINDOW_TYPE_UNKNOWN)
|
|
||||||
{
|
|
||||||
match |= E_REMEMBER_MATCH_TYPE;
|
|
||||||
rem->type = ec->netwm.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
rem->match = match;
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
E_API void
|
|
||||||
e_remember_update(E_Client *ec)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_WAYLAND
|
|
||||||
/* Use this as e_remeber_update is called in all the right places already */
|
|
||||||
e_uuid_store_entry_update(ec->uuid, ec);
|
|
||||||
#endif
|
|
||||||
if (ec->new_client) return;
|
|
||||||
if (!ec->remember) return;
|
|
||||||
if (ec->remember->keep_settings) return;
|
|
||||||
_e_remember_update(ec, ec->remember);
|
|
||||||
e_config_save_queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_e_remember_event_free(void *d EINA_UNUSED, void *event)
|
|
||||||
{
|
|
||||||
E_Event_Remember_Update *ev = event;
|
|
||||||
UNREFD(ev->ec, 10);
|
|
||||||
e_object_unref(E_OBJECT(ev->ec));
|
|
||||||
free(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_e_remember_update(E_Client *ec, E_Remember *rem)
|
|
||||||
{
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_POS ||
|
|
||||||
rem->apply & E_REMEMBER_APPLY_SIZE)
|
|
||||||
{
|
|
||||||
if (ec->fullscreen || ec->maximized)
|
|
||||||
{
|
|
||||||
rem->prop.pos_x = ec->saved.x;
|
|
||||||
rem->prop.pos_y = ec->saved.y;
|
|
||||||
rem->prop.pos_w = ec->saved.w;
|
|
||||||
rem->prop.pos_h = ec->saved.h;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rem->prop.pos_x = ec->x - ec->zone->x;
|
|
||||||
rem->prop.pos_y = ec->y - ec->zone->y;
|
|
||||||
rem->prop.res_x = ec->zone->w;
|
|
||||||
rem->prop.res_y = ec->zone->h;
|
|
||||||
rem->prop.pos_w = ec->client.w;
|
|
||||||
rem->prop.pos_h = ec->client.h;
|
|
||||||
rem->prop.w = ec->client.w;
|
|
||||||
rem->prop.h = ec->client.h;
|
|
||||||
}
|
|
||||||
rem->prop.maximize = ec->maximized & E_MAXIMIZE_DIRECTION;
|
|
||||||
}
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_LAYER)
|
|
||||||
{
|
|
||||||
if (ec->fullscreen)
|
|
||||||
rem->prop.layer = ec->saved.layer;
|
|
||||||
else
|
|
||||||
rem->prop.layer = ec->layer;
|
|
||||||
}
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_LOCKS)
|
|
||||||
{
|
|
||||||
rem->prop.lock_user_location = ec->lock_user_location;
|
|
||||||
rem->prop.lock_client_location = ec->lock_client_location;
|
|
||||||
rem->prop.lock_user_size = ec->lock_user_size;
|
|
||||||
rem->prop.lock_client_size = ec->lock_client_size;
|
|
||||||
rem->prop.lock_user_stacking = ec->lock_user_stacking;
|
|
||||||
rem->prop.lock_client_stacking = ec->lock_client_stacking;
|
|
||||||
rem->prop.lock_user_iconify = ec->lock_user_iconify;
|
|
||||||
rem->prop.lock_client_iconify = ec->lock_client_iconify;
|
|
||||||
rem->prop.lock_user_desk = ec->lock_user_desk;
|
|
||||||
rem->prop.lock_client_desk = ec->lock_client_desk;
|
|
||||||
rem->prop.lock_user_sticky = ec->lock_user_sticky;
|
|
||||||
rem->prop.lock_client_sticky = ec->lock_client_sticky;
|
|
||||||
rem->prop.lock_user_shade = ec->lock_user_shade;
|
|
||||||
rem->prop.lock_client_shade = ec->lock_client_shade;
|
|
||||||
rem->prop.lock_user_maximize = ec->lock_user_maximize;
|
|
||||||
rem->prop.lock_client_maximize = ec->lock_client_maximize;
|
|
||||||
rem->prop.lock_user_fullscreen = ec->lock_user_fullscreen;
|
|
||||||
rem->prop.lock_client_fullscreen = ec->lock_client_fullscreen;
|
|
||||||
rem->prop.lock_border = ec->lock_border;
|
|
||||||
rem->prop.lock_close = ec->lock_close;
|
|
||||||
rem->prop.lock_focus_in = ec->lock_focus_in;
|
|
||||||
rem->prop.lock_focus_out = ec->lock_focus_out;
|
|
||||||
rem->prop.lock_life = ec->lock_life;
|
|
||||||
}
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_SHADE)
|
|
||||||
{
|
|
||||||
if (ec->shaded)
|
|
||||||
rem->prop.shaded = (100 + ec->shade_dir);
|
|
||||||
else
|
|
||||||
rem->prop.shaded = (50 + ec->shade_dir);
|
|
||||||
}
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_ZONE)
|
|
||||||
{
|
|
||||||
rem->prop.zone = ec->zone->num;
|
|
||||||
}
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST)
|
|
||||||
rem->prop.skip_winlist = ec->user_skip_winlist;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_STICKY)
|
|
||||||
rem->prop.sticky = ec->sticky;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER)
|
|
||||||
rem->prop.skip_pager = ec->netwm.state.skip_pager;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR)
|
|
||||||
rem->prop.skip_taskbar = ec->netwm.state.skip_taskbar;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_ICON_PREF)
|
|
||||||
rem->prop.icon_preference = ec->icon_preference;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_DESKTOP)
|
|
||||||
e_desk_xy_get(ec->desk, &rem->prop.desk_x, &rem->prop.desk_y);
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_FULLSCREEN)
|
|
||||||
rem->prop.fullscreen = ec->fullscreen;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_OFFER_RESISTANCE)
|
|
||||||
rem->prop.offer_resistance = ec->offer_resistance;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_OPACITY)
|
|
||||||
rem->prop.opacity = ec->netwm.opacity;
|
|
||||||
if (rem->apply & E_REMEMBER_APPLY_BORDER)
|
|
||||||
{
|
|
||||||
if (ec->borderless)
|
|
||||||
eina_stringshare_replace(&rem->prop.border, "borderless");
|
|
||||||
else
|
|
||||||
eina_stringshare_replace(&rem->prop.border, ec->bordername);
|
|
||||||
}
|
|
||||||
rem->no_reopen = ec->internal_no_reopen;
|
|
||||||
{
|
|
||||||
E_Event_Remember_Update *ev;
|
|
||||||
|
|
||||||
ev = malloc(sizeof(E_Event_Remember_Update));
|
|
||||||
if (!ev) return;
|
|
||||||
ev->ec = ec;
|
|
||||||
REFD(ec, 10);
|
|
||||||
e_object_ref(E_OBJECT(ec));
|
|
||||||
ecore_event_add(E_EVENT_REMEMBER_UPDATE, ev, _e_remember_event_free, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* local subsystem functions */
|
|
||||||
static E_Remember *
|
|
||||||
_e_remember_find(E_Client *ec, int check_usable)
|
|
||||||
{
|
|
||||||
Eina_List *l = NULL;
|
|
||||||
E_Remember *rem;
|
|
||||||
|
|
||||||
#if REMEMBER_SIMPLE
|
|
||||||
EINA_LIST_FOREACH(e_config->remembers, l, rem)
|
|
||||||
{
|
|
||||||
int required_matches;
|
|
||||||
int matches;
|
|
||||||
const char *title = "";
|
|
||||||
|
|
||||||
matches = 0;
|
|
||||||
required_matches = 0;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_NAME) required_matches++;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_CLASS) required_matches++;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TITLE) required_matches++;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_ROLE) required_matches++;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TYPE) required_matches++;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TRANSIENT) required_matches++;
|
|
||||||
|
|
||||||
if (ec->netwm.name) title = ec->netwm.name;
|
|
||||||
else title = ec->icccm.title;
|
|
||||||
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_NAME) &&
|
|
||||||
((!e_util_strcmp(rem->name, ec->icccm.name)) ||
|
|
||||||
(e_util_both_str_empty(rem->name, ec->icccm.name))))
|
|
||||||
matches++;
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_CLASS) &&
|
|
||||||
((!e_util_strcmp(rem->class, ec->icccm.class)) ||
|
|
||||||
(e_util_both_str_empty(rem->class, ec->icccm.class))))
|
|
||||||
matches++;
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_TITLE) &&
|
|
||||||
((!e_util_strcmp(rem->title, title)) ||
|
|
||||||
(e_util_both_str_empty(rem->title, title))))
|
|
||||||
matches++;
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_ROLE) &&
|
|
||||||
((!e_util_strcmp(rem->role, ec->icccm.window_role)) ||
|
|
||||||
(e_util_both_str_empty(rem->role, ec->icccm.window_role))))
|
|
||||||
matches++;
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_TYPE) &&
|
|
||||||
(rem->type == ec->netwm.type))
|
|
||||||
matches++;
|
|
||||||
if ((rem->match & E_REMEMBER_MATCH_TRANSIENT) &&
|
|
||||||
(((rem->transient) && (ec->icccm.transient_for != 0)) ||
|
|
||||||
((!rem->transient) && (ec->icccm.transient_for == 0))))
|
|
||||||
matches++;
|
|
||||||
if (matches >= required_matches)
|
|
||||||
return rem;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
#if REMEMBER_HIERARCHY
|
|
||||||
/* This search method finds the best possible match available and is
|
|
||||||
* based on the fact that the list is sorted, with those remembers
|
|
||||||
* with the most possible matches at the start of the list. This
|
|
||||||
* means, as soon as a valid match is found, it is a match
|
|
||||||
* within the set of best possible matches. */
|
|
||||||
EINA_LIST_FOREACH(e_config->remembers, l, rem)
|
|
||||||
{
|
|
||||||
const char *title = "";
|
|
||||||
|
|
||||||
if ((check_usable) && (!e_remember_usable_get(rem)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ec->netwm.name) title = ec->netwm.name;
|
|
||||||
else title = ec->icccm.title;
|
|
||||||
|
|
||||||
/* For each type of match, check whether the match is
|
|
||||||
* required, and if it is, check whether there's a match. If
|
|
||||||
* it fails, then go to the next remember */
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_NAME &&
|
|
||||||
!e_util_glob_match(ec->icccm.name, rem->name))
|
|
||||||
continue;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_CLASS &&
|
|
||||||
!e_util_glob_match(ec->icccm.class, rem->class))
|
|
||||||
continue;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TITLE &&
|
|
||||||
!e_util_glob_match(title, rem->title))
|
|
||||||
continue;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_ROLE &&
|
|
||||||
e_util_strcmp(rem->role, ec->icccm.window_role) &&
|
|
||||||
!e_util_both_str_empty(rem->role, ec->icccm.window_role))
|
|
||||||
continue;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TYPE &&
|
|
||||||
rem->type != (int)ec->netwm.type)
|
|
||||||
continue;
|
|
||||||
if (rem->match & E_REMEMBER_MATCH_TRANSIENT &&
|
|
||||||
!(rem->transient && ec->icccm.transient_for != 0) &&
|
|
||||||
!(!rem->transient) && (ec->icccm.transient_for == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_e_remember_free(E_Remember *rem)
|
|
||||||
{
|
|
||||||
e_config->remembers = eina_list_remove(e_config->remembers, rem);
|
|
||||||
if (rem->name) eina_stringshare_del(rem->name);
|
|
||||||
if (rem->class) eina_stringshare_del(rem->class);
|
|
||||||
if (rem->title) eina_stringshare_del(rem->title);
|
|
||||||
if (rem->role) eina_stringshare_del(rem->role);
|
|
||||||
if (rem->prop.border) eina_stringshare_del(rem->prop.border);
|
|
||||||
if (rem->prop.command) eina_stringshare_del(rem->prop.command);
|
|
||||||
if (rem->prop.desktop_file) eina_stringshare_del(rem->prop.desktop_file);
|
|
||||||
free(rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_e_remember_cb_hook_eval_post_new_client(void *data EINA_UNUSED, E_Client *ec)
|
|
||||||
{
|
|
||||||
// remember only when window was modified
|
|
||||||
// if (!ec->new_client) return;
|
|
||||||
if (e_client_util_ignored_get(ec)) return;
|
|
||||||
if ((ec->internal) && (!ec->remember) &&
|
|
||||||
(e_config->remember_internal_windows) &&
|
|
||||||
(!ec->internal_no_remember) &&
|
|
||||||
(ec->icccm.class && ec->icccm.class[0]))
|
|
||||||
{
|
|
||||||
E_Remember *rem;
|
|
||||||
|
|
||||||
if (!strncmp(ec->icccm.class, "e_fwin", 6))
|
|
||||||
{
|
|
||||||
if (!e_config->remember_internal_fm_windows) return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!e_config->remember_internal_windows)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rem = e_remember_new();
|
|
||||||
if (!rem) return;
|
|
||||||
|
|
||||||
e_remember_default_match_set(rem, ec);
|
|
||||||
|
|
||||||
rem->apply = E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_SIZE | E_REMEMBER_APPLY_BORDER;
|
|
||||||
|
|
||||||
e_remember_use(rem);
|
|
||||||
e_remember_update(ec);
|
|
||||||
ec->remember = rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_e_remember_cb_hook_pre_post_fetch(void *data EINA_UNUSED, E_Client *ec)
|
|
||||||
{
|
|
||||||
E_Remember *rem = NULL;
|
|
||||||
int temporary = 0;
|
int temporary = 0;
|
||||||
|
|
||||||
if ((!ec->new_client) || ec->internal_no_remember || e_client_util_ignored_get(ec)) return;
|
|
||||||
|
|
||||||
if (!ec->remember)
|
|
||||||
{
|
|
||||||
rem = e_remember_find_usable(ec);
|
|
||||||
if (rem)
|
|
||||||
{
|
|
||||||
ec->remember = rem;
|
|
||||||
e_remember_use(rem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ec->internal && remembers && ec->icccm.class && ec->icccm.class[0])
|
if (ec->internal && remembers && ec->icccm.class && ec->icccm.class[0])
|
||||||
{
|
{
|
||||||
Eina_List *l;
|
Eina_List *l;
|
||||||
|
@ -952,6 +551,423 @@ _e_remember_cb_hook_pre_post_fetch(void *data EINA_UNUSED, E_Client *ec)
|
||||||
_e_remember_free(rem);
|
_e_remember_free(rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
E_API E_Remember *
|
||||||
|
e_remember_find_usable(E_Client *ec)
|
||||||
|
{
|
||||||
|
E_Remember *rem;
|
||||||
|
|
||||||
|
rem = _e_remember_find(ec, 1);
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_API E_Remember *
|
||||||
|
e_remember_find(E_Client *ec)
|
||||||
|
{
|
||||||
|
E_Remember *rem;
|
||||||
|
|
||||||
|
rem = _e_remember_find(ec, 0);
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_API void
|
||||||
|
e_remember_match_update(E_Remember *rem)
|
||||||
|
{
|
||||||
|
int max_count = 0;
|
||||||
|
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_NAME) max_count += 2;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_CLASS) max_count += 2;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TITLE) max_count += 2;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_ROLE) max_count += 2;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TYPE) max_count += 2;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TRANSIENT) max_count += 2;
|
||||||
|
if (rem->apply_first_only) max_count++;
|
||||||
|
|
||||||
|
if (max_count != rem->max_score)
|
||||||
|
{
|
||||||
|
/* The number of matches for this remember has changed so we
|
||||||
|
* need to remove from list and insert back into the appropriate
|
||||||
|
* location. */
|
||||||
|
Eina_List *l = NULL;
|
||||||
|
E_Remember *r;
|
||||||
|
|
||||||
|
rem->max_score = max_count;
|
||||||
|
e_config->remembers = eina_list_remove(e_config->remembers, rem);
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(e_config->remembers, l, r)
|
||||||
|
{
|
||||||
|
if (r->max_score <= rem->max_score) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l)
|
||||||
|
e_config->remembers = eina_list_prepend_relative_list(e_config->remembers, rem, l);
|
||||||
|
else
|
||||||
|
e_config->remembers = eina_list_append(e_config->remembers, rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
E_API int
|
||||||
|
e_remember_default_match_set(E_Remember *rem, E_Client *ec)
|
||||||
|
{
|
||||||
|
const char *title, *clasz, *name, *role;
|
||||||
|
int match;
|
||||||
|
|
||||||
|
eina_stringshare_replace(&rem->name, NULL);
|
||||||
|
eina_stringshare_replace(&rem->class, NULL);
|
||||||
|
eina_stringshare_replace(&rem->title, NULL);
|
||||||
|
eina_stringshare_replace(&rem->role, NULL);
|
||||||
|
|
||||||
|
name = ec->icccm.name;
|
||||||
|
if (!name || name[0] == 0) name = NULL;
|
||||||
|
clasz = ec->icccm.class;
|
||||||
|
if (!clasz || clasz[0] == 0) clasz = NULL;
|
||||||
|
role = ec->icccm.window_role;
|
||||||
|
if (!role || role[0] == 0) role = NULL;
|
||||||
|
|
||||||
|
match = E_REMEMBER_MATCH_TRANSIENT;
|
||||||
|
if (ec->icccm.transient_for != 0)
|
||||||
|
rem->transient = 1;
|
||||||
|
else
|
||||||
|
rem->transient = 0;
|
||||||
|
|
||||||
|
if (name && clasz)
|
||||||
|
{
|
||||||
|
match |= E_REMEMBER_MATCH_NAME | E_REMEMBER_MATCH_CLASS;
|
||||||
|
rem->name = eina_stringshare_ref(name);
|
||||||
|
rem->class = eina_stringshare_ref(clasz);
|
||||||
|
}
|
||||||
|
else if ((title = e_client_util_name_get(ec)) && title[0])
|
||||||
|
{
|
||||||
|
match |= E_REMEMBER_MATCH_TITLE;
|
||||||
|
rem->title = eina_stringshare_ref(title);
|
||||||
|
}
|
||||||
|
if (role)
|
||||||
|
{
|
||||||
|
match |= E_REMEMBER_MATCH_ROLE;
|
||||||
|
rem->role = eina_stringshare_ref(role);
|
||||||
|
}
|
||||||
|
if (ec->netwm.type != E_WINDOW_TYPE_UNKNOWN)
|
||||||
|
{
|
||||||
|
match |= E_REMEMBER_MATCH_TYPE;
|
||||||
|
rem->type = ec->netwm.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
rem->match = match;
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_API void
|
||||||
|
e_remember_update(E_Client *ec)
|
||||||
|
{
|
||||||
|
if (ec->new_client) return;
|
||||||
|
if (!ec->remember) return;
|
||||||
|
if (ec->remember->keep_settings) return;
|
||||||
|
_e_remember_update(ec, ec->remember);
|
||||||
|
e_config_save_queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_remember_event_free(void *d EINA_UNUSED, void *event)
|
||||||
|
{
|
||||||
|
E_Event_Remember_Update *ev = event;
|
||||||
|
UNREFD(ev->ec, 10);
|
||||||
|
e_object_unref(E_OBJECT(ev->ec));
|
||||||
|
free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_remember_update(E_Client *ec, E_Remember *rem)
|
||||||
|
{
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_POS ||
|
||||||
|
rem->apply & E_REMEMBER_APPLY_SIZE)
|
||||||
|
{
|
||||||
|
if (ec->fullscreen || ec->maximized)
|
||||||
|
{
|
||||||
|
rem->prop.pos_x = ec->saved.x;
|
||||||
|
rem->prop.pos_y = ec->saved.y;
|
||||||
|
rem->prop.pos_w = ec->saved.w;
|
||||||
|
rem->prop.pos_h = ec->saved.h;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rem->prop.pos_x = ec->x - ec->zone->x;
|
||||||
|
rem->prop.pos_y = ec->y - ec->zone->y;
|
||||||
|
rem->prop.res_x = ec->zone->w;
|
||||||
|
rem->prop.res_y = ec->zone->h;
|
||||||
|
rem->prop.pos_w = ec->client.w;
|
||||||
|
rem->prop.pos_h = ec->client.h;
|
||||||
|
rem->prop.w = ec->client.w;
|
||||||
|
rem->prop.h = ec->client.h;
|
||||||
|
}
|
||||||
|
rem->prop.maximize = ec->maximized & E_MAXIMIZE_DIRECTION;
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_LAYER)
|
||||||
|
{
|
||||||
|
if (ec->fullscreen)
|
||||||
|
rem->prop.layer = ec->saved.layer;
|
||||||
|
else
|
||||||
|
rem->prop.layer = ec->layer;
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_LOCKS)
|
||||||
|
{
|
||||||
|
rem->prop.lock_user_location = ec->lock_user_location;
|
||||||
|
rem->prop.lock_client_location = ec->lock_client_location;
|
||||||
|
rem->prop.lock_user_size = ec->lock_user_size;
|
||||||
|
rem->prop.lock_client_size = ec->lock_client_size;
|
||||||
|
rem->prop.lock_user_stacking = ec->lock_user_stacking;
|
||||||
|
rem->prop.lock_client_stacking = ec->lock_client_stacking;
|
||||||
|
rem->prop.lock_user_iconify = ec->lock_user_iconify;
|
||||||
|
rem->prop.lock_client_iconify = ec->lock_client_iconify;
|
||||||
|
rem->prop.lock_user_desk = ec->lock_user_desk;
|
||||||
|
rem->prop.lock_client_desk = ec->lock_client_desk;
|
||||||
|
rem->prop.lock_user_sticky = ec->lock_user_sticky;
|
||||||
|
rem->prop.lock_client_sticky = ec->lock_client_sticky;
|
||||||
|
rem->prop.lock_user_shade = ec->lock_user_shade;
|
||||||
|
rem->prop.lock_client_shade = ec->lock_client_shade;
|
||||||
|
rem->prop.lock_user_maximize = ec->lock_user_maximize;
|
||||||
|
rem->prop.lock_client_maximize = ec->lock_client_maximize;
|
||||||
|
rem->prop.lock_user_fullscreen = ec->lock_user_fullscreen;
|
||||||
|
rem->prop.lock_client_fullscreen = ec->lock_client_fullscreen;
|
||||||
|
rem->prop.lock_border = ec->lock_border;
|
||||||
|
rem->prop.lock_close = ec->lock_close;
|
||||||
|
rem->prop.lock_focus_in = ec->lock_focus_in;
|
||||||
|
rem->prop.lock_focus_out = ec->lock_focus_out;
|
||||||
|
rem->prop.lock_life = ec->lock_life;
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_SHADE)
|
||||||
|
{
|
||||||
|
if (ec->shaded)
|
||||||
|
rem->prop.shaded = (100 + ec->shade_dir);
|
||||||
|
else
|
||||||
|
rem->prop.shaded = (50 + ec->shade_dir);
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_ZONE)
|
||||||
|
{
|
||||||
|
rem->prop.zone = ec->zone->num;
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST)
|
||||||
|
rem->prop.skip_winlist = ec->user_skip_winlist;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_STICKY)
|
||||||
|
rem->prop.sticky = ec->sticky;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER)
|
||||||
|
rem->prop.skip_pager = ec->netwm.state.skip_pager;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR)
|
||||||
|
rem->prop.skip_taskbar = ec->netwm.state.skip_taskbar;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_ICON_PREF)
|
||||||
|
rem->prop.icon_preference = ec->icon_preference;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_DESKTOP)
|
||||||
|
e_desk_xy_get(ec->desk, &rem->prop.desk_x, &rem->prop.desk_y);
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_FULLSCREEN)
|
||||||
|
rem->prop.fullscreen = ec->fullscreen;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_OFFER_RESISTANCE)
|
||||||
|
rem->prop.offer_resistance = ec->offer_resistance;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_OPACITY)
|
||||||
|
rem->prop.opacity = ec->netwm.opacity;
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_BORDER)
|
||||||
|
{
|
||||||
|
if (ec->borderless)
|
||||||
|
eina_stringshare_replace(&rem->prop.border, "borderless");
|
||||||
|
else
|
||||||
|
eina_stringshare_replace(&rem->prop.border, ec->bordername);
|
||||||
|
}
|
||||||
|
if (rem->apply & E_REMEMBER_APPLY_UUID)
|
||||||
|
{
|
||||||
|
eina_stringshare_refplace(&rem->uuid, ec->uuid);
|
||||||
|
rem->pid = ec->netwm.pid;
|
||||||
|
rem->apply_first_only = 1;
|
||||||
|
}
|
||||||
|
rem->no_reopen = ec->internal_no_reopen;
|
||||||
|
{
|
||||||
|
E_Event_Remember_Update *ev;
|
||||||
|
|
||||||
|
ev = malloc(sizeof(E_Event_Remember_Update));
|
||||||
|
if (!ev) return;
|
||||||
|
ev->ec = ec;
|
||||||
|
REFD(ec, 10);
|
||||||
|
e_object_ref(E_OBJECT(ec));
|
||||||
|
ecore_event_add(E_EVENT_REMEMBER_UPDATE, ev, _e_remember_event_free, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* local subsystem functions */
|
||||||
|
static E_Remember *
|
||||||
|
_e_remember_find(E_Client *ec, int check_usable)
|
||||||
|
{
|
||||||
|
Eina_List *l = NULL;
|
||||||
|
E_Remember *rem;
|
||||||
|
|
||||||
|
#if REMEMBER_SIMPLE
|
||||||
|
EINA_LIST_FOREACH(e_config->remembers, l, rem)
|
||||||
|
{
|
||||||
|
int required_matches;
|
||||||
|
int matches;
|
||||||
|
const char *title = "";
|
||||||
|
|
||||||
|
matches = 0;
|
||||||
|
required_matches = 0;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_NAME) required_matches++;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_CLASS) required_matches++;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TITLE) required_matches++;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_ROLE) required_matches++;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TYPE) required_matches++;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TRANSIENT) required_matches++;
|
||||||
|
|
||||||
|
if (ec->netwm.name) title = ec->netwm.name;
|
||||||
|
else title = ec->icccm.title;
|
||||||
|
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_NAME) &&
|
||||||
|
((!e_util_strcmp(rem->name, ec->icccm.name)) ||
|
||||||
|
(e_util_both_str_empty(rem->name, ec->icccm.name))))
|
||||||
|
matches++;
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_CLASS) &&
|
||||||
|
((!e_util_strcmp(rem->class, ec->icccm.class)) ||
|
||||||
|
(e_util_both_str_empty(rem->class, ec->icccm.class))))
|
||||||
|
matches++;
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_TITLE) &&
|
||||||
|
((!e_util_strcmp(rem->title, title)) ||
|
||||||
|
(e_util_both_str_empty(rem->title, title))))
|
||||||
|
matches++;
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_ROLE) &&
|
||||||
|
((!e_util_strcmp(rem->role, ec->icccm.window_role)) ||
|
||||||
|
(e_util_both_str_empty(rem->role, ec->icccm.window_role))))
|
||||||
|
matches++;
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_TYPE) &&
|
||||||
|
(rem->type == ec->netwm.type))
|
||||||
|
matches++;
|
||||||
|
if ((rem->match & E_REMEMBER_MATCH_TRANSIENT) &&
|
||||||
|
(((rem->transient) && (ec->icccm.transient_for != 0)) ||
|
||||||
|
((!rem->transient) && (ec->icccm.transient_for == 0))))
|
||||||
|
matches++;
|
||||||
|
if (matches >= required_matches)
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
#if REMEMBER_HIERARCHY
|
||||||
|
/* This search method finds the best possible match available and is
|
||||||
|
* based on the fact that the list is sorted, with those remembers
|
||||||
|
* with the most possible matches at the start of the list. This
|
||||||
|
* means, as soon as a valid match is found, it is a match
|
||||||
|
* within the set of best possible matches. */
|
||||||
|
EINA_LIST_FOREACH(e_config->remembers, l, rem)
|
||||||
|
{
|
||||||
|
const char *title = "";
|
||||||
|
|
||||||
|
if ((check_usable) && (!e_remember_usable_get(rem)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!eina_streq(rem->uuid, ec->uuid)) continue;
|
||||||
|
if (rem->uuid)
|
||||||
|
{
|
||||||
|
if (rem->pid != ec->netwm.pid) continue;
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ec->netwm.name) title = ec->netwm.name;
|
||||||
|
else title = ec->icccm.title;
|
||||||
|
|
||||||
|
/* For each type of match, check whether the match is
|
||||||
|
* required, and if it is, check whether there's a match. If
|
||||||
|
* it fails, then go to the next remember */
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_NAME &&
|
||||||
|
!e_util_glob_match(ec->icccm.name, rem->name))
|
||||||
|
continue;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_CLASS &&
|
||||||
|
!e_util_glob_match(ec->icccm.class, rem->class))
|
||||||
|
continue;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TITLE &&
|
||||||
|
!e_util_glob_match(title, rem->title))
|
||||||
|
continue;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_ROLE &&
|
||||||
|
e_util_strcmp(rem->role, ec->icccm.window_role) &&
|
||||||
|
!e_util_both_str_empty(rem->role, ec->icccm.window_role))
|
||||||
|
continue;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TYPE &&
|
||||||
|
rem->type != (int)ec->netwm.type)
|
||||||
|
continue;
|
||||||
|
if (rem->match & E_REMEMBER_MATCH_TRANSIENT &&
|
||||||
|
!(rem->transient && ec->icccm.transient_for != 0) &&
|
||||||
|
!(!rem->transient) && (ec->icccm.transient_for == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_remember_free(E_Remember *rem)
|
||||||
|
{
|
||||||
|
e_config->remembers = eina_list_remove(e_config->remembers, rem);
|
||||||
|
if (rem->name) eina_stringshare_del(rem->name);
|
||||||
|
if (rem->class) eina_stringshare_del(rem->class);
|
||||||
|
if (rem->title) eina_stringshare_del(rem->title);
|
||||||
|
if (rem->role) eina_stringshare_del(rem->role);
|
||||||
|
if (rem->prop.border) eina_stringshare_del(rem->prop.border);
|
||||||
|
if (rem->prop.command) eina_stringshare_del(rem->prop.command);
|
||||||
|
if (rem->prop.desktop_file) eina_stringshare_del(rem->prop.desktop_file);
|
||||||
|
eina_stringshare_del(rem->uuid);
|
||||||
|
free(rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_remember_cb_hook_eval_post_new_client(void *data EINA_UNUSED, E_Client *ec)
|
||||||
|
{
|
||||||
|
// remember only when window was modified
|
||||||
|
// if (!ec->new_client) return;
|
||||||
|
if (e_client_util_ignored_get(ec)) return;
|
||||||
|
if ((ec->internal) && (!ec->remember) &&
|
||||||
|
(e_config->remember_internal_windows) &&
|
||||||
|
(!ec->internal_no_remember) &&
|
||||||
|
(ec->icccm.class && ec->icccm.class[0]))
|
||||||
|
{
|
||||||
|
E_Remember *rem;
|
||||||
|
|
||||||
|
if (!strncmp(ec->icccm.class, "e_fwin", 6))
|
||||||
|
{
|
||||||
|
if (!e_config->remember_internal_fm_windows) return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!e_config->remember_internal_windows)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rem = e_remember_new();
|
||||||
|
if (!rem) return;
|
||||||
|
|
||||||
|
e_remember_default_match_set(rem, ec);
|
||||||
|
|
||||||
|
rem->apply = E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_SIZE | E_REMEMBER_APPLY_BORDER;
|
||||||
|
|
||||||
|
e_remember_use(rem);
|
||||||
|
e_remember_update(ec);
|
||||||
|
ec->remember = rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e_remember_cb_hook_pre_post_fetch(void *data EINA_UNUSED, E_Client *ec)
|
||||||
|
{
|
||||||
|
E_Remember *rem = NULL;
|
||||||
|
|
||||||
|
if ((!ec->new_client) || ec->internal_no_remember || e_client_util_ignored_get(ec)) return;
|
||||||
|
|
||||||
|
if (!ec->remember)
|
||||||
|
{
|
||||||
|
rem = e_remember_find_usable(ec);
|
||||||
|
if (rem)
|
||||||
|
{
|
||||||
|
ec->remember = rem;
|
||||||
|
e_remember_use(rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e_remember_apply(rem, ec);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_remember_init_edd(void)
|
_e_remember_init_edd(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct _E_Remember E_Remember;
|
||||||
#define E_REMEMBER_APPLY_FULLSCREEN (1 << 15)
|
#define E_REMEMBER_APPLY_FULLSCREEN (1 << 15)
|
||||||
#define E_REMEMBER_APPLY_OFFER_RESISTANCE (1 << 16)
|
#define E_REMEMBER_APPLY_OFFER_RESISTANCE (1 << 16)
|
||||||
#define E_REMEMBER_APPLY_OPACITY (1 << 17)
|
#define E_REMEMBER_APPLY_OPACITY (1 << 17)
|
||||||
|
#define E_REMEMBER_APPLY_UUID (1 << 18)
|
||||||
|
|
||||||
#define E_REMEMBER_INTERNAL_DIALOGS (1 << 0)
|
#define E_REMEMBER_INTERNAL_DIALOGS (1 << 0)
|
||||||
#define E_REMEMBER_INTERNAL_FM_WINS (1 << 1)
|
#define E_REMEMBER_INTERNAL_FM_WINS (1 << 1)
|
||||||
|
@ -109,6 +110,8 @@ struct _E_Remember
|
||||||
const char *desktop_file;
|
const char *desktop_file;
|
||||||
unsigned char opacity;
|
unsigned char opacity;
|
||||||
} prop;
|
} prop;
|
||||||
|
Eina_Stringshare *uuid;
|
||||||
|
int pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
EINTERN int e_remember_init(E_Startup_Mode mode);
|
EINTERN int e_remember_init(E_Startup_Mode mode);
|
||||||
|
@ -124,5 +127,7 @@ E_API void e_remember_match_update(E_Remember *rem);
|
||||||
E_API void e_remember_update(E_Client *ec);
|
E_API void e_remember_update(E_Client *ec);
|
||||||
E_API int e_remember_default_match_set(E_Remember *rem, E_Client *ec);
|
E_API int e_remember_default_match_set(E_Remember *rem, E_Client *ec);
|
||||||
E_API void e_remember_internal_save(void);
|
E_API void e_remember_internal_save(void);
|
||||||
|
|
||||||
|
E_API void e_remember_apply(E_Remember *rem, E_Client *ec);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 1. Create mmaped memory blob, name the memory object
|
|
||||||
* 2. Fill in table and keep it up-to-date
|
|
||||||
* 3. (optional) Write the whole blob into a file on disk for later use)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <e.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
/* Use anonymous mapping if we don't want a persistent file on the disk */
|
|
||||||
#define OBJECT_NAME "/e_uuid_store"
|
|
||||||
#define TABLE_SIZE 10*eina_cpu_page_size()
|
|
||||||
|
|
||||||
struct uuid_store *store;
|
|
||||||
|
|
||||||
void
|
|
||||||
e_uuid_dump(void)
|
|
||||||
{
|
|
||||||
struct uuid_table *table;
|
|
||||||
int i;
|
|
||||||
char uuid_string[37];
|
|
||||||
|
|
||||||
if (store == NULL) return;
|
|
||||||
|
|
||||||
table = store->table;
|
|
||||||
if (table == NULL) return;
|
|
||||||
|
|
||||||
INF("Dump UUID table:");
|
|
||||||
for (i = 0; i < UUID_STORE_TABLE_SIZE -1; i++)
|
|
||||||
{
|
|
||||||
if (uuid_is_null(table->entries[i].uuid)) continue;
|
|
||||||
uuid_unparse(table->entries[i].uuid, uuid_string);
|
|
||||||
INF("UUID %s, x=%i, y=%i, width=%i, heigth=%i", uuid_string, table->entries[i].x,
|
|
||||||
table->entries[i].y, table->entries[i].width,
|
|
||||||
table->entries[i].heigth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the UUID store
|
|
||||||
*
|
|
||||||
* @returns 1 if init was successful, 0 on failure
|
|
||||||
*/
|
|
||||||
EINTERN int
|
|
||||||
e_uuid_store_init(void)
|
|
||||||
{
|
|
||||||
/* FIXME think about refcounting here */
|
|
||||||
eina_init();
|
|
||||||
|
|
||||||
store = calloc(1, sizeof(struct uuid_store));
|
|
||||||
if (store == NULL) return 0;
|
|
||||||
|
|
||||||
/* Try to open existing SHM object */
|
|
||||||
store->shmfd = shm_open(OBJECT_NAME, O_RDWR, S_IRWXU | S_IRWXG);
|
|
||||||
if (store->shmfd < 0 && errno == ENOENT)
|
|
||||||
{
|
|
||||||
INF("shm_open failed to open an existing file %s", OBJECT_NAME);
|
|
||||||
if (!e_uuid_store_reload()) return 0;
|
|
||||||
}
|
|
||||||
else if (store->shmfd < 0)
|
|
||||||
{
|
|
||||||
INF("shm_open failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust in memory blob to our given table size */
|
|
||||||
/* FIXME: How can we make sure we have the right size for our given table? */
|
|
||||||
if (ftruncate(store->shmfd, TABLE_SIZE) < 0)
|
|
||||||
{
|
|
||||||
ERR("ftruncate failed: %s", strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
store->table = (struct uuid_table *)mmap(NULL, TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, store->shmfd, 0);
|
|
||||||
if (store->table == NULL)
|
|
||||||
{
|
|
||||||
ERR("mmap failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
INF("mmaped blob with size %i created", TABLE_SIZE);
|
|
||||||
|
|
||||||
if (store->table->version)
|
|
||||||
INF("UUID table with version %i", store->table->version);
|
|
||||||
else
|
|
||||||
store->table->version = 1;
|
|
||||||
|
|
||||||
INF("UUID table with %i entries", store->table->entry_count);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
EINTERN int
|
|
||||||
e_uuid_store_shutdown(void)
|
|
||||||
{
|
|
||||||
/* Cleanup for shutdown */
|
|
||||||
if (shm_unlink(OBJECT_NAME) != 0)
|
|
||||||
{
|
|
||||||
ERR("shm_unlink failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(store->shmfd);
|
|
||||||
free(store);
|
|
||||||
eina_shutdown();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eina_Bool
|
|
||||||
e_uuid_store_reload(void)
|
|
||||||
{
|
|
||||||
/* After crash reload the table with its POSIX object name from memory */
|
|
||||||
store->shmfd = shm_open(OBJECT_NAME, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);
|
|
||||||
if (store->shmfd < 0)
|
|
||||||
{
|
|
||||||
INF("shm_open failed");
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eina_Bool
|
|
||||||
e_uuid_store_entry_del(uuid_t uuid)
|
|
||||||
{
|
|
||||||
struct uuid_table *table;
|
|
||||||
int i;
|
|
||||||
char uuid_string[37];
|
|
||||||
|
|
||||||
if (store == NULL) return EINA_FALSE;
|
|
||||||
|
|
||||||
table = store->table;
|
|
||||||
if (table == NULL) return EINA_FALSE;
|
|
||||||
|
|
||||||
/* Search through uuid list and delete if found */
|
|
||||||
for (i = 0; i < UUID_STORE_TABLE_SIZE -1; i++)
|
|
||||||
{
|
|
||||||
if (!uuid_compare(table->entries[i].uuid, uuid))
|
|
||||||
{
|
|
||||||
uuid_clear(table->entries[i].uuid);
|
|
||||||
table->entries[i].x = 0;
|
|
||||||
table->entries[i].x = 0;
|
|
||||||
table->entries[i].width = 0;
|
|
||||||
table->entries[i].heigth = 0;
|
|
||||||
table->entry_count--;
|
|
||||||
uuid_unparse(uuid, uuid_string);
|
|
||||||
DBG("Removed entry with UUID %s", uuid_string);
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uuid_unparse(uuid, uuid_string);
|
|
||||||
DBG("NOT removed entry with UUID %s. Entry not found.", uuid_string);
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Think about having _add and _update functions instead only update */
|
|
||||||
|
|
||||||
Eina_Bool
|
|
||||||
e_uuid_store_entry_update(uuid_t uuid, E_Client *ec)
|
|
||||||
{
|
|
||||||
struct uuid_table *table;
|
|
||||||
int i, index = -1;
|
|
||||||
char uuid_string[37];
|
|
||||||
|
|
||||||
if (store == NULL) return EINA_FALSE;
|
|
||||||
|
|
||||||
table = store->table;
|
|
||||||
if (table == NULL) return EINA_FALSE;
|
|
||||||
|
|
||||||
/* Search through uuid list if it already exist if yes update */
|
|
||||||
for (i = 0; i < UUID_STORE_TABLE_SIZE -1; i++)
|
|
||||||
{
|
|
||||||
if (!uuid_compare(table->entries[i].uuid, uuid))
|
|
||||||
{
|
|
||||||
table->entries[i].x = ec->x;
|
|
||||||
table->entries[i].y = ec->y;
|
|
||||||
table->entries[i].width = ec->client.w;
|
|
||||||
table->entries[i].heigth = ec->client.h;
|
|
||||||
uuid_unparse(uuid, uuid_string);
|
|
||||||
DBG("Updated entry with UUID %s", uuid_string);
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find first empty entry */
|
|
||||||
for (i = 0; i < UUID_STORE_TABLE_SIZE -1; i++)
|
|
||||||
{
|
|
||||||
if (uuid_is_null(table->entries[i].uuid))
|
|
||||||
index = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == -1)
|
|
||||||
{
|
|
||||||
ERR("UUID table full");
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We do not have this UUID in the table yet. Create it */
|
|
||||||
table->entries[index].x = ec->x;
|
|
||||||
table->entries[index].y = ec->y;
|
|
||||||
table->entries[index].width = ec->client.w;
|
|
||||||
table->entries[index].heigth = ec->client.h;
|
|
||||||
uuid_copy(table->entries[index].uuid, uuid);
|
|
||||||
table->entry_count++;
|
|
||||||
uuid_unparse(table->entries[index].uuid, uuid_string);
|
|
||||||
DBG("Created entry with UUID %s", uuid_string);
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef E_UUID_STORE_H
|
|
||||||
#define E_UUID_STORE_H
|
|
||||||
|
|
||||||
/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define UUID_STORE_TABLE_SIZE 100
|
|
||||||
|
|
||||||
struct table_entry {
|
|
||||||
uuid_t uuid;
|
|
||||||
/* data structure for per application properties */
|
|
||||||
Evas_Coord x, y;
|
|
||||||
Evas_Coord width, heigth;
|
|
||||||
unsigned int virtual_desktop;
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uuid_table {
|
|
||||||
int version; /* Version to allow future extensions */
|
|
||||||
unsigned int entry_count; /* Entry counter to allow excat memory consuptions needs? */
|
|
||||||
/* Global settings like current virtual desktop, screen setup, etc */
|
|
||||||
struct table_entry entries[UUID_STORE_TABLE_SIZE]; /* FIXME make this more adjustable */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uuid_store {
|
|
||||||
struct uuid_table *table;
|
|
||||||
int shmfd;
|
|
||||||
};
|
|
||||||
|
|
||||||
EINTERN int e_uuid_store_init(void);
|
|
||||||
EINTERN int e_uuid_store_shutdown(void);
|
|
||||||
E_API void e_uuid_dump(void);
|
|
||||||
E_API Eina_Bool e_uuid_store_reload(void);
|
|
||||||
E_API Eina_Bool e_uuid_store_entry_del(uuid_t uuid);
|
|
||||||
E_API Eina_Bool e_uuid_store_entry_update(uuid_t uuid, E_Client *ec);
|
|
||||||
#endif
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef E_SESSION_RECOVERY_SERVER_PROTOCOL_H
|
|
||||||
#define E_SESSION_RECOVERY_SERVER_PROTOCOL_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "wayland-server.h"
|
|
||||||
|
|
||||||
struct wl_client;
|
|
||||||
struct wl_resource;
|
|
||||||
|
|
||||||
struct zwp_e_session_recovery;
|
|
||||||
|
|
||||||
extern const struct wl_interface zwp_e_session_recovery_interface;
|
|
||||||
|
|
||||||
struct zwp_e_session_recovery_interface {
|
|
||||||
/**
|
|
||||||
* provide_uuid - (none)
|
|
||||||
* @uuid: (none)
|
|
||||||
*/
|
|
||||||
void (*provide_uuid)(struct wl_client *client,
|
|
||||||
struct wl_resource *resource,
|
|
||||||
const char *uuid);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ZWP_E_SESSION_RECOVERY_UUID 0
|
|
||||||
|
|
||||||
#define ZWP_E_SESSION_RECOVERY_UUID_SINCE_VERSION 1
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
zwp_e_session_recovery_send_uuid(struct wl_resource *resource_, const char *uuid)
|
|
||||||
{
|
|
||||||
wl_resource_post_event(resource_, ZWP_E_SESSION_RECOVERY_UUID, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -2,22 +2,31 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "wayland-util.h"
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
|
||||||
static const struct wl_interface *types[] = {
|
static const struct wl_interface *types[] = {
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_message zwp_e_session_recovery_requests[] = {
|
static const struct wl_message zwp_e_session_recovery_requests[] = {
|
||||||
{ "provide_uuid", "s", types + 0 },
|
{ "get_uuid", "o", types + 0 },
|
||||||
|
{ "set_uuid", "os", types + 1 },
|
||||||
|
{ "destroy_uuid", "os", types + 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_message zwp_e_session_recovery_events[] = {
|
static const struct wl_message zwp_e_session_recovery_events[] = {
|
||||||
{ "uuid", "s", types + 0 },
|
{ "create_uuid", "os", types + 5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
|
WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
|
||||||
"zwp_e_session_recovery", 1,
|
"zwp_e_session_recovery", 1,
|
||||||
1, zwp_e_session_recovery_requests,
|
3, zwp_e_session_recovery_requests,
|
||||||
1, zwp_e_session_recovery_events,
|
1, zwp_e_session_recovery_events,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef E_SESSION_RECOVERY_SERVER_PROTOCOL_H
|
||||||
|
#define E_SESSION_RECOVERY_SERVER_PROTOCOL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-server.h"
|
||||||
|
|
||||||
|
struct wl_client;
|
||||||
|
struct wl_resource;
|
||||||
|
|
||||||
|
struct wl_surface;
|
||||||
|
struct zwp_e_session_recovery;
|
||||||
|
|
||||||
|
extern const struct wl_interface zwp_e_session_recovery_interface;
|
||||||
|
|
||||||
|
struct zwp_e_session_recovery_interface {
|
||||||
|
/**
|
||||||
|
* get_uuid - (none)
|
||||||
|
* @surface: (none)
|
||||||
|
*/
|
||||||
|
void (*get_uuid)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
struct wl_resource *surface);
|
||||||
|
/**
|
||||||
|
* set_uuid - (none)
|
||||||
|
* @surface: (none)
|
||||||
|
* @uuid: (none)
|
||||||
|
*/
|
||||||
|
void (*set_uuid)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
struct wl_resource *surface,
|
||||||
|
const char *uuid);
|
||||||
|
/**
|
||||||
|
* destroy_uuid - (none)
|
||||||
|
* @surface: (none)
|
||||||
|
* @uuid: (none)
|
||||||
|
*/
|
||||||
|
void (*destroy_uuid)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
struct wl_resource *surface,
|
||||||
|
const char *uuid);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_CREATE_UUID 0
|
||||||
|
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_CREATE_UUID_SINCE_VERSION 1
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_send_create_uuid(struct wl_resource *resource_, struct wl_resource *surface, const char *uuid)
|
||||||
|
{
|
||||||
|
wl_resource_post_event(resource_, ZWP_E_SESSION_RECOVERY_CREATE_UUID, surface, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,10 +1,19 @@
|
||||||
<protocol name="e_session_recovery">
|
<protocol name="e_session_recovery">
|
||||||
|
|
||||||
<interface name="zwp_e_session_recovery" version="1">
|
<interface name="zwp_e_session_recovery" version="1">
|
||||||
<request name="provide_uuid">
|
<request name="get_uuid">
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
<request name="set_uuid">
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
<arg name="uuid" type="string"/>
|
<arg name="uuid" type="string"/>
|
||||||
</request>
|
</request>
|
||||||
<event name="uuid">
|
<request name="destroy_uuid">
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
<arg name="uuid" type="string"/>
|
||||||
|
</request>
|
||||||
|
<event name="create_uuid">
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
<arg name="uuid" type="string"/>
|
<arg name="uuid" type="string"/>
|
||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
Loading…
Reference in New Issue