diff --git a/TODO b/TODO index f857c6772..afe4a4819 100644 --- a/TODO +++ b/TODO @@ -8,6 +8,7 @@ Some of the things (in very short form) that need to be done to E17... BUGS / FIXES ------------------------------------------------------------------------------- +* if always click to raise is set, double clicks stop working (sometimes) * e_hints.c manually changes flags on a border isnetad of calling e_border_stick() for exampe or the calls in e_border.c - add calls as needed to e_border.c. before calling check the lock flags too. @@ -43,6 +44,7 @@ Some of the things (in very short form) that need to be done to E17... ESSENTIAL FEATURES ------------------------------------------------------------------------------- +* emit signal to submenu entries if they have a submenu shown for them or not * add window placement options like place at pointer * shaded windows should not allow border changes by the user * if a border is borderless it should not be allowed to be shaded (padl/r/t/b diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 5d0eea572..72f83f12d 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -1931,6 +1931,11 @@ _e_border_free(E_Border *bd) e_object_del(E_OBJECT(bd->border_locks_menu)); bd->border_locks_menu = NULL; } + if (bd->border_remember_menu) + { + e_object_del(E_OBJECT(bd->border_remember_menu)); + bd->border_remember_menu = NULL; + } if (focused == bd) { ecore_x_window_focus(bd->zone->container->manager->root); @@ -1944,6 +1949,11 @@ _e_border_free(E_Border *bd) bd->handlers = evas_list_remove_list(bd->handlers, bd->handlers); ecore_event_handler_del(h); } + if (bd->remember) + { + e_remember_unuse(bd->remember); + bd->remember = NULL; + } if (!bd->already_unparented) { ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root, @@ -3958,6 +3968,123 @@ _e_border_eval(E_Border *bd) bd->changes.shape = 0; } + if (bd->new_client) + { + E_Remember *rem = NULL; + + if (!bd->remember) + { + rem = e_remember_find(bd); + if ((rem) && (e_remember_usable_get(rem))) + { + bd->remember = rem; + e_remember_use(rem); + } + } + if (bd->remember) + { + rem = bd->remember; + + 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 (rem->apply & E_REMEMBER_APPLY_POS) + { + E_Event_Border_Move *ev; + + bd->x = rem->prop.pos_x; + bd->y = rem->prop.pos_y; + if (bd->zone->w != rem->prop.res_x) + { + bd->x = (rem->prop.pos_x * rem->prop.res_x) / bd->zone->w; + } + if (bd->zone->h != rem->prop.res_y) + { + bd->y = (rem->prop.pos_y * rem->prop.res_y) / bd->zone->h; + } + bd->x += bd->zone->x; + bd->y += bd->zone->y; + bd->placed = 1; + bd->changes.pos = 1; + } + if (rem->apply & E_REMEMBER_APPLY_SIZE) + { + E_Event_Border_Resize *ev; + + bd->w = rem->prop.w + bd->client_inset.l + bd->client_inset.r; + bd->h = rem->prop.h + bd->client_inset.t + bd->client_inset.b; + bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r); + bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b); + bd->changes.size = 1; + bd->changes.shape = 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_FREE(bd->client.border.name); + if (rem->prop.border) + bd->client.border.name = strdup(rem->prop.border); + bd->client.border.changed = 1; + } + if (rem->apply & E_REMEMBER_APPLY_STICKY) + { + if (rem->prop.sticky) e_border_stick(bd); + } + if (rem->apply & E_REMEMBER_APPLY_SHADE) + { + /* FIXME: determine shade dir */ + e_border_shade(bd, E_DIRECTION_UP); + } + 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_mazimize = rem->prop.lock_client_mazimize; + 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 (bd->client.border.changed) { Evas_Object *o; @@ -4135,7 +4262,7 @@ _e_border_eval(E_Border *bd) bd->y -= bd->client_inset.t; bd->changes.pos = 1; } - else + else if (!bd->placed) { if (bd->client.icccm.request_pos) { @@ -4237,19 +4364,25 @@ _e_border_eval(E_Border *bd) E_Border_Pending_Move_Resize *pnd; pnd = bd->pending_move_resize->data; - if (pnd->move) + if (!bd->lock_client_location) { - bd->x = pnd->x; - bd->y = pnd->y; - bd->changes.pos = 1; + if (pnd->move) + { + bd->x = pnd->x; + bd->y = pnd->y; + bd->changes.pos = 1; + } } - if (pnd->resize) + if (!bd->lock_client_size) { - bd->w = pnd->w; - bd->h = pnd->h; - bd->client.w = pnd->w - (bd->client_inset.l + bd->client_inset.r); - bd->client.h = pnd->h - (bd->client_inset.t + bd->client_inset.b); - bd->changes.size = 1; + if (pnd->resize) + { + bd->w = pnd->w; + bd->h = pnd->h; + bd->client.w = pnd->w - (bd->client_inset.l + bd->client_inset.r); + bd->client.h = pnd->h - (bd->client_inset.t + bd->client_inset.b); + bd->changes.size = 1; + } } free(pnd); bd->pending_move_resize = evas_list_remove_list(bd->pending_move_resize, bd->pending_move_resize); @@ -4579,6 +4712,9 @@ _e_border_eval(E_Border *bd) bd->changes.stack = 0; bd->changes.prop = 0; bd->changes.border = 0; + + if (bd->remember) + e_remember_update(bd->remember, bd); } static void @@ -4886,6 +5022,11 @@ _e_border_cb_border_menu_end(void *data, E_Menu *m) e_object_del(E_OBJECT(bd->border_locks_menu)); bd->border_locks_menu = NULL; } + if (bd->border_remember_menu) + { + e_object_del(E_OBJECT(bd->border_remember_menu)); + bd->border_remember_menu = NULL; + } bd->border_menu = NULL; } e_object_del(E_OBJECT(m)); @@ -4898,6 +5039,7 @@ _e_border_menu_cb_##var(void *data, E_Menu *m, E_Menu_Item *mi) \ E_Border *bd; \ bd = data; \ bd->var = e_menu_item_toggle_get(mi); \ + bd->changed = 1; \ } NEW_LOCK_FN(lock_user_location) @@ -4924,6 +5066,230 @@ NEW_LOCK_FN(lock_close) /*NEW_LOCK_FN(lock_focus_out)*/ NEW_LOCK_FN(lock_life) +static void +_e_border_menu_cb_remember(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) + { + bd->remember = e_remember_new(); + if (bd->remember) + { + e_remember_use(bd->remember); + e_remember_update(bd->remember, bd); + } + } + else + { + Evas_List *l; + + e_remember_unuse(bd->remember); + e_remember_del(bd->remember); + bd->remember = NULL; + for (l = bd->border_remember_menu->items; l; l = l->next) + { + E_Menu_Item *mi2; + + mi2 = l->data; + e_menu_item_toggle_set(mi2, 0); + } + } + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_first(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + bd->remember->apply_first_only = e_menu_item_toggle_get(mi); + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_match_name(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->match |= E_REMEMBER_MATCH_NAME; + else + bd->remember->match &= ~E_REMEMBER_MATCH_NAME; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_match_class(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->match |= E_REMEMBER_MATCH_CLASS; + else + bd->remember->match &= ~E_REMEMBER_MATCH_CLASS; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_match_title(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->match |= E_REMEMBER_MATCH_TITLE; + else + bd->remember->match &= ~E_REMEMBER_MATCH_TITLE; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_match_role(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->match |= E_REMEMBER_MATCH_ROLE; + else + bd->remember->match &= ~E_REMEMBER_MATCH_ROLE; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_pos(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_POS; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_POS; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_size(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_SIZE; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_SIZE; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_layer(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_LAYER; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_LAYER; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_locks(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_LOCKS; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_LOCKS; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_border(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_BORDER; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_BORDER; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_sticky(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_STICKY; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_STICKY; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_desktop(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_DESKTOP; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_DESKTOP; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_shade(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_SHADE; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_SHADE; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_zone(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_ZONE; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_ZONE; + e_config_save_queue(); +} + +static void +_e_border_menu_cb_remember_apply_run(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd; + bd = data; + if (!bd->remember) return; + if (e_menu_item_toggle_get(mi)) + bd->remember->apply |= E_REMEMBER_APPLY_RUN; + else + bd->remember->apply &= ~E_REMEMBER_APPLY_RUN; + e_config_save_queue(); +} + static void _e_border_menu_show(E_Border *bd, Evas_Coord x, Evas_Coord y, int key) { @@ -4971,7 +5337,49 @@ _e_border_menu_show(E_Border *bd, Evas_Coord x, Evas_Coord y, int key) /* NEW_LOCK_MI(_("Focus In"), lock_focus_in);*/ /* NEW_LOCK_MI(_("Focus Out"), lock_focus_out);*/ /* NEW_LOCK_MI(_("Lifespan"), lock_life);*/ + + m = e_menu_new(); + bd->border_remember_menu = m; +#define NEW_REMEMBER_MI(txt, flag, var, cb) \ + mi = e_menu_item_new(m); \ + e_menu_item_label_set(mi, txt); \ + e_menu_item_check_set(mi, 1); \ + if ((bd->remember) && (bd->remember->flag & var)) \ + e_menu_item_toggle_set(mi, 1); \ + e_menu_item_callback_set(mi, cb, bd); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Remember this window")); \ + e_menu_item_check_set(mi, 1); + if (bd->remember) + e_menu_item_toggle_set(mi, 1); + e_menu_item_callback_set(mi, _e_border_menu_cb_remember, bd); + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + NEW_REMEMBER_MI(_("Remember this instance only"), apply_first_only, 1, _e_border_menu_cb_remember_first); + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + NEW_REMEMBER_MI(_("Match by name"), match, E_REMEMBER_MATCH_NAME, _e_border_menu_cb_remember_match_name); + NEW_REMEMBER_MI(_("Match by class"), match, E_REMEMBER_MATCH_CLASS, _e_border_menu_cb_remember_match_class); + NEW_REMEMBER_MI(_("Match by title"), match, E_REMEMBER_MATCH_TITLE, _e_border_menu_cb_remember_match_title); + NEW_REMEMBER_MI(_("Match by role"), match, E_REMEMBER_MATCH_ROLE, _e_border_menu_cb_remember_match_role); + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + NEW_REMEMBER_MI(_("Remember position"), apply, E_REMEMBER_APPLY_POS, _e_border_menu_cb_remember_apply_pos); + NEW_REMEMBER_MI(_("Remember size"), apply, E_REMEMBER_APPLY_SIZE, _e_border_menu_cb_remember_apply_size); + NEW_REMEMBER_MI(_("Remember stacking"), apply, E_REMEMBER_APPLY_LAYER, _e_border_menu_cb_remember_apply_layer); + NEW_REMEMBER_MI(_("Remember locks"), apply, E_REMEMBER_APPLY_LOCKS, _e_border_menu_cb_remember_apply_locks); + NEW_REMEMBER_MI(_("Remember border"), apply, E_REMEMBER_APPLY_BORDER, _e_border_menu_cb_remember_apply_border); + NEW_REMEMBER_MI(_("Remember stickiness"), apply, E_REMEMBER_APPLY_STICKY, _e_border_menu_cb_remember_apply_sticky); + NEW_REMEMBER_MI(_("Remember desktop"), apply, E_REMEMBER_APPLY_DESKTOP, _e_border_menu_cb_remember_apply_desktop); + NEW_REMEMBER_MI(_("Remember shaded state"), apply, E_REMEMBER_APPLY_SHADE, _e_border_menu_cb_remember_apply_shade); + NEW_REMEMBER_MI(_("Remember zone"), apply, E_REMEMBER_APPLY_ZONE, _e_border_menu_cb_remember_apply_zone); +/* + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + NEW_REMEMBER_MI(_("Run this porgram on login"), apply, E_REMEMBER_APPLY_RUN, _e_border_menu_cb_remember_apply_run); + */ m = e_menu_new(); e_object_data_set(E_OBJECT(m), bd); bd->border_menu = m; @@ -5104,6 +5512,13 @@ _e_border_menu_show(E_Border *bd, Evas_Coord x, Evas_Coord y, int key) "widgets/border/default/locks"), "widgets/border/default/locks"); mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Remember")); + e_menu_item_submenu_set(mi, bd->border_remember_menu); + e_menu_item_icon_edje_set(mi, + (char *)e_theme_edje_file_get("base/theme/borders", + "widgets/border/default/remember"), + "widgets/border/default/remember"); + mi = e_menu_item_new(m); e_menu_item_separator_set(mi, 1); mi = e_menu_item_new(m); diff --git a/src/bin/e_border.h b/src/bin/e_border.h index 3bce2986e..03a6b22db 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -269,6 +269,7 @@ struct _E_Border unsigned int focused : 1; unsigned int new_client : 1; unsigned int re_manage : 1; + unsigned int placed : 1; unsigned int shading : 1; unsigned int shaded : 1; unsigned int iconic : 1; @@ -332,6 +333,7 @@ struct _E_Border Evas_List *stick_desks; E_Menu *border_menu; E_Menu *border_locks_menu; + E_Menu *border_remember_menu; Evas_List *pending_move_resize; struct { @@ -360,6 +362,7 @@ struct _E_Border Ecore_Timer *kill_timer; int shape_rects_num; Ecore_X_Rectangle *shape_rects; + E_Remember *remember; Ecore_Timer *dangling_ref_check; }; diff --git a/src/bin/e_config.c b/src/bin/e_config.c index c30fca87e..534eb00ff 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -33,6 +33,7 @@ static E_Config_DD *_e_config_bindings_mouse_edd = NULL; static E_Config_DD *_e_config_bindings_key_edd = NULL; static E_Config_DD *_e_config_path_append_edd = NULL; static E_Config_DD *_e_config_desktop_bg_edd = NULL; +static E_Config_DD *_e_config_remember_edd = NULL; /* externally accessible functions */ int @@ -114,6 +115,59 @@ e_config_init(void) E_CONFIG_VAL(D, T, params, STR); E_CONFIG_VAL(D, T, any_mod, UCHAR); + _e_config_remember_edd = E_CONFIG_DD_NEW("E_Remember", E_Remember); +#undef T +#undef D +#define T E_Remember +#define D _e_config_remember_edd + E_CONFIG_VAL(D, T, match, INT); + E_CONFIG_VAL(D, T, apply_first_only, 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, apply, 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_mazimize, 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.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_edd = E_CONFIG_DD_NEW("E_Config", E_Config); #undef T #undef D @@ -191,6 +245,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, transition_start, STR); /**/ E_CONFIG_VAL(D, T, transition_desk, STR); /**/ E_CONFIG_VAL(D, T, transition_change, STR); /**/ + E_CONFIG_LIST(D, T, remembers, _e_config_remember_edd); e_config = e_config_domain_load("e", _e_config_edd); if (e_config) diff --git a/src/bin/e_config.h b/src/bin/e_config.h index b8cec4e6a..45001edeb 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -134,6 +134,7 @@ struct _E_Config char *transition_start; char *transition_desk; char *transition_change; + Evas_List *remembers; }; struct _E_Config_Module diff --git a/src/bin/e_remember.c b/src/bin/e_remember.c index 2bda68369..a9b38c990 100644 --- a/src/bin/e_remember.c +++ b/src/bin/e_remember.c @@ -4,6 +4,7 @@ #include "e.h" /* local subsystem functions */ +static void _e_remember_free(E_Remember *rem); /* local subsystem globals */ @@ -12,6 +13,17 @@ int e_remember_init(void) { + Evas_List *l; + + for (l = e_config->remembers; l; l = l->next) + { + E_Remember *rem; + + rem = l->data; + if ((rem->apply & E_REMEMBER_APPLY_RUN) && + (rem->prop.command)) + e_util_head_exec(rem->prop.head, rem->prop.command); + } return 1; } @@ -21,4 +33,184 @@ e_remember_shutdown(void) return 1; } +E_Remember * +e_remember_new(void) +{ + E_Remember *rem; + + rem = E_NEW(E_Remember, 1); + if (!rem) return NULL; + e_config->remembers = evas_list_prepend(e_config->remembers, rem); + return rem; +} + +int +e_remember_usable_get(E_Remember *rem) +{ + if ((rem->apply_first_only) && (rem->used_count > 0)) return 0; + return 1; +} + +void +e_remember_use(E_Remember *rem) +{ + rem->used_count++; +} + +void +e_remember_unuse(E_Remember *rem) +{ + rem->used_count--; + if ((rem->used_count <= 0) && (rem->delete_me)) + _e_remember_free(rem); +} + +void +e_remember_del(E_Remember *rem) +{ + if (rem->used_count > 0) + { + rem->delete_me = 1; + return; + } + _e_remember_free(rem); +} + +E_Remember * +e_remember_find(E_Border *bd) +{ + Evas_List *l; + + for (l = e_config->remembers; l; l = l->next) + { + E_Remember *rem; + int required_matches; + int matches; + char *title = ""; + + rem = l->data; + 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 (bd->client.netwm.name) title = bd->client.netwm.name; + else title = bd->client.icccm.title; + + if ((rem->match & E_REMEMBER_MATCH_NAME) && + (bd->client.icccm.name) && (rem->name) && + (!strcmp(rem->name, bd->client.icccm.name))) + matches++; + if ((rem->match & E_REMEMBER_MATCH_CLASS) && + (bd->client.icccm.class) && (rem->class) && + (!strcmp(rem->class, bd->client.icccm.class))) + matches++; + if ((rem->match & E_REMEMBER_MATCH_TITLE) && + (title) && (rem->title) && (!strcmp(rem->title, title))) + matches++; + if ((rem->match & E_REMEMBER_MATCH_ROLE) && + (bd->client.icccm.window_role) && (rem->role) && + (!strcmp(rem->role, bd->client.icccm.window_role))) + matches++; + if (matches >= required_matches) + return rem; + } + return NULL; +} + +void +e_remember_update(E_Remember *rem, E_Border *bd) +{ + IF_FREE(rem->name); + IF_FREE(rem->class); + /* only match title the first time - never change it later */ + /* IF_FREE(rem->title); */ + IF_FREE(rem->role); + IF_FREE(rem->prop.border); + IF_FREE(rem->prop.command); + + if (bd->client.icccm.name) + rem->name = strdup(bd->client.icccm.name); + if (bd->client.icccm.class) + rem->class = strdup(bd->client.icccm.class); + /* only match title the first time - never change it later */ + /* + if (bd->client.netwm.name) + rem->title = strdup(bd->client.netwm.name); + else if (bd->client.icccm.title) + rem->title = strdup(bd->client.icccm.title); + */ + if (bd->client.icccm.window_role) + rem->role = strdup(bd->client.icccm.window_role); + + rem->prop.pos_x = bd->x + bd->client_inset.l - bd->zone->x; + rem->prop.pos_y = bd->y + bd->client_inset.t - 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; + + rem->prop.layer = bd->layer; + + 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_mazimize = bd->lock_client_mazimize; + 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_FREE(rem->prop.border); + if (bd->client.border.name) + rem->prop.border = strdup(bd->client.border.name); + + rem->prop.sticky = bd->sticky; + + rem->prop.shaded = bd->shaded; + + e_desk_xy_get(bd->desk, &rem->prop.desk_x, &rem->prop.desk_y); + + rem->prop.zone = bd->zone->num; + + rem->prop.head = bd->zone->container->manager->num; +/* FIXME: e17 doesn't fetch WM_COMMAND property yet + IF_FREE(rem->prop.command); + */ + + e_config_save_queue(); +} + /* local subsystem functions */ +static void +_e_remember_free(E_Remember *rem) +{ + e_config->remembers = evas_list_remove(e_config->remembers, rem); + IF_FREE(rem->name); + IF_FREE(rem->class); + IF_FREE(rem->title); + IF_FREE(rem->role); + IF_FREE(rem->prop.border); + IF_FREE(rem->prop.command); + free(rem); +} diff --git a/src/bin/e_remember.h b/src/bin/e_remember.h index 160afb175..14398be92 100644 --- a/src/bin/e_remember.h +++ b/src/bin/e_remember.h @@ -4,6 +4,7 @@ #ifdef E_TYPEDEFS typedef struct _E_Remember E_Remember; + #define E_REMEMBER_MATCH_NAME (1 << 0) #define E_REMEMBER_MATCH_CLASS (1 << 1) #define E_REMEMBER_MATCH_TITLE (1 << 2) @@ -26,6 +27,7 @@ typedef struct _E_Remember E_Remember; struct _E_Remember { + unsigned char delete_me; int match; unsigned char apply_first_only; int used_count; @@ -70,14 +72,24 @@ struct _E_Remember unsigned char shaded; + int desk_x, desk_y; + int zone; + int head; char *command; } prop; }; EAPI int e_remember_init(void); EAPI int e_remember_shutdown(void); - +EAPI E_Remember *e_remember_new(void); +EAPI int e_remember_usable_get(E_Remember *rem); +EAPI void e_remember_use(E_Remember *rem); +EAPI void e_remember_unuse(E_Remember *rem); +EAPI void e_remember_del(E_Remember *rem); +EAPI E_Remember *e_remember_find(E_Border *bd); +EAPI void e_remember_update(E_Remember *rem, E_Border *bd); + #endif #endif diff --git a/src/bin/e_utils.c b/src/bin/e_utils.c index d2ca538f1..8fc82b0b8 100644 --- a/src/bin/e_utils.c +++ b/src/bin/e_utils.c @@ -159,3 +159,59 @@ e_util_container_zone_number_get(int con_num, int zone_num) if (!con) return NULL; return e_container_zone_number_get(con, zone_num); } + +int +e_util_head_exec(int head, char *cmd) +{ + char *penv_display; + char *p1, *p2; + char buf[4096], buf2[32]; + int ok = 0; + Ecore_Exe *exe; + + penv_display = getenv("DISPLAY"); + if (penv_display) penv_display = strdup(penv_display); + /* set env vars */ + p1 = strrchr(penv_display, ':'); + p2 = strrchr(penv_display, '.'); + if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */ + { + /* yes it could overflow... but who will voerflow DISPLAY eh? why? to + * "exploit" your own applications running as you? + */ + strcpy(buf, penv_display); + buf[p2 - penv_display + 1] = 0; + snprintf(buf2, sizeof(buf2), "%i", head); + strcat(buf, buf2); + } + else if (p1) /* "blah:x */ + { + strcpy(buf, penv_display); + snprintf(buf2, sizeof(buf2), ".%i", head); + strcat(buf, buf2); + } + else + strcpy(buf, penv_display); + + ok = 1; + exe = ecore_exe_run(cmd, NULL); + if (!exe) + { + e_error_dialog_show(_("Run Error"), + _("Enlightenment was unable fork a child process\n" + "to run the execute line:\n" + "\n" + "%s\n" + "\n"), + cmd); + ok = 0; + } + + /* reset env vars */ + if (penv_display) + { + e_util_env_set("DISPLAY", penv_display); + free(penv_display); + } + return ok; +} diff --git a/src/bin/e_utils.h b/src/bin/e_utils.h index 13c4778fc..557f51639 100644 --- a/src/bin/e_utils.h +++ b/src/bin/e_utils.h @@ -16,6 +16,7 @@ EAPI int e_util_app_installed(char *app); EAPI int e_util_glob_match(char *str, char *glob); EAPI E_Container *e_util_container_number_get(int num); EAPI E_Zone *e_util_container_zone_number_get(int con_num, int zone_num); - +EAPI int e_util_head_exec(int head, char *cmd); + #endif #endif diff --git a/src/bin/e_zone.c b/src/bin/e_zone.c index e18a96f72..43c4d4d9a 100644 --- a/src/bin/e_zone.c +++ b/src/bin/e_zone.c @@ -485,7 +485,7 @@ e_zone_app_exec(E_Zone *zone, E_App *a) launch_id++; if (launch_id == 0) launch_id = 1; /* execute */ - if (!e_app_exec(a)) return 0; + if (!e_app_exec(a)) launch_id = 0; /* reset env vars */ if (penv_display)