feature: selective redirection toggling

this toggles redirection on compatible (X) clients while still mostly preserving window frame functionality
This commit is contained in:
Mike Blumenkrantz 2014-01-13 16:30:37 -05:00
parent 70d65978c7
commit 390b8a5bf5
6 changed files with 66 additions and 4 deletions

View File

@ -671,6 +671,7 @@ struct E_Client
Eina_Bool dialog : 1;
Eina_Bool tooltip : 1;
Eina_Bool redirected : 1;
Eina_Bool unredirected_single : 1; //window has been selectively unredirected
Eina_Bool shape_changed : 1;
Eina_Bool layer_block : 1; // client is doing crazy stuff and should not be relayered in protocol
Eina_Bool ignored : 1; // client is comp-ignored

View File

@ -1020,6 +1020,12 @@ _e_comp_act_opacity_set_go(E_Object * obj __UNUSED__, const char *params)
evas_object_color_set(o, opacity, opacity, opacity, opacity);
}
static void
_e_comp_act_redirect_toggle_go(E_Object * obj EINA_UNUSED, const char *params EINA_UNUSED)
{
e_comp_client_redirect_toggle(e_client_focused_get());
}
//////////////////////////////////////////////////////////////////////////
EINTERN Eina_Bool
@ -1088,6 +1094,11 @@ e_comp_init(void)
e_action_predef_name_set(N_("Compositor"),
N_("Set current window opacity"), "opacity_set",
"255", "syntax: number between 0-255 to set for transparent-opaque", 1);
act = e_action_add("redirect_toggle");
act->func.go = _e_comp_act_redirect_toggle_go;
e_action_predef_name_set(N_("Compositor"),
N_("Toggle focused client's redirect state"), "redirect_toggle",
NULL, NULL, 0);
actions = eina_list_append(actions, act);
}
@ -1753,3 +1764,15 @@ e_comp_button_bindings_grab_all(void)
if (c->bindings_grab_cb)
c->bindings_grab_cb(c);
}
EAPI void
e_comp_client_redirect_toggle(E_Client *ec)
{
EINA_SAFETY_ON_NULL_RETURN(ec);
if (!conf->enable_advanced_features) return;
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_X) return;
ec->unredirected_single = !ec->unredirected_single;
e_client_redirected_set(ec, !ec->redirected);
ec->no_shape_cut = !ec->redirected;
e_comp_shape_queue(ec->comp);
}

View File

@ -163,6 +163,7 @@ EAPI E_Comp *e_comp_evas_find(const Evas *e);
EAPI void e_comp_button_bindings_grab_all(void);
EAPI void e_comp_button_bindings_ungrab_all(void);
EAPI void e_comp_client_redirect_toggle(E_Client *ec);
EINTERN Evas_Object *e_comp_style_selector_create(Evas *evas, const char **source);
EAPI E_Config_Dialog *e_int_config_comp(E_Comp *comp, const char *params);

View File

@ -595,6 +595,7 @@ _e_comp_x_client_stack(E_Client *ec)
Eina_List *l;
if (ec->override && (!ec->internal)) return; //can't restack these
if (ec->comp_data->unredirected_single) return;
ecore_x_window_shadow_tree_flush();
@ -786,7 +787,7 @@ _e_comp_x_evas_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
{
E_Client *ec = data;
if (ec->comp_data->moving)
if (ec->comp_data->moving && (!ec->comp_data->unredirected_single))
{
if (ec->comp_data->move_counter++ < MOVE_COUNTER_LIMIT) return;
ec->comp_data->move_counter = 0;
@ -855,6 +856,9 @@ _e_comp_x_evas_hide_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp)
evas_object_hide(tmp->frame);
if (ec->unredirected_single)
ecore_x_window_hide(_e_comp_x_client_window_get(ec));
if (e_comp_config_get()->send_flush)
ecore_x_e_comp_flush_send(e_client_util_pwin_get(ec));
if (e_comp_config_get()->send_dump)
@ -874,6 +878,8 @@ _e_comp_x_evas_show_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
ecore_x_window_shadow_tree_flush();
if (!ec->comp_data->need_reparent)
ecore_x_window_show(win);
if (ec->unredirected_single)
ecore_x_window_show(_e_comp_x_client_window_get(ec));
e_hints_window_visible_set(ec);
ecore_x_window_prop_card32_set(win, E_ATOM_MAPPED, &visible, 1);
@ -1222,7 +1228,7 @@ _e_comp_x_hide(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_Windo
}
return ECORE_CALLBACK_PASS_ON;
}
if (!ec->visible)
if ((!ec->visible) || (ec->hidden && ec->unredirected_single))
{
//INF("IGNORED");
return ECORE_CALLBACK_PASS_ON;
@ -4003,12 +4009,18 @@ static void
_e_comp_x_hook_client_redirect(void *d EINA_UNUSED, E_Client *ec)
{
E_COMP_X_PIXMAP_CHECK;
if (ec->comp->nocomp)
if (ec->comp_data->unredirected_single)
{
ecore_x_composite_redirect_window(_e_comp_x_client_window_get(ec), ECORE_X_COMPOSITE_UPDATE_MANUAL);
ec->comp_data->unredirected_single = 0;
}
else if (ec->comp->nocomp)
{
/* first window */
ec->comp->nocomp = 0;
ecore_x_composite_redirect_subwindows(ec->comp->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
ecore_x_window_show(ec->comp->win);
ecore_x_window_reparent(_e_comp_x_client_window_get(ec), ec->comp->man->root, ec->client.x, ec->client.y);
_e_comp_x_client_stack(ec);
}
if (!ec->comp_data->damage)
_e_comp_x_client_damage_add(ec);
@ -4027,6 +4039,13 @@ _e_comp_x_hook_client_unredirect(void *d EINA_UNUSED, E_Client *ec)
ecore_x_damage_free(ec->comp_data->damage);
ec->comp_data->damage = 0;
if (ec->unredirected_single && (!ec->comp_data->unredirected_single))
{
ecore_x_composite_unredirect_window(_e_comp_x_client_window_get(ec), ECORE_X_COMPOSITE_UPDATE_MANUAL);
ecore_x_window_reparent(_e_comp_x_client_window_get(ec), ec->comp->win, ec->client.x, ec->client.y);
ecore_x_window_raise(_e_comp_x_client_window_get(ec));
ec->comp_data->unredirected_single = 1;
}
if (!ec->comp->nocomp) return; //wait for it...
ecore_x_composite_unredirect_subwindows(ec->comp->man->root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
ecore_x_window_hide(ec->comp->win);

View File

@ -100,6 +100,7 @@ struct _E_Comp_Client_Data
Eina_Bool set_win_type : 1;
Eina_Bool frame_update : 1;
Eina_Bool evas_init : 1;
Eina_Bool unredirected_single : 1;
};
EINTERN Eina_Bool e_comp_x_init(void);

View File

@ -5,6 +5,7 @@ static void _e_client_menu_cb_locks(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_remember(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_borderless(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_border(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_redirect_set(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi EINA_UNUSED);
static void _e_client_menu_cb_close(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_iconify(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_client_menu_cb_kill(void *data, E_Menu *m, E_Menu_Item *mi);
@ -200,6 +201,15 @@ e_int_client_menu_create(E_Client *ec)
"e/widgets/border/default/borderless");
}
if (e_comp_config_get()->enable_advanced_features && (e_pixmap_type_get(ec->pixmap) == E_PIXMAP_TYPE_X))
{
mi = e_menu_item_new(m);
e_menu_item_check_set(mi, 1);
e_menu_item_label_set(mi, _("Unredirected"));
e_menu_item_toggle_set(mi, !ec->redirected);
e_menu_item_callback_set(mi, _e_client_menu_cb_redirect_set, ec);
}
if (!ec->lock_close)
{
mi = e_menu_item_new(m);
@ -317,6 +327,13 @@ _e_client_menu_cb_borderless(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi)
ec->borderless = mi->toggle;
}
static void
_e_client_menu_cb_redirect_set(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi EINA_UNUSED)
{
e_comp_client_redirect_toggle(data);
}
static void
_e_client_menu_cb_close(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
{