feature: selective redirection toggling
authorMike Blumenkrantz <zmike@samsung.com>
Mon, 13 Jan 2014 21:30:37 +0000 (16:30 -0500)
committerMike Blumenkrantz <zmike@samsung.com>
Wed, 15 Jan 2014 01:29:00 +0000 (20:29 -0500)
this toggles redirection on compatible (X) clients while still mostly preserving window frame functionality

src/bin/e_client.h
src/bin/e_comp.c
src/bin/e_comp.h
src/bin/e_comp_x.c
src/bin/e_comp_x.h
src/bin/e_int_client_menu.c

index ea43b18..4308c99 100644 (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
index a497689..4f744a3 100644 (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);
+}
index 0032d54..dd86913 100644 (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);
index c291305..80b4eaa 100644 (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);
index 13d828c..2b71729 100644 (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);
index f1b04a6..31d94ec 100644 (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__)
 {