discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=ef1772b8cb992b115411f01e1915fca015eea158

commit ef1772b8cb992b115411f01e1915fca015eea158
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Thu May 5 10:22:04 2016 -0400

    implement wl client session recovery
    
    another small feature patch brought to you by insomnia
    
     #SamsungFeatures
---
 src/bin/Makefile.mk                                |    6 +-
 src/bin/e.h                                        |    1 -
 src/bin/e_client.c                                 |    9 +-
 src/bin/e_client.h                                 |    4 +-
 src/bin/e_comp_wl.c                                |   16 +-
 src/bin/e_comp_wl_extensions.c                     |   65 +-
 src/bin/e_config.c                                 |    2 +
 src/bin/e_includes.h                               |    1 -
 src/bin/e_main.c                                   |   13 -
 src/bin/e_remember.c                               | 1222 ++++++++++----------
 src/bin/e_remember.h                               |    5 +
 src/bin/e_uuid_store.c                             |  210 ----
 src/bin/e_uuid_store.h                             |   36 -
 .../generated/session-recovery-server-protocol.h   |   43 -
 ...sion-recovery-protocol.c => session-recovery.c} |   15 +-
 src/bin/generated/session-recovery.h               |   62 +
 src/protocol/session-recovery.xml                  |   13 +-
 17 files changed, 783 insertions(+), 940 deletions(-)

diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk
index c7d04fc..c6930d3 100644
--- a/src/bin/Makefile.mk
+++ b/src/bin/Makefile.mk
@@ -221,7 +221,6 @@ src/bin/e_zone.h
 
 if HAVE_WAYLAND
 ENLIGHTENMENTHEADERS += \
-src/bin/e_uuid_store.h \
 src/bin/e_comp_wl_data.h \
 src/bin/e_comp_wl_input.h \
 src/bin/e_comp_wl.h
@@ -394,11 +393,10 @@ endif
 
 if HAVE_WAYLAND
 enlightenment_src += \
-src/bin/e_uuid_store.c \
 src/bin/generated/www-protocol.c \
 src/bin/generated/www-protocol.h \
-src/bin/generated/session-recovery-protocol.c \
-src/bin/generated/session-recovery-server-protocol.h \
+src/bin/generated/session-recovery.c \
+src/bin/generated/session-recovery.h \
 src/bin/generated/e_comp_wl_screenshooter_server.c \
 src/bin/generated/e_comp_wl_screenshooter_server.h \
 src/bin/e_comp_wl_data.c \
diff --git a/src/bin/e.h b/src/bin/e.h
index 2c2d203..b7390af 100644
--- a/src/bin/e.h
+++ b/src/bin/e.h
@@ -133,7 +133,6 @@ void *alloca (size_t);
 
 # ifdef HAVE_WAYLAND
 #  include <Ecore_Wl2.h>
-#  include <uuid.h>
 # endif
 
 # ifdef E_API
diff --git a/src/bin/e_client.c b/src/bin/e_client.c
index be4f523..d3a00a3 100644
--- a/src/bin/e_client.c
+++ b/src/bin/e_client.c
@@ -554,6 +554,7 @@ _e_client_free(E_Client *ec)
    eina_stringshare_replace(&ec->netwm.icon_name, NULL);
    eina_stringshare_replace(&ec->internal_icon, NULL);
    eina_stringshare_replace(&ec->internal_icon_key, NULL);
+   eina_stringshare_replace(&ec->uuid, NULL);
    
    focus_stack = eina_list_remove(focus_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);
    E_OBJECT(ec)->references--;
 
-#ifdef HAVE_WAYLAND
-   e_uuid_store_entry_del(ec->uuid);
-#endif
-
    free(ec);
 }
 
@@ -2346,10 +2343,6 @@ e_client_new(E_Pixmap *cp, int first_map, int internal)
    if (!ec) return NULL;
    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->w = 1;
    ec->h = 1;
diff --git a/src/bin/e_client.h b/src/bin/e_client.h
index e2d83fc..1508e27 100644
--- a/src/bin/e_client.h
+++ b/src/bin/e_client.h
@@ -686,9 +686,7 @@ struct E_Client
 
    E_Focus_Policy             focus_policy_override;
 
-#ifdef HAVE_WAYLAND
-   uuid_t uuid;
-#endif
+   Eina_Stringshare *uuid;
 
    Eina_Bool override : 1;
    Eina_Bool input_only : 1;
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index ec57131..105bad6 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -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);
      }
-   if (ec)
-     {
-        if (ec->new_client)
-          e_comp->new_clients--;
-        ec->new_client = 0;
-        if ((!ec->client.w) && (ec->client.h))
-          ec->client.w = ec->client.h = 1;
-        ec->comp_data->surface = res;
-     }
+   if (ec->new_client)
+     e_comp->new_clients--;
+   ec->new_client = 0;
+   if ((!ec->client.w) && (ec->client.h))
+     ec->client.w = ec->client.h = 1;
+   ec->comp_data->surface = res;
+   ec->netwm.pid = pid;
 
    /* set reference to pixmap so we can fetch it later */
    DBG("\tUsing Client: %p", ec);
diff --git a/src/bin/e_comp_wl_extensions.c b/src/bin/e_comp_wl_extensions.c
index dd15f10..4849682 100644
--- a/src/bin/e_comp_wl_extensions.c
+++ b/src/bin/e_comp_wl_extensions.c
@@ -1,8 +1,10 @@
 #define E_COMP_WL
 #include "e.h"
 
+
+#include <uuid.h>
 #include "e_comp_wl_screenshooter_server.h"
-#include "session-recovery-server-protocol.h"
+#include "session-recovery.h"
 #include "www-protocol.h"
 
 static void
@@ -24,9 +26,62 @@ _e_comp_wl_extensions_client_move_end(void *d EINA_UNUSED, 
E_Client *ec)
 }
 
 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
@@ -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 =
 {
-   _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 =
diff --git a/src/bin/e_config.c b/src/bin/e_config.c
index 3ca9456..cb999fc 100644
--- a/src/bin/e_config.c
+++ b/src/bin/e_config.c
@@ -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.offer_resistance, 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);
 #undef T
diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h
index 63133df..cfc6f53 100644
--- a/src/bin/e_includes.h
+++ b/src/bin/e_includes.h
@@ -157,5 +157,4 @@
 # include "e_comp_wl.h"
 # include "e_comp_wl_data.h"
 # include "e_comp_wl_input.h"
-# include "e_uuid_store.h"
 #endif
diff --git a/src/bin/e_main.c b/src/bin/e_main.c
index 04ddbb2..ef68ab5 100644
--- a/src/bin/e_main.c
+++ b/src/bin/e_main.c
@@ -536,19 +536,6 @@ main(int argc, char **argv)
    _e_main_shutdown_push(e_alert_shutdown);
 #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");
    /* setup directories we will be using for configurations storage etc. */
    if (!_e_main_dirs_init())
diff --git a/src/bin/e_remember.c b/src/bin/e_remember.c
index 62147f4..e0fec51 100644
--- a/src/bin/e_remember.c
+++ b/src/bin/e_remember.c
@@ -268,688 +268,704 @@ e_remember_del(E_Remember *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)
+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)
+   int temporary = 0;
+   if (ec->internal && remembers && ec->icccm.class && ec->icccm.class[0])
      {
-        /* 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)
+        Eina_List *l;
+        EINA_LIST_FOREACH(remembers->list, l, rem)
           {
-             if (r->max_score <= rem->max_score) break;
+             if (rem->class && !strcmp(rem->class, ec->icccm.class))
+               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);
+        if (rem)
+          {
+             temporary = 1;
+             remembers->list = eina_list_remove(remembers->list, rem);
+             remember_idler_list = eina_list_remove(remember_idler_list, rem);
+             if (!remembers->list)
+               e_config_domain_save("e_remember_restart",
+                                    e_remember_list_edd, remembers);
+          }
+        else rem = ec->remember;
      }
-}
-
-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 (!rem)
+     return;
 
-   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])
+   if (rem->apply & E_REMEMBER_APPLY_ZONE)
      {
-        match |= E_REMEMBER_MATCH_TITLE;
-        rem->title = eina_stringshare_ref(title);
+        E_Zone *zone;
+
+        zone = e_comp_zone_number_get(rem->prop.zone);
+        if (zone)
+          e_client_zone_set(ec, zone);
      }
-   if (role)
+   if (rem->apply & E_REMEMBER_APPLY_DESKTOP)
      {
-        match |= E_REMEMBER_MATCH_ROLE;
-        rem->role = eina_stringshare_ref(role);
+        E_Desk *desk;
+
+        desk = e_desk_at_xy_get(ec->zone, rem->prop.desk_x, rem->prop.desk_y);
+        if (desk)
+          {
+             if (ec->desk != desk)
+               ec->hidden = 0;
+             e_client_desk_set(ec, desk);
+             if (e_config->desk_auto_switch)
+               e_desk_show(desk);
+          }
      }
-   if (ec->netwm.type != E_WINDOW_TYPE_UNKNOWN)
+   if (rem->apply & E_REMEMBER_APPLY_SIZE)
      {
-        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);
-}
+        int w, h;
 
-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)
+        w = ec->client.w;
+        h = ec->client.h;
+        if (rem->prop.pos_w)
+          ec->client.w = rem->prop.pos_w;
+        if (rem->prop.pos_h)
+          ec->client.h = rem->prop.pos_h;
+        /* we can trust internal windows */
+        if (ec->internal)
           {
-             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;
+             if (ec->zone->w != rem->prop.res_x)
+               {
+                  if (ec->client.w > (ec->zone->w - 64))
+                    ec->client.w = ec->zone->w - 64;
+               }
+             if (ec->zone->h != rem->prop.res_y)
+               {
+                  if (ec->client.h > (ec->zone->h - 64))
+                    ec->client.h = ec->zone->h - 64;
+               }
+             if (ec->icccm.min_w > ec->client.w)
+               ec->client.w = ec->icccm.min_w;
+             if ((ec->icccm.max_w > 0) && (ec->icccm.max_w < ec->client.w))
+               ec->client.w = ec->icccm.max_w;
+             if (ec->icccm.min_h > ec->client.h)
+               ec->client.h = ec->icccm.min_h;
+             if ((ec->icccm.max_h > 0) && (ec->icccm.max_h < ec->client.h))
+               ec->client.h = ec->icccm.max_h;
           }
-        else
+        e_comp_object_frame_wh_adjust(ec->frame, ec->client.w, ec->client.h, 
&ec->w, &ec->h);
+        if (rem->prop.maximize)
           {
-             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;
+             ec->saved.x = rem->prop.pos_x;
+             ec->saved.y = rem->prop.pos_y;
+             ec->saved.w = ec->client.w;
+             ec->saved.h = ec->client.h;
+             ec->maximized = rem->prop.maximize | e_config->maximize_policy;
+          }
+        if ((w != ec->client.w) || (h != ec->client.h))
+          {
+             ec->changes.size = 1;
+             ec->changes.shape = 1;
+             EC_CHANGED(ec);
           }
-        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)
+   if ((rem->apply & E_REMEMBER_APPLY_POS) && (!ec->re_manage))
      {
-        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;
+        ec->x = rem->prop.pos_x;
+        ec->y = rem->prop.pos_y;
+        if (ec->zone->w != rem->prop.res_x)
+          {
+             int px;
+
+             px = ec->x + (ec->w / 2);
+             if (px < ((rem->prop.res_x * 1) / 3))
+               {
+                  if (ec->zone->w >= (rem->prop.res_x / 3))
+                    ec->x = rem->prop.pos_x;
+                  else
+                    ec->x = ((rem->prop.pos_x - 0) * ec->zone->w) /
+                      (rem->prop.res_x / 3);
+               }
+             else if (px < ((rem->prop.res_x * 2) / 3))
+               {
+                  if (ec->zone->w >= (rem->prop.res_x / 3))
+                    ec->x = (ec->zone->w / 2) +
+                      (px - (rem->prop.res_x / 2)) -
+                      (ec->w / 2);
+                  else
+                    ec->x = (ec->zone->w / 2) +
+                      (((px - (rem->prop.res_x / 2)) * ec->zone->w) /
+                       (rem->prop.res_x / 3)) -
+                      (ec->w / 2);
+               }
+             else
+               {
+                  if (ec->zone->w >= (rem->prop.res_x / 3))
+                    ec->x = ec->zone->w +
+                      rem->prop.pos_x - rem->prop.res_x +
+                      (rem->prop.w - ec->client.w);
+                  else
+                    ec->x = ec->zone->w +
+                      (((rem->prop.pos_x - rem->prop.res_x) * ec->zone->w) /
+                       (rem->prop.res_x / 3)) +
+                      (rem->prop.w - ec->client.w);
+               }
+             if ((rem->prop.pos_x >= 0) && (ec->x < 0))
+               ec->x = 0;
+             else if (((rem->prop.pos_x + rem->prop.w) < rem->prop.res_x) &&
+                      ((ec->x + ec->w) > ec->zone->w))
+               ec->x = ec->zone->w - ec->w;
+          }
+        if (ec->zone->h != rem->prop.res_y)
+          {
+             int py;
+
+             py = ec->y + (ec->h / 2);
+             if (py < ((rem->prop.res_y * 1) / 3))
+               {
+                  if (ec->zone->h >= (rem->prop.res_y / 3))
+                    ec->y = rem->prop.pos_y;
+                  else
+                    ec->y = ((rem->prop.pos_y - 0) * ec->zone->h) /
+                      (rem->prop.res_y / 3);
+               }
+             else if (py < ((rem->prop.res_y * 2) / 3))
+               {
+                  if (ec->zone->h >= (rem->prop.res_y / 3))
+                    ec->y = (ec->zone->h / 2) +
+                      (py - (rem->prop.res_y / 2)) -
+                      (ec->h / 2);
+                  else
+                    ec->y = (ec->zone->h / 2) +
+                      (((py - (rem->prop.res_y / 2)) * ec->zone->h) /
+                       (rem->prop.res_y / 3)) -
+                      (ec->h / 2);
+               }
+             else
+               {
+                  if (ec->zone->h >= (rem->prop.res_y / 3))
+                    ec->y = ec->zone->h +
+                      rem->prop.pos_y - rem->prop.res_y +
+                      (rem->prop.h - ec->client.h);
+                  else
+                    ec->y = ec->zone->h +
+                      (((rem->prop.pos_y - rem->prop.res_y) * ec->zone->h) /
+                       (rem->prop.res_y / 3)) +
+                      (rem->prop.h - ec->client.h);
+               }
+             if ((rem->prop.pos_y >= 0) && (ec->y < 0))
+               ec->y = 0;
+             else if (((rem->prop.pos_y + rem->prop.h) < rem->prop.res_y) &&
+                      ((ec->y + ec->h) > ec->zone->h))
+               ec->y = ec->zone->h - ec->h;
+          }
+        //               if (ec->zone->w != rem->prop.res_x)
+        //                 ec->x = (rem->prop.pos_x * ec->zone->w) / 
rem->prop.res_x;
+        //               if (ec->zone->h != rem->prop.res_y)
+        //                 ec->y = (rem->prop.pos_y * ec->zone->h) / 
rem->prop.res_y;
+        if (
+          /* upper left */
+          (!E_INSIDE(ec->x, ec->y, 0, 0, ec->zone->w, ec->zone->h)) &&
+          /* upper right */
+          (!E_INSIDE(ec->x + ec->w, ec->y, 0, 0, ec->zone->w, ec->zone->h)) &&
+          /* lower left */
+          (!E_INSIDE(ec->x, ec->y + ec->h, 0, 0, ec->zone->w, ec->zone->h)) &&
+          /* lower right */
+          (!E_INSIDE(ec->x + ec->w, ec->y + ec->h, 0, 0, ec->zone->w, 
ec->zone->h))
+          )
+          {
+             e_comp_object_util_center_pos_get(ec->frame, &ec->x, &ec->y);
+             rem->prop.pos_x = ec->x, rem->prop.pos_y = ec->y;
+          }
+        ec->x += ec->zone->x;
+        ec->y += ec->zone->y;
+        ec->placed = 1;
+        ec->changes.pos = 1;
+        EC_CHANGED(ec);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_LAYER)
+     {
+        evas_object_layer_set(ec->frame, rem->prop.layer);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_BORDER)
+     {
+        eina_stringshare_replace(&ec->bordername, NULL);
+        ec->bordername = eina_stringshare_ref(rem->prop.border);
+        ec->border.changed = 1;
+        EC_CHANGED(ec);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_FULLSCREEN)
+     {
+        if (rem->prop.fullscreen)
+          e_client_fullscreen(ec, e_config->fullscreen_policy);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_STICKY)
+     {
+        if (rem->prop.sticky) e_client_stick(ec);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_SHADE)
+     {
+        if (rem->prop.shaded >= 100)
+          e_client_shade(ec, rem->prop.shaded - 100);
+        else if (rem->prop.shaded >= 50)
+          e_client_unshade(ec, rem->prop.shaded - 50);
+     }
+   if (rem->apply & E_REMEMBER_APPLY_LOCKS)
+     {
+        ec->lock_user_location = rem->prop.lock_user_location;
+        ec->lock_client_location = rem->prop.lock_client_location;
+        ec->lock_user_size = rem->prop.lock_user_size;
+        ec->lock_client_size = rem->prop.lock_client_size;
+        ec->lock_user_stacking = rem->prop.lock_user_stacking;
+        ec->lock_client_stacking = rem->prop.lock_client_stacking;
+        ec->lock_user_iconify = rem->prop.lock_user_iconify;
+        ec->lock_client_iconify = rem->prop.lock_client_iconify;
+        ec->lock_user_desk = rem->prop.lock_user_desk;
+        ec->lock_client_desk = rem->prop.lock_client_desk;
+        ec->lock_user_sticky = rem->prop.lock_user_sticky;
+        ec->lock_client_sticky = rem->prop.lock_client_sticky;
+        ec->lock_user_shade = rem->prop.lock_user_shade;
+        ec->lock_client_shade = rem->prop.lock_client_shade;
+        ec->lock_user_maximize = rem->prop.lock_user_maximize;
+        ec->lock_client_maximize = rem->prop.lock_client_maximize;
+        ec->lock_user_fullscreen = rem->prop.lock_user_fullscreen;
+        ec->lock_client_fullscreen = rem->prop.lock_client_fullscreen;
+        ec->lock_border = rem->prop.lock_border;
+        ec->lock_close = rem->prop.lock_close;
+        ec->lock_focus_in = rem->prop.lock_focus_in;
+        ec->lock_focus_out = rem->prop.lock_focus_out;
+        ec->lock_life = rem->prop.lock_life;
+     }
+   if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST)
+     ec->user_skip_winlist = rem->prop.skip_winlist;
    if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER)
-     rem->prop.skip_pager = ec->netwm.state.skip_pager;
+     ec->netwm.state.skip_pager = rem->prop.skip_pager;
    if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR)
-     rem->prop.skip_taskbar = ec->netwm.state.skip_taskbar;
+     ec->netwm.state.skip_taskbar = rem->prop.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;
+     ec->icon_preference = rem->prop.icon_preference;
    if (rem->apply & E_REMEMBER_APPLY_OFFER_RESISTANCE)
-     rem->prop.offer_resistance = ec->offer_resistance;
+     ec->offer_resistance = rem->prop.offer_resistance;
+   if (rem->apply & E_REMEMBER_SET_FOCUS_ON_START)
+     ec->want_focus = 1;
    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;
+     ec->netwm.opacity = rem->prop.opacity;
 
-      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);
-   }
+   if (temporary)
+     _e_remember_free(rem);
 }
 
-/* local subsystem functions */
-static E_Remember *
-_e_remember_find(E_Client *ec, int check_usable)
+E_API E_Remember *
+e_remember_find_usable(E_Client *ec)
 {
-   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 = "";
+   rem = _e_remember_find(ec, 1);
+   return rem;
+}
 
-        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++;
+E_API E_Remember *
+e_remember_find(E_Client *ec)
+{
+   E_Remember *rem;
 
-        if (ec->netwm.name) title = ec->netwm.name;
-        else title = ec->icccm.title;
+   rem = _e_remember_find(ec, 0);
+   return rem;
+}
 
-        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 = "";
+E_API void
+e_remember_match_update(E_Remember *rem)
+{
+   int max_count = 0;
 
-        if ((check_usable) && (!e_remember_usable_get(rem)))
-          continue;
+   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 (ec->netwm.name) title = ec->netwm.name;
-        else title = ec->icccm.title;
+   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;
 
-        /* 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;
+        rem->max_score = max_count;
+        e_config->remembers = eina_list_remove(e_config->remembers, rem);
 
-        return rem;
-     }
+        EINA_LIST_FOREACH(e_config->remembers, l, r)
+          {
+             if (r->max_score <= rem->max_score) break;
+          }
 
-   return NULL;
-#endif
+        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);
+     }
 }
 
-static void
-_e_remember_free(E_Remember *rem)
+E_API int
+e_remember_default_match_set(E_Remember *rem, E_Client *ec)
 {
-   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);
-}
+   const char *title, *clasz, *name, *role;
+   int match;
 
-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;
+   eina_stringshare_replace(&rem->name, NULL);
+   eina_stringshare_replace(&rem->class, NULL);
+   eina_stringshare_replace(&rem->title, NULL);
+   eina_stringshare_replace(&rem->role, NULL);
 
-        if (!strncmp(ec->icccm.class, "e_fwin", 6))
-          {
-             if (!e_config->remember_internal_fm_windows) return;
-          }
-        else
-          {
-             if (!e_config->remember_internal_windows)
-               return;
-          }
+   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;
 
-        rem = e_remember_new();
-        if (!rem) return;
+   match = E_REMEMBER_MATCH_TRANSIENT;
+   if (ec->icccm.transient_for != 0)
+     rem->transient = 1;
+   else
+     rem->transient = 0;
 
-        e_remember_default_match_set(rem, ec);
+   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->apply = E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_SIZE | 
E_REMEMBER_APPLY_BORDER;
+   rem->match = match;
 
-        e_remember_use(rem);
-        e_remember_update(ec);
-        ec->remember = rem;
-     }
+   return match;
 }
 
-static void
-_e_remember_cb_hook_pre_post_fetch(void *data EINA_UNUSED, E_Client *ec)
+E_API void
+e_remember_update(E_Client *ec)
 {
-   E_Remember *rem = NULL;
-   int temporary = 0;
-
-   if ((!ec->new_client) || ec->internal_no_remember || 
e_client_util_ignored_get(ec)) return;
+   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();
+}
 
-   if (!ec->remember)
-     {
-        rem = e_remember_find_usable(ec);
-        if (rem)
-          {
-             ec->remember = rem;
-             e_remember_use(rem);
-          }
-     }
+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);
+}
 
-   if (ec->internal && remembers && ec->icccm.class && ec->icccm.class[0])
+static void
+_e_remember_update(E_Client *ec, E_Remember *rem)
+{
+   if (rem->apply & E_REMEMBER_APPLY_POS ||
+       rem->apply & E_REMEMBER_APPLY_SIZE)
      {
-        Eina_List *l;
-        EINA_LIST_FOREACH(remembers->list, l, rem)
+        if (ec->fullscreen || ec->maximized)
           {
-             if (rem->class && !strcmp(rem->class, ec->icccm.class))
-               break;
+             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;
           }
-        if (rem)
+        else
           {
-             temporary = 1;
-             remembers->list = eina_list_remove(remembers->list, rem);
-             remember_idler_list = eina_list_remove(remember_idler_list, rem);
-             if (!remembers->list)
-               e_config_domain_save("e_remember_restart",
-                                    e_remember_list_edd, remembers);
+             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;
           }
-        else rem = ec->remember;
-     }
-
-   if (!rem)
-     return;
-
-   if (rem->apply & E_REMEMBER_APPLY_ZONE)
-     {
-        E_Zone *zone;
-
-        zone = e_comp_zone_number_get(rem->prop.zone);
-        if (zone)
-          e_client_zone_set(ec, zone);
+        rem->prop.maximize = ec->maximized & E_MAXIMIZE_DIRECTION;
      }
-   if (rem->apply & E_REMEMBER_APPLY_DESKTOP)
+   if (rem->apply & E_REMEMBER_APPLY_LAYER)
      {
-        E_Desk *desk;
-
-        desk = e_desk_at_xy_get(ec->zone, rem->prop.desk_x, rem->prop.desk_y);
-        if (desk)
-          {
-             if (ec->desk != desk)
-               ec->hidden = 0;
-             e_client_desk_set(ec, desk);
-             if (e_config->desk_auto_switch)
-               e_desk_show(desk);
-          }
+        if (ec->fullscreen)
+          rem->prop.layer = ec->saved.layer;
+        else
+          rem->prop.layer = ec->layer;
      }
-   if (rem->apply & E_REMEMBER_APPLY_SIZE)
+   if (rem->apply & E_REMEMBER_APPLY_LOCKS)
      {
-        int w, h;
-
-        w = ec->client.w;
-        h = ec->client.h;
-        if (rem->prop.pos_w)
-          ec->client.w = rem->prop.pos_w;
-        if (rem->prop.pos_h)
-          ec->client.h = rem->prop.pos_h;
-        /* we can trust internal windows */
-        if (ec->internal)
-          {
-             if (ec->zone->w != rem->prop.res_x)
-               {
-                  if (ec->client.w > (ec->zone->w - 64))
-                    ec->client.w = ec->zone->w - 64;
-               }
-             if (ec->zone->h != rem->prop.res_y)
-               {
-                  if (ec->client.h > (ec->zone->h - 64))
-                    ec->client.h = ec->zone->h - 64;
-               }
-             if (ec->icccm.min_w > ec->client.w)
-               ec->client.w = ec->icccm.min_w;
-             if ((ec->icccm.max_w > 0) && (ec->icccm.max_w < ec->client.w))
-               ec->client.w = ec->icccm.max_w;
-             if (ec->icccm.min_h > ec->client.h)
-               ec->client.h = ec->icccm.min_h;
-             if ((ec->icccm.max_h > 0) && (ec->icccm.max_h < ec->client.h))
-               ec->client.h = ec->icccm.max_h;
-          }
-        e_comp_object_frame_wh_adjust(ec->frame, ec->client.w, ec->client.h, 
&ec->w, &ec->h);
-        if (rem->prop.maximize)
-          {
-             ec->saved.x = rem->prop.pos_x;
-             ec->saved.y = rem->prop.pos_y;
-             ec->saved.w = ec->client.w;
-             ec->saved.h = ec->client.h;
-             ec->maximized = rem->prop.maximize | e_config->maximize_policy;
-          }
-        if ((w != ec->client.w) || (h != ec->client.h))
-          {
-             ec->changes.size = 1;
-             ec->changes.shape = 1;
-             EC_CHANGED(ec);
-          }
+        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_POS) && (!ec->re_manage))
+   if (rem->apply & E_REMEMBER_APPLY_SHADE)
      {
-        ec->x = rem->prop.pos_x;
-        ec->y = rem->prop.pos_y;
-        if (ec->zone->w != rem->prop.res_x)
-          {
-             int px;
-
-             px = ec->x + (ec->w / 2);
-             if (px < ((rem->prop.res_x * 1) / 3))
-               {
-                  if (ec->zone->w >= (rem->prop.res_x / 3))
-                    ec->x = rem->prop.pos_x;
-                  else
-                    ec->x = ((rem->prop.pos_x - 0) * ec->zone->w) /
-                      (rem->prop.res_x / 3);
-               }
-             else if (px < ((rem->prop.res_x * 2) / 3))
-               {
-                  if (ec->zone->w >= (rem->prop.res_x / 3))
-                    ec->x = (ec->zone->w / 2) +
-                      (px - (rem->prop.res_x / 2)) -
-                      (ec->w / 2);
-                  else
-                    ec->x = (ec->zone->w / 2) +
-                      (((px - (rem->prop.res_x / 2)) * ec->zone->w) /
-                       (rem->prop.res_x / 3)) -
-                      (ec->w / 2);
-               }
-             else
-               {
-                  if (ec->zone->w >= (rem->prop.res_x / 3))
-                    ec->x = ec->zone->w +
-                      rem->prop.pos_x - rem->prop.res_x +
-                      (rem->prop.w - ec->client.w);
-                  else
-                    ec->x = ec->zone->w +
-                      (((rem->prop.pos_x - rem->prop.res_x) * ec->zone->w) /
-                       (rem->prop.res_x / 3)) +
-                      (rem->prop.w - ec->client.w);
-               }
-             if ((rem->prop.pos_x >= 0) && (ec->x < 0))
-               ec->x = 0;
-             else if (((rem->prop.pos_x + rem->prop.w) < rem->prop.res_x) &&
-                      ((ec->x + ec->w) > ec->zone->w))
-               ec->x = ec->zone->w - ec->w;
-          }
-        if (ec->zone->h != rem->prop.res_y)
-          {
-             int py;
-
-             py = ec->y + (ec->h / 2);
-             if (py < ((rem->prop.res_y * 1) / 3))
-               {
-                  if (ec->zone->h >= (rem->prop.res_y / 3))
-                    ec->y = rem->prop.pos_y;
-                  else
-                    ec->y = ((rem->prop.pos_y - 0) * ec->zone->h) /
-                      (rem->prop.res_y / 3);
-               }
-             else if (py < ((rem->prop.res_y * 2) / 3))
-               {
-                  if (ec->zone->h >= (rem->prop.res_y / 3))
-                    ec->y = (ec->zone->h / 2) +
-                      (py - (rem->prop.res_y / 2)) -
-                      (ec->h / 2);
-                  else
-                    ec->y = (ec->zone->h / 2) +
-                      (((py - (rem->prop.res_y / 2)) * ec->zone->h) /
-                       (rem->prop.res_y / 3)) -
-                      (ec->h / 2);
-               }
-             else
-               {
-                  if (ec->zone->h >= (rem->prop.res_y / 3))
-                    ec->y = ec->zone->h +
-                      rem->prop.pos_y - rem->prop.res_y +
-                      (rem->prop.h - ec->client.h);
-                  else
-                    ec->y = ec->zone->h +
-                      (((rem->prop.pos_y - rem->prop.res_y) * ec->zone->h) /
-                       (rem->prop.res_y / 3)) +
-                      (rem->prop.h - ec->client.h);
-               }
-             if ((rem->prop.pos_y >= 0) && (ec->y < 0))
-               ec->y = 0;
-             else if (((rem->prop.pos_y + rem->prop.h) < rem->prop.res_y) &&
-                      ((ec->y + ec->h) > ec->zone->h))
-               ec->y = ec->zone->h - ec->h;
-          }
-        //               if (ec->zone->w != rem->prop.res_x)
-        //                 ec->x = (rem->prop.pos_x * ec->zone->w) / 
rem->prop.res_x;
-        //               if (ec->zone->h != rem->prop.res_y)
-        //                 ec->y = (rem->prop.pos_y * ec->zone->h) / 
rem->prop.res_y;
-        if (
-          /* upper left */
-          (!E_INSIDE(ec->x, ec->y, 0, 0, ec->zone->w, ec->zone->h)) &&
-          /* upper right */
-          (!E_INSIDE(ec->x + ec->w, ec->y, 0, 0, ec->zone->w, ec->zone->h)) &&
-          /* lower left */
-          (!E_INSIDE(ec->x, ec->y + ec->h, 0, 0, ec->zone->w, ec->zone->h)) &&
-          /* lower right */
-          (!E_INSIDE(ec->x + ec->w, ec->y + ec->h, 0, 0, ec->zone->w, 
ec->zone->h))
-          )
-          {
-             e_comp_object_util_center_pos_get(ec->frame, &ec->x, &ec->y);
-             rem->prop.pos_x = ec->x, rem->prop.pos_y = ec->y;
-          }
-        ec->x += ec->zone->x;
-        ec->y += ec->zone->y;
-        ec->placed = 1;
-        ec->changes.pos = 1;
-        EC_CHANGED(ec);
+        if (ec->shaded)
+          rem->prop.shaded = (100 + ec->shade_dir);
+        else
+          rem->prop.shaded = (50 + ec->shade_dir);
      }
-   if (rem->apply & E_REMEMBER_APPLY_LAYER)
+   if (rem->apply & E_REMEMBER_APPLY_ZONE)
      {
-        evas_object_layer_set(ec->frame, rem->prop.layer);
+        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)
      {
-        eina_stringshare_replace(&ec->bordername, NULL);
-        ec->bordername = eina_stringshare_ref(rem->prop.border);
-        ec->border.changed = 1;
-        EC_CHANGED(ec);
+        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_FULLSCREEN)
+   if (rem->apply & E_REMEMBER_APPLY_UUID)
      {
-        if (rem->prop.fullscreen)
-          e_client_fullscreen(ec, e_config->fullscreen_policy);
+        eina_stringshare_refplace(&rem->uuid, ec->uuid);
+        rem->pid = ec->netwm.pid;
+        rem->apply_first_only = 1;
      }
-   if (rem->apply & E_REMEMBER_APPLY_STICKY)
+   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)
      {
-        if (rem->prop.sticky) e_client_stick(ec);
+        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;
      }
-   if (rem->apply & E_REMEMBER_APPLY_SHADE)
+   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)
      {
-        if (rem->prop.shaded >= 100)
-          e_client_shade(ec, rem->prop.shaded - 100);
-        else if (rem->prop.shaded >= 50)
-          e_client_unshade(ec, rem->prop.shaded - 50);
+        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;
      }
-   if (rem->apply & E_REMEMBER_APPLY_LOCKS)
+
+   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]))
      {
-        ec->lock_user_location = rem->prop.lock_user_location;
-        ec->lock_client_location = rem->prop.lock_client_location;
-        ec->lock_user_size = rem->prop.lock_user_size;
-        ec->lock_client_size = rem->prop.lock_client_size;
-        ec->lock_user_stacking = rem->prop.lock_user_stacking;
-        ec->lock_client_stacking = rem->prop.lock_client_stacking;
-        ec->lock_user_iconify = rem->prop.lock_user_iconify;
-        ec->lock_client_iconify = rem->prop.lock_client_iconify;
-        ec->lock_user_desk = rem->prop.lock_user_desk;
-        ec->lock_client_desk = rem->prop.lock_client_desk;
-        ec->lock_user_sticky = rem->prop.lock_user_sticky;
-        ec->lock_client_sticky = rem->prop.lock_client_sticky;
-        ec->lock_user_shade = rem->prop.lock_user_shade;
-        ec->lock_client_shade = rem->prop.lock_client_shade;
-        ec->lock_user_maximize = rem->prop.lock_user_maximize;
-        ec->lock_client_maximize = rem->prop.lock_client_maximize;
-        ec->lock_user_fullscreen = rem->prop.lock_user_fullscreen;
-        ec->lock_client_fullscreen = rem->prop.lock_client_fullscreen;
-        ec->lock_border = rem->prop.lock_border;
-        ec->lock_close = rem->prop.lock_close;
-        ec->lock_focus_in = rem->prop.lock_focus_in;
-        ec->lock_focus_out = rem->prop.lock_focus_out;
-        ec->lock_life = rem->prop.lock_life;
+        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;
      }
-   if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST)
-     ec->user_skip_winlist = rem->prop.skip_winlist;
-   if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER)
-     ec->netwm.state.skip_pager = rem->prop.skip_pager;
-   if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR)
-     ec->netwm.state.skip_taskbar = rem->prop.skip_taskbar;
-   if (rem->apply & E_REMEMBER_APPLY_ICON_PREF)
-     ec->icon_preference = rem->prop.icon_preference;
-   if (rem->apply & E_REMEMBER_APPLY_OFFER_RESISTANCE)
-     ec->offer_resistance = rem->prop.offer_resistance;
-   if (rem->apply & E_REMEMBER_SET_FOCUS_ON_START)
-     ec->want_focus = 1;
-   if (rem->apply & E_REMEMBER_APPLY_OPACITY)
-     ec->netwm.opacity = rem->prop.opacity;
+}
 
-   if (temporary)
-     _e_remember_free(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
diff --git a/src/bin/e_remember.h b/src/bin/e_remember.h
index 1182cd8..5f0bae4 100644
--- a/src/bin/e_remember.h
+++ b/src/bin/e_remember.h
@@ -35,6 +35,7 @@ typedef struct _E_Remember E_Remember;
 #define E_REMEMBER_APPLY_FULLSCREEN       (1 << 15)
 #define E_REMEMBER_APPLY_OFFER_RESISTANCE (1 << 16)
 #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_FM_WINS       (1 << 1)
@@ -109,6 +110,8 @@ struct _E_Remember
       const char   *desktop_file;
       unsigned char opacity;
    } prop;
+   Eina_Stringshare *uuid;
+   int pid;
 };
 
 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 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_apply(E_Remember *rem, E_Client *ec);
 #endif
 #endif
diff --git a/src/bin/e_uuid_store.c b/src/bin/e_uuid_store.c
deleted file mode 100644
index d083c3a..0000000
--- a/src/bin/e_uuid_store.c
+++ /dev/null
@@ -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;
- }
diff --git a/src/bin/e_uuid_store.h b/src/bin/e_uuid_store.h
deleted file mode 100644
index 855c57d..0000000
--- a/src/bin/e_uuid_store.h
+++ /dev/null
@@ -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
diff --git a/src/bin/generated/session-recovery-server-protocol.h 
b/src/bin/generated/session-recovery-server-protocol.h
deleted file mode 100644
index c0880021..0000000
--- a/src/bin/generated/session-recovery-server-protocol.h
+++ /dev/null
@@ -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
diff --git a/src/bin/generated/session-recovery-protocol.c 
b/src/bin/generated/session-recovery.c
similarity index 54%
rename from src/bin/generated/session-recovery-protocol.c
rename to src/bin/generated/session-recovery.c
index 32ddbcb..47ecbb9 100644
--- a/src/bin/generated/session-recovery-protocol.c
+++ b/src/bin/generated/session-recovery.c
@@ -2,22 +2,31 @@
 #include <stdint.h>
 #include "wayland-util.h"
 
+extern const struct wl_interface wl_surface_interface;
 
 static const struct wl_interface *types[] = {
+       &wl_surface_interface,
+       &wl_surface_interface,
+       NULL,
+       &wl_surface_interface,
+       NULL,
+       &wl_surface_interface,
        NULL,
 };
 
 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[] = {
-       { "uuid", "s", types + 0 },
+       { "create_uuid", "os", types + 5 },
 };
 
 WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
        "zwp_e_session_recovery", 1,
-       1, zwp_e_session_recovery_requests,
+       3, zwp_e_session_recovery_requests,
        1, zwp_e_session_recovery_events,
 };
 
diff --git a/src/bin/generated/session-recovery.h 
b/src/bin/generated/session-recovery.h
new file mode 100644
index 0000000..674c77a
--- /dev/null
+++ b/src/bin/generated/session-recovery.h
@@ -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
diff --git a/src/protocol/session-recovery.xml 
b/src/protocol/session-recovery.xml
index 469871e..3109413 100644
--- a/src/protocol/session-recovery.xml
+++ b/src/protocol/session-recovery.xml
@@ -1,10 +1,19 @@
 <protocol name="e_session_recovery">
 
   <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"/>
+    </request>
+    <request name="destroy_uuid">
+      <arg name="surface" type="object" interface="wl_surface"/>
       <arg name="uuid" type="string"/>
     </request>
-    <event name="uuid">
+    <event name="create_uuid">
+      <arg name="surface" type="object" interface="wl_surface"/>
       <arg name="uuid" type="string"/>
     </event>
   </interface>

-- 


Reply via email to