e_client_border_set(ec, bordername);
}
- const Eina_List *cl;
- E_Comp *c;
+static Eina_Bool
+_e_client_type_match(E_Client *ec, E_Config_Client_Type *m)
+{
+ if (!ec || !m) return EINA_FALSE;
+ if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+
+ if ((int)ec->netwm.type != m->window_type)
+ return EINA_FALSE;
+
+ if (((m->clas) && (!ec->icccm.class)) ||
+ ((ec->icccm.class) && (m->clas) && (!e_util_glob_match(ec->icccm.class, m->clas))))
+ return EINA_FALSE;
+
+ if (((m->name) && (!ec->icccm.name)) ||
+ ((ec->icccm.name) && (m->name) && (!e_util_glob_match(ec->icccm.name, m->name))))
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static int
+_e_client_type_get(E_Client *ec)
+{
+ E_Config_Client_Type *m;
+ Eina_List *l;
+ int type = 0;
+
+ if (!e_config->client_types) return 0;
+
+ EINA_LIST_FOREACH(e_config->client_types, l, m)
+ {
+ if (!_e_client_type_match(ec, m)) continue;
+ else
+ {
+ type = m->client_type;
+ break;
+ }
+ }
+
+ ec->client_type = type;
+
+ return ec->client_type;
+}
+
+static void
+_e_client_visibility_zone_calculate(E_Zone *zone)
+{
+ E_Client *ec;
+ Evas_Object *o;
+ Eina_Tiler *t;
+ Eina_Rectangle r, *_r;
+ Eina_Iterator *itr;
+ Eina_Bool is_intersected = EINA_FALSE;
+ const int edge = 1;
+
+ if (!zone) return;
+
+ t = eina_tiler_new(zone->w + edge, zone->h + edge);
+ eina_tiler_tile_size_set(t, 1, 1);
+
+ EINA_RECTANGLE_SET(&r, zone->x, zone->y, zone->w, zone->h);
+ eina_tiler_rect_add(t, &r);
+
+ for (o = evas_object_top_get(zone->comp->evas); o; o = evas_object_below_get(o))
+ {
+ ec = evas_object_data_get(o, "E_Client");
+
+ /* check e_client and skip e_clients not intersects with zone */
+ if (!ec) continue;
+ if (e_client_util_ignored_get(ec)) continue;
+ if (ec->zone != zone) continue;
+ if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
+ zone->x, zone->y, zone->w, zone->h))
+ continue;
+
+ /* check if internal animation is running */
+ if (e_comp_object_is_animating(ec->frame)) continue;
+
+ /* check if external animation is running */
+ if (evas_object_data_get(ec->frame, "effect_running")) continue;
+
+ /* check intersects */
+ if (eina_tiler_empty(t)) is_intersected = EINA_FALSE;
+
+ itr = eina_tiler_iterator_new(t);
+ EINA_ITERATOR_FOREACH(itr, _r)
+ {
+ if (E_INTERSECTS(ec->x, ec->y, ec->w, ec->h,
+ _r->x, _r->y, _r->w, _r->h))
+ {
+ is_intersected = EINA_TRUE;
+ break;
+ }
+ }
+ eina_iterator_free(itr);
+
+ /* check some visible state */
+ if ((!ec->visible) || (ec->iconic) ||
+ (!evas_object_visible_get(ec->frame)) ||
+ (e_object_is_del(E_OBJECT(ec))))
+ is_intersected = EINA_FALSE;
+
+#ifndef HAVE_WAYLAND_ONLY
+ /* check if it entered to hide process
+ * TODO: support wayland
+ */
+ if (ec->icccm.state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+ is_intersected = EINA_FALSE;
+#endif
+ if (is_intersected)
+ {
+ Eina_Bool opaque = EINA_FALSE;
+ /* unobscured case */
+ if (ec->visibility.obscured == 0)
+ {
+ /* previous state is unobscured */
+ /* do nothing */
+ }
+ else
+ {
+ /* previous state is obscured */
+ ec->visibility.obscured = 0;
+ _e_client_event_simple(ec, E_EVENT_CLIENT_VISIBILITY_CHANGE);
+ }
+
+ /* check alpha window is opaque or not. */
+ if ((ec->visibility.opaque > 0) && (ec->argb)) opaque = EINA_TRUE;
+
+ /* if e_client is not alpha or opaque then delete intersect rect */
+ if ((!ec->argb) || (opaque))
+ {
+ EINA_RECTANGLE_SET(&r,
+ ec->x, ec->y,
+ ec->w + edge, ec->h + edge);
+ eina_tiler_rect_del(t, &r);
+ }
+ }
+ else
+ {
+ /* obscured case */
+ if (ec->visibility.obscured != 1)
+ {
+ /* previous state is unobscured */
+ ec->visibility.obscured = 1;
+ _e_client_event_simple(ec, E_EVENT_CLIENT_VISIBILITY_CHANGE);
+ }
+ else
+ {
+ /* previous state is obscured */
+ /* do nothing */
+ }
+ }
+ }
+
+ eina_tiler_free(t);
+}
+
+EAPI void
+e_client_visibility_calculate(E_Client *ec)
+{
- EINA_LIST_FOREACH(e_comp_list(), cl, c)
++ E_Zone *zone;
++ Eina_List *zl;
+
+ if (e_object_is_del(E_OBJECT(ec))) return;
+
- E_Zone *zone;
- Eina_List *zl;
-
- EINA_LIST_FOREACH(c->zones, zl, zone)
- {
- _e_client_visibility_zone_calculate(zone);
- }
++ EINA_LIST_FOREACH(e_comp->zones, zl, zone)
+ {
++ _e_client_visibility_zone_calculate(zone);
+ }
+}
+
////////////////////////////////////////////////
EINTERN void
e_client_idler_before(void)
if (!eina_hash_population(clients_hash)) return;
- EINA_LIST_FOREACH(e_comp_list(), l, c)
+
+
+ EINA_LIST_FOREACH(e_comp->clients, l, ec)
{
- Eina_List *ll;
- E_Client *ec;
+ Eina_Stringshare *title;
++ int client_type;
++
+ // pass 1 - eval0. fetch properties on new or on change and
+ // call hooks to decide what to do - maybe move/resize
+ if (!ec->changed) continue;
- EINA_LIST_FOREACH(c->clients, ll, ec)
+ if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FETCH, ec)) continue;
+ /* FETCH is hooked by the compositor to get client hints */
+ title = e_client_util_name_get(ec);
+ if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_FETCH, ec)) continue;
+ if (title != e_client_util_name_get(ec))
+ _e_client_event_property(ec, E_CLIENT_PROPERTY_TITLE);
++
++ client_type = ec->client_type;
++ if (client_type != _e_client_type_get(ec))
++ _e_client_event_property(ec, E_CLIENT_PROPERTY_CLIENT_TYPE);
++
++ /* calculate visibility of the client" */
++ e_client_visibility_calculate(ec);
++
+ /* PRE_POST_FETCH calls e_remember apply for new client */
+ if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, ec)) continue;
+ if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FETCH, ec)) continue;
+ if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, ec)) continue;
+
+ if ((ec->border.changed) && (!ec->shaded) && ((!ec->override) || ec->internal) &&
+ (!(((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
+ _e_client_frame_update(ec);
+ ec->border.changed = 0;
+ _e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN, ec);
+ }
+
+ E_CLIENT_FOREACH(e_comp, ec)
+ {
+ // pass 2 - show windows needing show
+ if ((ec->changes.visible) && (ec->visible) &&
+ (!ec->new_client) && (!ec->changes.pos) &&
+ (!ec->changes.size))
{
- Eina_Stringshare *title;
- int client_type;
- // pass 1 - eval0. fetch properties on new or on change and
- // call hooks to decide what to do - maybe move/resize
- if (!ec->changed) continue;
-
- if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FETCH, ec)) continue;
- /* FETCH is hooked by the compositor to get client hints */
- title = e_client_util_name_get(ec);
- if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_FETCH, ec)) continue;
- if (title != e_client_util_name_get(ec))
- _e_client_event_property(ec, E_CLIENT_PROPERTY_TITLE);
- client_type = ec->client_type;
- if (client_type != _e_client_type_get(ec))
- _e_client_event_property(ec, E_CLIENT_PROPERTY_CLIENT_TYPE);
- /* calculate visibility of the client" */
- e_client_visibility_calculate(ec);
- /* PRE_POST_FETCH calls e_remember apply for new client */
- if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, ec)) continue;
- if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FETCH, ec)) continue;
- if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, ec)) continue;
-
- if ((ec->border.changed) && (!ec->shaded) && (!ec->override) &&
- (!(((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
- _e_client_frame_update(ec);
- ec->border.changed = 0;
- _e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN, ec);
+ evas_object_show(ec->frame);
+ ec->changes.visible = !evas_object_visible_get(ec->frame);
}
- E_CLIENT_FOREACH(c, ec)
+ if ((!ec->new_client) && (!e_client_util_ignored_get(ec)) &&
+ (!E_INSIDE(ec->x, ec->y, 0, 0, ec->comp->man->w - 5, ec->comp->man->h - 5)) &&
+ (!E_INSIDE(ec->x, ec->y, 0 - ec->w + 5, 0 - ec->h + 5, ec->comp->man->w - 5, ec->comp->man->h - 5))
+ )
{
- // pass 2 - show windows needing show
- if ((ec->changes.visible) && (ec->visible) &&
- (!ec->new_client) && (!ec->changes.pos) &&
- (!ec->changes.size))
- {
- evas_object_show(ec->frame);
- ec->changes.visible = !evas_object_visible_get(ec->frame);
- }
-
- if ((!ec->new_client) && (!e_client_util_ignored_get(ec)) &&
- (!E_INSIDE(ec->x, ec->y, 0, 0, ec->comp->man->w - 5, ec->comp->man->h - 5)) &&
- (!E_INSIDE(ec->x, ec->y, 0 - ec->w + 5, 0 - ec->h + 5, ec->comp->man->w - 5, ec->comp->man->h - 5))
- )
- {
- if (e_config->screen_limits != E_SCREEN_LIMITS_COMPLETELY)
- _e_client_move_lost_window_to_center(ec);
- }
+ if (e_config->screen_limits != E_CLIENT_OFFSCREEN_LIMIT_ALLOW_FULL)
+ _e_client_move_lost_window_to_center(ec);
}
+ }
- if (_e_client_layout_cb)
- _e_client_layout_cb(c);
+ if (_e_client_layout_cb)
+ _e_client_layout_cb(e_comp);
- // pass 3 - hide windows needing hide and eval (main eval)
- E_CLIENT_FOREACH(c, ec)
- {
- if (e_object_is_del(E_OBJECT(ec))) continue;
+ // pass 3 - hide windows needing hide and eval (main eval)
+ E_CLIENT_FOREACH(e_comp, ec)
+ {
+ if (e_object_is_del(E_OBJECT(ec))) continue;
- if ((ec->changes.visible) && (!ec->visible))
- {
- evas_object_hide(ec->frame);
- ec->changes.visible = 0;
- }
+ if ((ec->changes.visible) && (!ec->visible))
+ {
+ evas_object_hide(ec->frame);
+ ec->changes.visible = 0;
+ }
- if (ec->changed)
- _e_client_eval(ec);
+ if (ec->changed)
+ _e_client_eval(ec);
- if ((ec->changes.visible) && (ec->visible) && (!ec->changed))
- {
- evas_object_show(ec->frame);
- ec->changes.visible = !evas_object_visible_get(ec->frame);
- ec->changed = ec->changes.visible;
- }
+ if ((ec->changes.visible) && (ec->visible) && (!ec->changed))
+ {
+ evas_object_show(ec->frame);
+ ec->changes.visible = !evas_object_visible_get(ec->frame);
+ ec->changed = ec->changes.visible;
}
}
}
ec->netwm.action.close = 0;
ec->netwm.opacity = 255;
+ ec->visibility.obscured = -1;
+ ec->visibility.opaque = -1;
+
EC_CHANGED(ec);
- c->clients = eina_list_append(c->clients, ec);
+ e_comp->clients = eina_list_append(e_comp->clients, ec);
eina_hash_add(clients_hash, &ec->pixmap, ec);
_e_client_event_simple(ec, E_EVENT_CLIENT_ADD);
focus_stack = eina_list_append(focus_stack, ec);
}
+ e_hints_client_list_set();
++
+#ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
+ _e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT_POST, ec);
+#endif
+
return ec;
}