#include "e.h" #define REMEMBER_HIERARCHY 1 #define REMEMBER_SIMPLE 0 typedef struct _E_Remember_List E_Remember_List; struct _E_Remember_List { Eina_List *list; }; /* local subsystem functions */ static void _e_remember_free(E_Remember *rem); static void _e_remember_update(E_Border *bd, E_Remember *rem); static E_Remember *_e_remember_find(E_Border *bd, int check_usable); static void _e_remember_cb_hook_pre_post_fetch(void *data, void *bd); static void _e_remember_cb_hook_eval_post_new_border(void *data, void *bd); static void _e_remember_init_edd(void); static Eina_Bool _e_remember_restore_cb(void *data, int type, void *event); /* local subsystem globals */ static Eina_List *hooks = NULL; static E_Config_DD *e_remember_edd = NULL; static E_Config_DD *e_remember_list_edd = NULL; static E_Remember_List *remembers = NULL; static Eina_List *handlers = NULL; /* static Eina_List *e_remember_restart_list = NULL; */ /* externally accessible functions */ EAPI int e_remember_init(E_Startup_Mode mode) { Eina_List *l = NULL; E_Remember *rem; E_Border_Hook *h; if (mode == E_STARTUP_START) { EINA_LIST_FOREACH(e_config->remembers, l, rem) { if ((rem->apply & E_REMEMBER_APPLY_RUN) && (rem->prop.command)) e_util_head_exec(rem->prop.head, rem->prop.command); } } h = e_border_hook_add(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, _e_remember_cb_hook_pre_post_fetch, NULL); if (h) hooks = eina_list_append(hooks, h); h = e_border_hook_add(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, _e_remember_cb_hook_eval_post_new_border, NULL); if (h) hooks = eina_list_append(hooks, h); _e_remember_init_edd(); remembers = e_config_domain_load("e_remember_restart", e_remember_list_edd); if (remembers) { handlers = eina_list_append (handlers, ecore_event_handler_add (E_EVENT_MODULE_INIT_END, _e_remember_restore_cb, NULL)); } return 1; } EAPI int e_remember_shutdown(void) { E_Border_Hook *h; Ecore_Event_Handler *hh; EINA_LIST_FREE(hooks, h) e_border_hook_del(h); E_CONFIG_DD_FREE(e_remember_edd); E_CONFIG_DD_FREE(e_remember_list_edd); EINA_LIST_FREE(handlers, hh) ecore_event_handler_del(hh); return 1; } EAPI void e_remember_internal_save(void) { Eina_List *l; E_Border *bd; E_Remember *rem; //printf("internal save %d\n", restart); if (!remembers) remembers = E_NEW(E_Remember_List, 1); else { EINA_LIST_FREE(remembers->list, rem) _e_remember_free(rem); } EINA_LIST_FOREACH(e_border_client_list(), l, bd) { if (!bd->internal) continue; rem = E_NEW(E_Remember, 1); if (!rem) break; e_remember_default_match_set(rem, bd); rem->apply = (E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_SIZE | E_REMEMBER_APPLY_BORDER | E_REMEMBER_APPLY_LAYER | E_REMEMBER_APPLY_SHADE | E_REMEMBER_APPLY_ZONE | E_REMEMBER_APPLY_DESKTOP | E_REMEMBER_APPLY_LOCKS | E_REMEMBER_APPLY_SKIP_WINLIST | E_REMEMBER_APPLY_SKIP_PAGER | E_REMEMBER_APPLY_SKIP_TASKBAR); _e_remember_update(bd, rem); remembers->list = eina_list_append(remembers->list, rem); } e_config_domain_save("e_remember_restart", e_remember_list_edd, remembers); } static Eina_Bool _e_remember_restore_cb(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__) { E_Remember *rem; Eina_List *l; E_Action *act_fm, *act; E_Container *con; act_fm = e_action_find("fileman"); con = e_container_current_get(e_manager_current_get()); EINA_LIST_FOREACH(remembers->list, l, rem) { if (!rem->class) continue; if (!strncmp(rem->class, "e_fwin::", 8)) { if (!act_fm) continue; /* at least '/' */ if (!(rem->class + 9)) continue; act_fm->func.go(NULL, rem->class + 8); } else if (!strncmp(rem->class, "_config::", 9)) { char *param = NULL; char path[1024]; const char *p; p = rem->class + 9; if ((param = strstr(p, "::"))) { snprintf(path, (param - p) + sizeof(char), "%s", p); param = param + 2; } else snprintf(path, sizeof(path), "%s", p); if (e_configure_registry_exists(path)) { e_configure_registry_call(path, con, param); } } else if (!strcmp(rem->class, "_configure")) { /* TODO this is just for settings panel. it could also use e_configure_registry_item_add */ /* ..or make a general path for window that are started by actions */ act = e_action_find("configuration"); if (act) act->func.go(NULL, NULL); } } if (handlers) eina_list_free(handlers); handlers = NULL; return ECORE_CALLBACK_DONE; } EAPI E_Remember * e_remember_new(void) { E_Remember *rem; rem = E_NEW(E_Remember, 1); if (!rem) return NULL; e_config->remembers = eina_list_prepend(e_config->remembers, rem); return rem; } EAPI int e_remember_usable_get(E_Remember *rem) { if ((rem->apply_first_only) && (rem->used_count > 0)) return 0; return 1; } EAPI void e_remember_use(E_Remember *rem) { rem->used_count++; } EAPI void e_remember_unuse(E_Remember *rem) { rem->used_count--; } EAPI void e_remember_del(E_Remember *rem) { Eina_List *l = NULL; E_Border *bd; EINA_LIST_FOREACH(e_border_client_list(), l, bd) { if (bd->remember != rem) continue; bd->remember = NULL; e_remember_unuse(rem); } _e_remember_free(rem); } EAPI E_Remember * e_remember_find_usable(E_Border *bd) { E_Remember *rem; rem = _e_remember_find(bd, 1); return rem; } EAPI E_Remember * e_remember_find(E_Border *bd) { E_Remember *rem; rem = _e_remember_find(bd, 0); return rem; } EAPI 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 * loction. */ 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); } } EAPI int e_remember_default_match_set(E_Remember *rem, E_Border *bd) { const char *title, *clasz, *name, *role; 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); rem->name = NULL; rem->class = NULL; rem->title = NULL; rem->role = NULL; name = bd->client.icccm.name; if (!name || name[0] == 0) name = NULL; clasz = bd->client.icccm.class; if (!clasz || clasz[0] == 0) clasz = NULL; role = bd->client.icccm.window_role; if (!role || role[0] == 0) role = NULL; int match = E_REMEMBER_MATCH_TRANSIENT; if (bd->client.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_add(name); rem->class = eina_stringshare_add(clasz); } else if ((title = e_border_name_get(bd)) && title[0]) { match |= E_REMEMBER_MATCH_TITLE; rem->title = eina_stringshare_add(title); } if (role) { match |= E_REMEMBER_MATCH_ROLE; rem->role = eina_stringshare_add(role); } if (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_UNKNOWN) { match |= E_REMEMBER_MATCH_TYPE; rem->type = bd->client.netwm.type; } rem->match = match; return match; } EAPI void e_remember_update(E_Border *bd) { if (bd->new_client) return; if (!bd->remember) return; if (bd->remember->keep_settings) return; _e_remember_update(bd, bd->remember); e_config_save_queue(); } static void _e_remember_update(E_Border *bd, E_Remember *rem) { if (rem->apply & E_REMEMBER_APPLY_POS || rem->apply & E_REMEMBER_APPLY_SIZE) { if (bd->fullscreen) { rem->prop.pos_x = bd->saved.x; rem->prop.pos_y = bd->saved.y; rem->prop.pos_w = bd->saved.w; rem->prop.pos_h = bd->saved.h; } else { rem->prop.pos_x = bd->x - bd->zone->x; rem->prop.pos_y = bd->y - bd->zone->y; rem->prop.res_x = bd->zone->w; rem->prop.res_y = bd->zone->h; rem->prop.pos_w = bd->client.w; rem->prop.pos_h = bd->client.h; rem->prop.w = bd->client.w; rem->prop.h = bd->client.h; } } if (rem->apply & E_REMEMBER_APPLY_LAYER) { if (bd->fullscreen) rem->prop.layer = bd->saved.layer; else rem->prop.layer = bd->layer; } if (rem->apply & E_REMEMBER_APPLY_LOCKS) { rem->prop.lock_user_location = bd->lock_user_location; rem->prop.lock_client_location = bd->lock_client_location; rem->prop.lock_user_size = bd->lock_user_size; rem->prop.lock_client_size = bd->lock_client_size; rem->prop.lock_user_stacking = bd->lock_user_stacking; rem->prop.lock_client_stacking = bd->lock_client_stacking; rem->prop.lock_user_iconify = bd->lock_user_iconify; rem->prop.lock_client_iconify = bd->lock_client_iconify; rem->prop.lock_user_desk = bd->lock_user_desk; rem->prop.lock_client_desk = bd->lock_client_desk; rem->prop.lock_user_sticky = bd->lock_user_sticky; rem->prop.lock_client_sticky = bd->lock_client_sticky; rem->prop.lock_user_shade = bd->lock_user_shade; rem->prop.lock_client_shade = bd->lock_client_shade; rem->prop.lock_user_maximize = bd->lock_user_maximize; rem->prop.lock_client_maximize = bd->lock_client_maximize; rem->prop.lock_user_fullscreen = bd->lock_user_fullscreen; rem->prop.lock_client_fullscreen = bd->lock_client_fullscreen; rem->prop.lock_border = bd->lock_border; rem->prop.lock_close = bd->lock_close; rem->prop.lock_focus_in = bd->lock_focus_in; rem->prop.lock_focus_out = bd->lock_focus_out; rem->prop.lock_life = bd->lock_life; } if (rem->apply & E_REMEMBER_APPLY_SHADE) { if (bd->shaded) rem->prop.shaded = (100 + bd->shade.dir); else rem->prop.shaded = (50 + bd->shade.dir); } if (rem->apply & E_REMEMBER_APPLY_ZONE) { rem->prop.zone = bd->zone->num; rem->prop.head = bd->zone->container->manager->num; } if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST) rem->prop.skip_winlist = bd->user_skip_winlist; if (rem->apply & E_REMEMBER_APPLY_STICKY) rem->prop.sticky = bd->sticky; if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER) rem->prop.skip_pager = bd->client.netwm.state.skip_pager; if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR) rem->prop.skip_taskbar = bd->client.netwm.state.skip_taskbar; if (rem->apply & E_REMEMBER_APPLY_ICON_PREF) rem->prop.icon_preference = bd->icon_preference; if (rem->apply & E_REMEMBER_APPLY_DESKTOP) e_desk_xy_get(bd->desk, &rem->prop.desk_x, &rem->prop.desk_y); if (rem->apply & E_REMEMBER_APPLY_FULLSCREEN) rem->prop.fullscreen = bd->fullscreen; } /* local subsystem functions */ static E_Remember * _e_remember_find(E_Border *bd, 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 (bd->client.netwm.name) title = bd->client.netwm.name; else title = bd->client.icccm.title; if ((rem->match & E_REMEMBER_MATCH_NAME) && ((!e_util_strcmp(rem->name, bd->client.icccm.name)) || (e_util_both_str_empty(rem->name, bd->client.icccm.name)))) matches++; if ((rem->match & E_REMEMBER_MATCH_CLASS) && ((!e_util_strcmp(rem->class, bd->client.icccm.class)) || (e_util_both_str_empty(rem->class, bd->client.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, bd->client.icccm.window_role)) || (e_util_both_str_empty(rem->role, bd->client.icccm.window_role)))) matches++; if ((rem->match & E_REMEMBER_MATCH_TYPE) && (rem->type == bd->client.netwm.type)) matches++; if ((rem->match & E_REMEMBER_MATCH_TRANSIENT) && (((rem->transient) && (bd->client.icccm.transient_for != 0)) || ((!rem->transient) && (bd->client.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 (bd->client.netwm.name) title = bd->client.netwm.name; else title = bd->client.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(bd->client.icccm.name, rem->name)) continue; if (rem->match & E_REMEMBER_MATCH_CLASS && !e_util_glob_match(bd->client.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, bd->client.icccm.window_role) && !e_util_both_str_empty(rem->role, bd->client.icccm.window_role)) continue; if (rem->match & E_REMEMBER_MATCH_TYPE && rem->type != (int) bd->client.netwm.type) continue; if (rem->match & E_REMEMBER_MATCH_TRANSIENT && !(rem->transient && bd->client.icccm.transient_for != 0) && !(!rem->transient) && (bd->client.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_border(void *data __UNUSED__, void *border) { E_Border *bd; bd = border; // remember only when window was modified // if (!bd->new_client) return; if ((bd->internal) && (!bd->remember) && (e_config->remember_internal_windows) && (!bd->internal_no_remember) && (bd->client.icccm.class && bd->client.icccm.class[0])) { E_Remember *rem; if (!strncmp(bd->client.icccm.class, "e_fwin", 6)) { if (!(e_config->remember_internal_windows & E_REMEMBER_INTERNAL_FM_WINS)) return; } else { if (!(e_config->remember_internal_windows & E_REMEMBER_INTERNAL_DIALOGS)) return; } rem = e_remember_new(); if (!rem) return; e_remember_default_match_set(rem, bd); rem->apply = E_REMEMBER_APPLY_POS | E_REMEMBER_APPLY_SIZE | E_REMEMBER_APPLY_BORDER; e_remember_use(rem); e_remember_update(bd); bd->remember = rem; } } static void _e_remember_cb_hook_pre_post_fetch(void *data __UNUSED__, void *border) { E_Border *bd = border; E_Remember *rem = NULL; int temporary = 0; if ((!bd->new_client) || (bd->internal_no_remember)) return; if (!bd->remember) { rem = e_remember_find_usable(bd); if (rem) { bd->remember = rem; e_remember_use(rem); } } if (bd->internal && remembers && bd->client.icccm.class && bd->client.icccm.class[0]) { Eina_List *l; EINA_LIST_FOREACH(remembers->list, l, rem) { if (rem->class && !strcmp(rem->class, bd->client.icccm.class)) break; } if (rem) { temporary = 1; remembers->list = eina_list_remove(remembers->list, rem); if (!remembers->list) e_config_domain_save("e_remember_restart", e_remember_list_edd, remembers); } else rem = bd->remember; } if (!rem) return; if (rem->apply & E_REMEMBER_APPLY_ZONE) { E_Zone *zone; zone = e_container_zone_number_get(bd->zone->container, rem->prop.zone); if (zone) e_border_zone_set(bd, zone); } if (rem->apply & E_REMEMBER_APPLY_DESKTOP) { E_Desk *desk; desk = e_desk_at_xy_get(bd->zone, rem->prop.desk_x, rem->prop.desk_y); if (desk) { e_border_desk_set(bd, desk); if (e_config->desk_auto_switch) e_desk_show(desk); } } if (rem->apply & E_REMEMBER_APPLY_SIZE) { bd->client.w = rem->prop.w; bd->client.h = rem->prop.h; /* we can trust internal windows */ if (bd->internal) { if (bd->zone->w != rem->prop.res_x) { if (bd->client.w > (bd->zone->w - 64)) bd->client.w = bd->zone->w - 64; } if (bd->zone->h != rem->prop.res_y) { if (bd->client.h > (bd->zone->h - 64)) bd->client.h = bd->zone->h - 64; } if (bd->client.icccm.min_w > bd->client.w) bd->client.w = bd->client.icccm.min_w; if (bd->client.icccm.max_w < bd->client.w) bd->client.w = bd->client.icccm.max_w; if (bd->client.icccm.min_h > bd->client.h) bd->client.h = bd->client.icccm.min_h; if (bd->client.icccm.max_h < bd->client.h) bd->client.h = bd->client.icccm.max_h; } bd->w = bd->client.w + bd->client_inset.l + bd->client_inset.r; bd->h = bd->client.h + bd->client_inset.t + bd->client_inset.b; bd->changes.size = 1; bd->changes.shape = 1; } if ((rem->apply & E_REMEMBER_APPLY_POS) && (!bd->re_manage)) { bd->x = rem->prop.pos_x; bd->y = rem->prop.pos_y; if (bd->zone->w != rem->prop.res_x) { int px; px = bd->x + (bd->w / 2); if (px < ((rem->prop.res_x * 1) / 3)) { if (bd->zone->w >= (rem->prop.res_x / 3)) bd->x = rem->prop.pos_x; else bd->x = ((rem->prop.pos_x - 0) * bd->zone->w) / (rem->prop.res_x / 3); } else if (px < ((rem->prop.res_x * 2) / 3)) { if (bd->zone->w >= (rem->prop.res_x / 3)) bd->x = (bd->zone->w / 2) + (px - (rem->prop.res_x / 2)) - (bd->w / 2); else bd->x = (bd->zone->w / 2) + (((px - (rem->prop.res_x / 2)) * bd->zone->w) / (rem->prop.res_x / 3)) - (bd->w / 2); } else { if (bd->zone->w >= (rem->prop.res_x / 3)) bd->x = bd->zone->w + rem->prop.pos_x - rem->prop.res_x + (rem->prop.w - bd->client.w); else bd->x = bd->zone->w + (((rem->prop.pos_x - rem->prop.res_x) * bd->zone->w) / (rem->prop.res_x / 3)) + (rem->prop.w - bd->client.w); } if ((rem->prop.pos_x >= 0) && (bd->x < 0)) bd->x = 0; else if (((rem->prop.pos_x + rem->prop.w) < rem->prop.res_x) && ((bd->x + bd->w) > bd->zone->w)) bd->x = bd->zone->w - bd->w; } if (bd->zone->h != rem->prop.res_y) { int py; py = bd->y + (bd->h / 2); if (py < ((rem->prop.res_y * 1) / 3)) { if (bd->zone->h >= (rem->prop.res_y / 3)) bd->y = rem->prop.pos_y; else bd->y = ((rem->prop.pos_y - 0) * bd->zone->h) / (rem->prop.res_y / 3); } else if (py < ((rem->prop.res_y * 2) / 3)) { if (bd->zone->h >= (rem->prop.res_y / 3)) bd->y = (bd->zone->h / 2) + (py - (rem->prop.res_y / 2)) - (bd->h / 2); else bd->y = (bd->zone->h / 2) + (((py - (rem->prop.res_y / 2)) * bd->zone->h) / (rem->prop.res_y / 3)) - (bd->h / 2); } else { if (bd->zone->h >= (rem->prop.res_y / 3)) bd->y = bd->zone->h + rem->prop.pos_y - rem->prop.res_y + (rem->prop.h - bd->client.h); else bd->y = bd->zone->h + (((rem->prop.pos_y - rem->prop.res_y) * bd->zone->h) / (rem->prop.res_y / 3)) + (rem->prop.h - bd->client.h); } if ((rem->prop.pos_y >= 0) && (bd->y < 0)) bd->y = 0; else if (((rem->prop.pos_y + rem->prop.h) < rem->prop.res_y) && ((bd->y + bd->h) > bd->zone->h)) bd->y = bd->zone->h - bd->h; } // if (bd->zone->w != rem->prop.res_x) // bd->x = (rem->prop.pos_x * bd->zone->w) / rem->prop.res_x; // if (bd->zone->h != rem->prop.res_y) // bd->y = (rem->prop.pos_y * bd->zone->h) / rem->prop.res_y; bd->x += bd->zone->x; bd->y += bd->zone->y; bd->placed = 1; bd->changes.pos = 1; } if (rem->apply & E_REMEMBER_APPLY_LAYER) { bd->layer = rem->prop.layer; if (bd->layer == 100) e_hints_window_stacking_set(bd, E_STACKING_NONE); else if (bd->layer == 150) e_hints_window_stacking_set(bd, E_STACKING_ABOVE); e_container_border_raise(bd); } if (rem->apply & E_REMEMBER_APPLY_BORDER) { if (rem->prop.border) { if (bd->bordername) eina_stringshare_del(bd->bordername); if (rem->prop.border) bd->bordername = eina_stringshare_add(rem->prop.border); else bd->bordername = NULL; bd->client.border.changed = 1; } } if (rem->apply & E_REMEMBER_APPLY_FULLSCREEN) { if (rem->prop.fullscreen) e_border_fullscreen(bd, e_config->fullscreen_policy); } if (rem->apply & E_REMEMBER_APPLY_STICKY) { if (rem->prop.sticky) e_border_stick(bd); } if (rem->apply & E_REMEMBER_APPLY_SHADE) { if (rem->prop.shaded >= 100) e_border_shade(bd, rem->prop.shaded - 100); else if (rem->prop.shaded >= 50) e_border_unshade(bd, rem->prop.shaded - 50); } if (rem->apply & E_REMEMBER_APPLY_LOCKS) { bd->lock_user_location = rem->prop.lock_user_location; bd->lock_client_location = rem->prop.lock_client_location; bd->lock_user_size = rem->prop.lock_user_size; bd->lock_client_size = rem->prop.lock_client_size; bd->lock_user_stacking = rem->prop.lock_user_stacking; bd->lock_client_stacking = rem->prop.lock_client_stacking; bd->lock_user_iconify = rem->prop.lock_user_iconify; bd->lock_client_iconify = rem->prop.lock_client_iconify; bd->lock_user_desk = rem->prop.lock_user_desk; bd->lock_client_desk = rem->prop.lock_client_desk; bd->lock_user_sticky = rem->prop.lock_user_sticky; bd->lock_client_sticky = rem->prop.lock_client_sticky; bd->lock_user_shade = rem->prop.lock_user_shade; bd->lock_client_shade = rem->prop.lock_client_shade; bd->lock_user_maximize = rem->prop.lock_user_maximize; bd->lock_client_maximize = rem->prop.lock_client_maximize; bd->lock_user_fullscreen = rem->prop.lock_user_fullscreen; bd->lock_client_fullscreen = rem->prop.lock_client_fullscreen; bd->lock_border = rem->prop.lock_border; bd->lock_close = rem->prop.lock_close; bd->lock_focus_in = rem->prop.lock_focus_in; bd->lock_focus_out = rem->prop.lock_focus_out; bd->lock_life = rem->prop.lock_life; } if (rem->apply & E_REMEMBER_APPLY_SKIP_WINLIST) bd->user_skip_winlist = rem->prop.skip_winlist; if (rem->apply & E_REMEMBER_APPLY_SKIP_PAGER) bd->client.netwm.state.skip_pager = rem->prop.skip_pager; if (rem->apply & E_REMEMBER_APPLY_SKIP_TASKBAR) bd->client.netwm.state.skip_taskbar = rem->prop.skip_taskbar; if (rem->apply & E_REMEMBER_APPLY_ICON_PREF) bd->icon_preference = rem->prop.icon_preference; if (rem->apply & E_REMEMBER_SET_FOCUS_ON_START) bd->want_focus = 1; if (temporary) _e_remember_free(rem); } static void _e_remember_init_edd(void) { e_remember_edd = E_CONFIG_DD_NEW("E_Remember", E_Remember); #undef T #undef D #define T E_Remember #define D e_remember_edd E_CONFIG_VAL(D, T, match, INT); E_CONFIG_VAL(D, T, apply_first_only, UCHAR); E_CONFIG_VAL(D, T, keep_settings, UCHAR); E_CONFIG_VAL(D, T, name, STR); E_CONFIG_VAL(D, T, class, STR); E_CONFIG_VAL(D, T, title, STR); E_CONFIG_VAL(D, T, role, STR); E_CONFIG_VAL(D, T, type, INT); E_CONFIG_VAL(D, T, transient, UCHAR); E_CONFIG_VAL(D, T, apply, INT); E_CONFIG_VAL(D, T, max_score, INT); E_CONFIG_VAL(D, T, prop.pos_x, INT); E_CONFIG_VAL(D, T, prop.pos_y, INT); E_CONFIG_VAL(D, T, prop.res_x, INT); E_CONFIG_VAL(D, T, prop.res_y, INT); E_CONFIG_VAL(D, T, prop.pos_w, INT); E_CONFIG_VAL(D, T, prop.pos_h, INT); E_CONFIG_VAL(D, T, prop.w, INT); E_CONFIG_VAL(D, T, prop.h, INT); E_CONFIG_VAL(D, T, prop.layer, INT); E_CONFIG_VAL(D, T, prop.lock_user_location, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_location, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_size, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_size, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_stacking, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_stacking, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_iconify, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_iconify, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_desk, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_desk, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_sticky, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_sticky, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_shade, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_shade, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_maximize, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_maximize, UCHAR); E_CONFIG_VAL(D, T, prop.lock_user_fullscreen, UCHAR); E_CONFIG_VAL(D, T, prop.lock_client_fullscreen, UCHAR); E_CONFIG_VAL(D, T, prop.lock_border, UCHAR); E_CONFIG_VAL(D, T, prop.lock_close, UCHAR); E_CONFIG_VAL(D, T, prop.lock_focus_in, UCHAR); E_CONFIG_VAL(D, T, prop.lock_focus_out, UCHAR); E_CONFIG_VAL(D, T, prop.lock_life, UCHAR); E_CONFIG_VAL(D, T, prop.border, STR); E_CONFIG_VAL(D, T, prop.sticky, UCHAR); E_CONFIG_VAL(D, T, prop.shaded, UCHAR); E_CONFIG_VAL(D, T, prop.skip_winlist, UCHAR); E_CONFIG_VAL(D, T, prop.skip_pager, UCHAR); E_CONFIG_VAL(D, T, prop.skip_taskbar, UCHAR); E_CONFIG_VAL(D, T, prop.fullscreen, UCHAR); E_CONFIG_VAL(D, T, prop.desk_x, INT); E_CONFIG_VAL(D, T, prop.desk_y, INT); E_CONFIG_VAL(D, T, prop.zone, INT); E_CONFIG_VAL(D, T, prop.head, INT); E_CONFIG_VAL(D, T, prop.command, STR); E_CONFIG_VAL(D, T, prop.icon_preference, UCHAR); E_CONFIG_VAL(D, T, prop.desktop_file, STR); #undef T #undef D e_remember_list_edd = E_CONFIG_DD_NEW("E_Remember_List", E_Remember_List); #undef T #undef D #define T E_Remember_List #define D e_remember_list_edd E_CONFIG_LIST(D, T, list, e_remember_edd); #undef T #undef D }