From c86091fcaffbe702d300d46b76a7a1f287edf6fb Mon Sep 17 00:00:00 2001 From: sebastid Date: Tue, 15 Feb 2005 12:11:31 +0000 Subject: [PATCH] - Add atom E_ATOM_SHADE_DIRECTION, remove E_ATOM_ICONIC - Add function for reordering border lists. - Update hints, and use them. - Add a flag to e_border_hide to tell if the window still is managed or not. - Don't set changed flag if changing visibility. Visibility is handled outside _e_border_eval() - Cleanup focus_out. - Add desk show event. SVN revision: 13372 --- src/bin/e_atoms.c | 4 +- src/bin/e_atoms.h | 2 +- src/bin/e_border.c | 236 ++++++++++++++++++++++++++++-------------- src/bin/e_border.h | 2 +- src/bin/e_container.c | 4 +- src/bin/e_desk.c | 31 ++++-- src/bin/e_desk.h | 8 ++ src/bin/e_hints.c | 152 ++++++++++++++++++--------- src/bin/e_hints.h | 14 ++- 9 files changed, 308 insertions(+), 145 deletions(-) diff --git a/src/bin/e_atoms.c b/src/bin/e_atoms.c index 34f94bf0a..cddfb0101 100644 --- a/src/bin/e_atoms.c +++ b/src/bin/e_atoms.c @@ -8,8 +8,8 @@ Ecore_X_Atom E_ATOM_MANAGED = 0; Ecore_X_Atom E_ATOM_CONTAINER = 0; Ecore_X_Atom E_ATOM_ZONE = 0; Ecore_X_Atom E_ATOM_DESK = 0; -Ecore_X_Atom E_ATOM_ICONIC = 0; Ecore_X_Atom E_ATOM_MAPPED = 0; +Ecore_X_Atom E_ATOM_SHADE_DIRECTION = 0; /* externally accessible functions */ int @@ -19,8 +19,8 @@ e_atoms_init(void) E_ATOM_CONTAINER = ecore_x_atom_get("__E_WINDOW_CONTAINER"); E_ATOM_ZONE = ecore_x_atom_get("__E_WINDOW_ZONE"); E_ATOM_DESK = ecore_x_atom_get("__E_WINDOW_DESK"); - E_ATOM_ICONIC = ecore_x_atom_get("__E_WINDOW_ICONIC"); E_ATOM_MAPPED = ecore_x_atom_get("__E_WINDOW_MAPPED"); + E_ATOM_SHADE_DIRECTION = ecore_x_atom_get("__E_WINDOW_SHADE_DIRECTION"); return 1; } diff --git a/src/bin/e_atoms.h b/src/bin/e_atoms.h index b655bf45c..87b2bb10c 100644 --- a/src/bin/e_atoms.h +++ b/src/bin/e_atoms.h @@ -13,8 +13,8 @@ extern EAPI Ecore_X_Atom E_ATOM_MANAGED; extern EAPI Ecore_X_Atom E_ATOM_CONTAINER; extern EAPI Ecore_X_Atom E_ATOM_ZONE; extern EAPI Ecore_X_Atom E_ATOM_DESK; -extern EAPI Ecore_X_Atom E_ATOM_ICONIC; extern EAPI Ecore_X_Atom E_ATOM_MAPPED; +extern EAPI Ecore_X_Atom E_ATOM_SHADE_DIRECTION; EAPI int e_atoms_init(void); EAPI int e_atoms_shutdown(void); diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 3802acbb7..49b4d1970 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -88,6 +88,9 @@ static void _e_border_resize_begin(E_Border *bd); static void _e_border_resize_end(E_Border *bd); static void _e_border_resize_update(E_Border *bd); +static void _e_border_reorder_after(E_Border *bd, E_Border *after); +static void _e_border_reorder_before(E_Border *bd, E_Border *before); + /* local subsystem globals */ static Evas_List *handlers = NULL; static Evas_List *borders = NULL; @@ -97,8 +100,6 @@ static E_Border *resize = NULL; static Ecore_Evas *resize_ee = NULL; static Evas_Object *resize_obj = NULL; -extern int _e_desk_current_changing; - int E_EVENT_BORDER_ADD = 0; int E_EVENT_BORDER_REMOVE = 0; int E_EVENT_BORDER_ZONE_SET = 0; @@ -322,6 +323,8 @@ e_border_zone_set(E_Border *bd, E_Zone *zone) E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if (bd->zone == zone) return; + bd->zone->clients = evas_list_remove(bd->zone->clients, bd); + zone->clients = evas_list_append(zone->clients, bd); bd->zone = zone; if (bd->desk->zone != bd->zone) @@ -367,8 +370,6 @@ e_border_desk_set(E_Border *bd, E_Desk *desk) ev = calloc(1, sizeof(E_Event_Border_Desk_Set)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ev->desk = desk; e_object_ref(E_OBJECT(desk)); @@ -391,9 +392,8 @@ e_border_show(E_Border *bd) if (bd->visible) return; e_container_shape_show(bd->shape); ecore_x_window_show(bd->client.win); - ecore_x_icccm_state_set(bd->client.win, ECORE_X_WINDOW_STATE_HINT_NORMAL); + e_hints_window_visible_set(bd->client.win); bd->visible = 1; - bd->changed = 1; bd->changes.visible = 1; visible = 1; @@ -402,14 +402,12 @@ e_border_show(E_Border *bd) ev = calloc(1, sizeof(E_Event_Border_Show)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL); } void -e_border_hide(E_Border *bd) +e_border_hide(E_Border *bd, int manage) { E_Event_Border_Hide *ev; unsigned int visible; @@ -420,25 +418,19 @@ e_border_hide(E_Border *bd) ecore_x_window_hide(bd->client.win); e_container_shape_hide(bd->shape); - - if (bd->iconic) - ecore_x_icccm_state_set(bd->client.win, ECORE_X_WINDOW_STATE_HINT_ICONIC); - else - ecore_x_icccm_state_set(bd->client.win, ECORE_X_WINDOW_STATE_HINT_WITHDRAWN); + if (!bd->iconic) + e_hints_window_hidden_set(bd->client.win); bd->visible = 0; - bd->changed = 1; bd->changes.visible = 1; visible = 0; ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1); - if (!_e_desk_current_changing) + if (!manage) ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1); ev = calloc(1, sizeof(E_Event_Border_Hide)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL); } @@ -474,8 +466,6 @@ e_border_move(E_Border *bd, int x, int y) _e_border_zone_update(bd); ev = calloc(1, sizeof(E_Event_Border_Move)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL); } @@ -512,8 +502,6 @@ e_border_resize(E_Border *bd, int w, int h) _e_border_zone_update(bd); ev = calloc(1, sizeof(E_Event_Border_Resize)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL); } @@ -559,20 +547,15 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h) _e_border_zone_update(bd); mev = calloc(1, sizeof(E_Event_Border_Move)); mev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL); rev = calloc(1, sizeof(E_Event_Border_Resize)); rev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL); } -/* FIXME: Zone client list is not altered. This affects desktop show function */ void e_border_raise(E_Border *bd) { @@ -580,8 +563,7 @@ e_border_raise(E_Border *bd) E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - bd->container->clients = evas_list_remove(bd->container->clients, bd); - bd->container->clients = evas_list_append(bd->container->clients, bd); + _e_border_reorder_after(bd, NULL); mwin = e_menu_grab_window_get(); if (!mwin) ecore_x_window_raise(bd->win); @@ -598,8 +580,7 @@ e_border_lower(E_Border *bd) { E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - bd->container->clients = evas_list_remove(bd->container->clients, bd); - bd->container->clients = evas_list_prepend(bd->container->clients, bd); + _e_border_reorder_before(bd, NULL); ecore_x_window_lower(bd->win); } @@ -608,8 +589,7 @@ e_border_stack_above(E_Border *bd, E_Border *above) { E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - bd->container->clients = evas_list_remove(bd->container->clients, bd); - bd->container->clients = evas_list_append_relative(bd->container->clients, bd, above); + _e_border_reorder_after(bd, above); ecore_x_window_configure(bd->win, ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE, @@ -622,8 +602,7 @@ e_border_stack_below(E_Border *bd, E_Border *below) { E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - bd->container->clients = evas_list_remove(bd->container->clients, bd); - bd->container->clients = evas_list_prepend_relative(bd->container->clients, bd, below); + _e_border_reorder_before(bd, below); ecore_x_window_configure(bd->win, ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE, @@ -694,6 +673,7 @@ e_border_shade(E_Border *bd, E_Direction dir) bd->shade.dir = dir; e_hints_window_shaded_set(bd->client.win, 1); + e_hints_window_shade_direction_set(bd->client.win, dir); if (e_config->border_shade_animate) { @@ -741,8 +721,6 @@ e_border_shade(E_Border *bd, E_Direction dir) edje_object_signal_emit(bd->bg_object, "shaded", ""); ev = calloc(1, sizeof(E_Event_Border_Resize)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ /* The resize is added in the animator when animation complete */ /* For non-animated, we add it immediately with the new size */ e_object_ref(E_OBJECT(bd)); @@ -767,6 +745,7 @@ e_border_unshade(E_Border *bd, E_Direction dir) bd->shade.dir = dir; e_hints_window_shaded_set(bd->client.win, 0); + e_hints_window_shade_direction_set(bd->client.win, dir); if (bd->shade.dir == E_DIRECTION_UP || bd->shade.dir == E_DIRECTION_LEFT) @@ -824,8 +803,6 @@ e_border_unshade(E_Border *bd, E_Direction dir) edje_object_signal_emit(bd->bg_object, "unshaded", ""); ev = calloc(1, sizeof(E_Event_Border_Resize)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ /* The resize is added in the animator when animation complete */ /* For non-animated, we add it immediately with the new size */ e_object_ref(E_OBJECT(bd)); @@ -896,11 +873,11 @@ e_border_iconify(E_Border *bd) if (!bd->iconic) { bd->iconic = 1; - e_border_hide(bd); + e_border_hide(bd, 1); edje_object_signal_emit(bd->bg_object, "iconify", ""); } iconic = 1; - ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ICONIC, &iconic, 1); + e_hints_window_iconic_set(bd->client.win); ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1); } @@ -920,11 +897,12 @@ e_border_uniconify(E_Border *bd) e_border_desk_set(bd, desk); bd->iconic = 0; e_border_show(bd); + /* FIXME: DEPRECATED? e_iconify_border_remove(bd); + */ edje_object_signal_emit(bd->bg_object, "uniconify", ""); } iconic = 0; - ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ICONIC, &iconic, 1); ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1); } @@ -987,11 +965,35 @@ e_border_idler_before(void) { Evas_List *l; + if (!borders) + return; + + /* We need to loop two times through the borders. + * 1. show windows + * 2. hide windows and evaluate rest + */ + for (l = borders->last; l; l = l->prev) + { + E_Border *bd; + + bd = l->data; + if (bd->changes.visible && bd->visible) + { + ecore_x_window_show(bd->win); + bd->changes.visible = 0; + } + } + for (l = borders; l; l = l->next) { E_Border *bd; bd = l->data; + if (bd->changes.visible && !bd->visible) + { + ecore_x_window_hide(bd->win); + bd->changes.visible = 0; + } if (bd->changed) _e_border_eval(bd); } } @@ -1066,8 +1068,8 @@ _e_border_del(E_Border *bd) ev = calloc(1, sizeof(E_Event_Border_Remove)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ + /* FIXME Don't ref this during shutdown. And the event is pointless + * during shutdown.. */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL); } @@ -1092,7 +1094,7 @@ static int _e_border_cb_window_destroy(void *data, int ev_type, void *ev) e = ev; bd = e_border_find_by_client_window(e->win); if (!bd) return 1; - e_border_hide(bd); + e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); return 1; } @@ -1117,8 +1119,15 @@ _e_border_cb_window_hide(void *data, int ev_type, void *ev) /* Don't delete hidden or iconified windows */ was_iconic = bd->iconic; was_visible = bd->visible; - e_border_hide(bd); - if (!(was_iconic) && (was_visible)) e_object_del(E_OBJECT(bd)); + if (!(was_iconic) && (was_visible)) + { + e_border_hide(bd, 0); + e_object_del(E_OBJECT(bd)); + } + else + { + e_border_hide(bd, 1); + } return 1; } @@ -1133,7 +1142,7 @@ _e_border_cb_window_reparent(void *data, int ev_type, void *ev) bd = e_border_find_by_client_window(e->win); if (!bd) return 1; if (e->parent == bd->client.shell_win) return 1; - e_border_hide(bd); + e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); return 1; } @@ -1450,18 +1459,31 @@ _e_border_cb_window_focus_out(void *data, int ev_type, void *ev) e = ev; bd = e_border_find_by_client_window(e->win); if (!bd) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_NORMAL) && - (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_GRAB) && - (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_GRAB) && - (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_GRAB) && - (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_UNGRAB) && - (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)) return 1; - if ((e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED) && - (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)) return 1; + if (e->mode == ECORE_X_EVENT_MODE_NORMAL) + { + if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1; + } + else if (e->mode == ECORE_X_EVENT_MODE_GRAB) + { + if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return 1; + else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1; + else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL) return 1; + } + else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) + { + /* 1. enter moz window + * 2. activate menu + * 3. leave moz window + * 4. click + if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1; + */ + } + else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED) + { + /* FIXME: If window is grabbed, shouldn't we always return 1? */ + if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return 1; + else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1; + } // printf("f OUT %i | %i\n", e->mode, e->detail); e_border_focus_set(bd, 0, 0); return 1; @@ -1651,7 +1673,7 @@ _e_border_cb_signal_action(void *data, Evas_Object *obj, const char *emission, c ecore_x_kill(bd->client.win); ecore_x_sync(); // ecore_x_window_del(bd->client.win); - e_border_hide(bd); + e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); } } @@ -1709,13 +1731,13 @@ _e_border_cb_mouse_in(void *data, int type, void *event) char *ct; const char *modes[] = { - "MODE_NORMAL", + "MODE_NORMAL", "MODE_WHILE_GRABBED", "MODE_GRAB", "MODE_UNGRAB" }; const char *details[] = { - "DETAIL_ANCESTOR", + "DETAIL_ANCESTOR", "DETAIL_VIRTUAL", "DETAIL_INFERIOR", "DETAIL_NON_LINEAR", @@ -1736,7 +1758,6 @@ _e_border_cb_mouse_in(void *data, int type, void *event) #endif // if (ev->mode == ECORE_X_EVENT_MODE_GRAB) return 1; // if (ev->mode == ECORE_X_EVENT_MODE_UNGRAB) return 1; -// if (ev->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED) return 1; if (ev->event_win == bd->win) { /* FIXME: this would normally put focus on the client on pointer */ @@ -1765,13 +1786,13 @@ _e_border_cb_mouse_out(void *data, int type, void *event) char *ct; const char *modes[] = { - "MODE_NORMAL", + "MODE_NORMAL", "MODE_WHILE_GRABBED", "MODE_GRAB", "MODE_UNGRAB" }; const char *details[] = { - "DETAIL_ANCESTOR", + "DETAIL_ANCESTOR", "DETAIL_VIRTUAL", "DETAIL_INFERIOR", "DETAIL_NON_LINEAR", @@ -1792,7 +1813,6 @@ _e_border_cb_mouse_out(void *data, int type, void *event) #endif /* FIXME: this would normally take focus away in pointer focus mode */ // if (ev->mode == ECORE_X_EVENT_MODE_UNGRAB) return 1; -// if (ev->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED) return 1; if (ev->event_win == bd->win) { if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) && @@ -2094,7 +2114,7 @@ _e_border_eval(E_Border *bd) if (bd->client.icccm.fetch.title) { if (bd->client.icccm.title) free(bd->client.icccm.title); - bd->client.icccm.title = ecore_x_icccm_title_get(bd->client.win); + bd->client.icccm.title = e_hints_window_name_get(bd->client.win); bd->client.icccm.fetch.title = 0; if (bd->bg_object) { @@ -2189,6 +2209,11 @@ _e_border_eval(E_Border *bd) { bd->client.icccm.accepts_focus = accepts_focus; bd->client.icccm.urgent = is_urgent; + + /* If this is a new window, set the state as requested. */ + if ((bd->new_client + && (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))) + e_border_iconify(bd); } bd->client.icccm.fetch.hints = 0; } @@ -2511,11 +2536,17 @@ _e_border_eval(E_Border *bd) /* Recreate state */ if (e_hints_window_sticky_isset(bd->client.win)) e_border_stick(bd); - /* FIXME: use right shade direction! */ if (e_hints_window_shaded_isset(bd->client.win)) - e_border_shade(bd, E_DIRECTION_UP); + e_border_shade(bd, e_hints_window_shade_direction_get(bd->client.win)); if (e_hints_window_maximized_isset(bd->client.win)) e_border_maximize(bd); + if (e_hints_window_iconic_isset(bd->client.win)) + e_border_iconify(bd); + /* If a window isn't iconic, and is one the current desk, + * show it! */ + else if (bd->desk == e_desk_current_get(bd->zone)) + e_border_show(bd); + ecore_x_icccm_move_resize_send(bd->client.win, bd->x + bd->client_inset.l, bd->y + bd->client_inset.t, @@ -2525,20 +2556,11 @@ _e_border_eval(E_Border *bd) ev = calloc(1, sizeof(E_Event_Border_Add)); ev->border = bd; - /* SUSPICION: does the unref for this actually sometimes not get */ - /* called? coudl this be the dangling borders issue? */ e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL); } /* effect changes to the window border itself */ - if (bd->changes.visible) - { - if (bd->visible) ecore_x_window_show(bd->win); - else ecore_x_window_hide(bd->win); - bd->changes.visible = 0; - } - if ((bd->changes.shading)) { /* show at start of unshade (but don't hide until end of shade) */ @@ -3062,7 +3084,7 @@ _e_border_menu_cb_close(void *data, E_Menu *m, E_Menu_Item *mi) ecore_x_kill(bd->client.win); ecore_x_sync(); // ecore_x_window_del(bd->client.win); - e_border_hide(bd); + e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); } } @@ -3309,3 +3331,57 @@ _e_border_resize_update(E_Border *bd) (bd->client.h - bd->client.icccm.base_h) / bd->client.icccm.step_h); edje_object_part_text_set(resize_obj, "text", buf); } + +static void +_e_border_reorder_after(E_Border *bd, E_Border *after) +{ + if (after) + { + bd->container->clients = evas_list_remove(bd->container->clients, bd); + bd->container->clients = evas_list_append_relative(bd->container->clients, bd, after); + bd->zone->clients = evas_list_remove(bd->zone->clients, bd); + bd->zone->clients = evas_list_append_relative(bd->zone->clients, bd, after); + bd->desk->clients = evas_list_remove(bd->desk->clients, bd); + bd->desk->clients = evas_list_append_relative(bd->desk->clients, bd, after); + borders = evas_list_remove(borders, bd); + borders = evas_list_append_relative(borders, bd, after); + } + else + { + bd->container->clients = evas_list_remove(bd->container->clients, bd); + bd->container->clients = evas_list_append(bd->container->clients, bd); + bd->zone->clients = evas_list_remove(bd->zone->clients, bd); + bd->zone->clients = evas_list_append(bd->zone->clients, bd); + bd->desk->clients = evas_list_remove(bd->desk->clients, bd); + bd->desk->clients = evas_list_append(bd->desk->clients, bd); + borders = evas_list_remove(borders, bd); + borders = evas_list_append(borders, bd); + } +} + +static void +_e_border_reorder_before(E_Border *bd, E_Border *before) +{ + if (before) + { + bd->container->clients = evas_list_remove(bd->container->clients, bd); + bd->container->clients = evas_list_prepend_relative(bd->container->clients, bd, before); + bd->zone->clients = evas_list_remove(bd->zone->clients, bd); + bd->zone->clients = evas_list_prepend_relative(bd->zone->clients, bd, before); + bd->desk->clients = evas_list_remove(bd->desk->clients, bd); + bd->desk->clients = evas_list_prepend_relative(bd->desk->clients, bd, before); + borders = evas_list_remove(borders, bd); + borders = evas_list_prepend_relative(borders, bd, before); + } + else + { + bd->container->clients = evas_list_remove(bd->container->clients, bd); + bd->container->clients = evas_list_prepend(bd->container->clients, bd); + bd->zone->clients = evas_list_remove(bd->zone->clients, bd); + bd->zone->clients = evas_list_prepend(bd->zone->clients, bd); + bd->desk->clients = evas_list_remove(bd->desk->clients, bd); + bd->desk->clients = evas_list_prepend(bd->desk->clients, bd); + borders = evas_list_remove(borders, bd); + borders = evas_list_prepend(borders, bd); + } +} diff --git a/src/bin/e_border.h b/src/bin/e_border.h index 756d11a0e..b4f8d92d7 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -271,7 +271,7 @@ EAPI void e_border_unref(E_Border *bd); EAPI void e_border_zone_set(E_Border *bd, E_Zone *zone); EAPI void e_border_desk_set(E_Border *bd, E_Desk *desk); EAPI void e_border_show(E_Border *bd); -EAPI void e_border_hide(E_Border *bd); +EAPI void e_border_hide(E_Border *bd, int manage); EAPI void e_border_move(E_Border *bd, int x, int y); EAPI void e_border_resize(E_Border *bd, int w, int h); EAPI void e_border_move_resize(E_Border *bd, int x, int y, int w, int h); diff --git a/src/bin/e_container.c b/src/bin/e_container.c index 21d50282f..8eb0473d0 100644 --- a/src/bin/e_container.c +++ b/src/bin/e_container.c @@ -395,8 +395,10 @@ static void _e_container_free(E_Container *con) { if (con->gadman) e_object_del(E_OBJECT(con->gadman)); + while (con->zones) e_object_del(E_OBJECT(con->zones->data)); + /* We can't use e_object_del here, because border adds a ref to itself + * when it is removed, and the ref is never unref'ed */ while (con->clients) e_object_free(E_OBJECT(con->clients->data)); - while (con->zones) e_object_free(E_OBJECT(con->zones->data)); con->manager->containers = evas_list_remove(con->manager->containers, con); e_canvas_del(con->bg_ecore_evas); ecore_evas_free(con->bg_ecore_evas); diff --git a/src/bin/e_desk.c b/src/bin/e_desk.c index 537233a0f..45dde1e70 100644 --- a/src/bin/e_desk.c +++ b/src/bin/e_desk.c @@ -9,14 +9,19 @@ */ static void _e_desk_free(E_Desk *desk); -int _e_desk_current_changing; +static void _e_border_event_desk_show_free(void *data, void *ev); + static int desk_count; +int E_EVENT_DESK_SHOW = 0; + int e_desk_init(void) { - _e_desk_current_changing = 0; desk_count = 0; + + E_EVENT_DESK_SHOW = ecore_event_type_new(); + return 1; } @@ -61,12 +66,12 @@ e_desk_show(E_Desk *desk) { Evas_List *l; int x, y; + E_Event_Desk_Show *ev; E_OBJECT_CHECK(desk); E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); if (desk->visible) return; - _e_desk_current_changing = 1; for (l = desk->zone->container->clients; l; l = l->next) { E_Border *bd = l->data; @@ -79,7 +84,7 @@ e_desk_show(E_Desk *desk) } else { - e_border_hide(bd); + e_border_hide(bd, 1); } } } @@ -99,7 +104,11 @@ e_desk_show(E_Desk *desk) } } desk->visible = 1; - _e_desk_current_changing = 0; + + ev = E_NEW(E_Event_Desk_Show, 1); + ev->desk = desk; + e_object_ref(E_OBJECT(desk)); + ecore_event_add(E_EVENT_DESK_SHOW, ev, _e_border_event_desk_show_free, NULL); } void @@ -228,10 +237,18 @@ e_desk_prev(E_Zone *zone) static void _e_desk_free(E_Desk *desk) { - E_Zone *zone = desk->zone; if (desk->name) free(desk->name); -// zone->desks = evas_list_remove(zone->desks, desk); free(desk); } +static void +_e_border_event_desk_show_free(void *data, void *event) +{ + E_Event_Desk_Show *ev; + + ev = event; + e_object_unref(E_OBJECT(ev->desk)); + free(ev); +} + diff --git a/src/bin/e_desk.h b/src/bin/e_desk.h index a7afdf9ba..cc7f32540 100644 --- a/src/bin/e_desk.h +++ b/src/bin/e_desk.h @@ -4,6 +4,7 @@ #ifdef E_TYPEDEFS typedef struct _E_Desk E_Desk; +typedef struct _E_Event_Desk_Show E_Event_Desk_Show; #else #ifndef E_DESK_H @@ -25,6 +26,11 @@ struct _E_Desk Evas_List *clients; }; +struct _E_Event_Desk_Show +{ + E_Desk *desk; +}; + EAPI int e_desk_init(void); EAPI int e_desk_shutdown(void); EAPI E_Desk *e_desk_new(E_Zone *zone, int x, int y); @@ -40,5 +46,7 @@ EAPI void e_desk_row_remove(E_Zone *zone); EAPI void e_desk_col_add(E_Zone *zone); EAPI void e_desk_col_remove(E_Zone *zone); +extern EAPI int E_EVENT_DESK_SHOW; + #endif #endif diff --git a/src/bin/e_hints.c b/src/bin/e_hints.c index 041d46968..c0f7a94d3 100644 --- a/src/bin/e_hints.c +++ b/src/bin/e_hints.c @@ -158,6 +158,19 @@ e_hints_window_name_set(Ecore_X_Window win, const char *name) ecore_x_netwm_name_set(win, name); } +char * +e_hints_window_name_get(Ecore_X_Window win) +{ + char *name; + + name = ecore_x_netwm_name_get(win); + if (!name) + name = ecore_x_icccm_title_get(win); + if (!name) + name = strdup("No name!!"); + return name; +} + void e_hints_desktop_config_set(void) { @@ -257,12 +270,76 @@ e_hints_window_state_set(Ecore_X_Window win) } void -e_hints_window_visible_set(Ecore_X_Window win, int on) +e_hints_window_state_get(Ecore_X_Window win) { - int hidden; + E_Border *bd; + int above, below; - hidden = on ? 0 : 1; - ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_HIDDEN, hidden); + bd = e_border_find_by_client_window(win); + + bd->client.netwm.state.modal = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MODAL); + bd->sticky = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_STICKY); + bd->client.netwm.state.maximized_v = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MAXIMIZED_VERT); + bd->client.netwm.state.maximized_h = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ); + bd->shaded = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SHADED); + bd->client.netwm.state.skip_taskbar = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SKIP_TASKBAR); + bd->client.netwm.state.skip_pager = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SKIP_PAGER); + bd->visible = + !ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_HIDDEN); + bd->client.netwm.state.fullscreen = + ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_FULLSCREEN); + + above = ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_ABOVE); + below = ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_BELOW); + bd->client.netwm.state.stacking = (above << 0) + (below << 1); +} + +void +e_hints_window_visible_set(Ecore_X_Window win) +{ + ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_NORMAL); + ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_HIDDEN, 0); +} + +int +e_hints_window_visible_isset(Ecore_X_Window win) +{ + return !ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_HIDDEN) + || (ecore_x_icccm_state_get(win) == ECORE_X_WINDOW_STATE_HINT_NORMAL); +} + +void +e_hints_window_iconic_set(Ecore_X_Window win) +{ + ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_ICONIC); + ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_HIDDEN, 1); +} + +int +e_hints_window_iconic_isset(Ecore_X_Window win) +{ + return (ecore_x_icccm_state_get(win) == ECORE_X_WINDOW_STATE_HINT_ICONIC); +} + +void +e_hints_window_hidden_set(Ecore_X_Window win) +{ + ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_WITHDRAWN); + ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_HIDDEN, 1); +} + +int +e_hints_window_hidden_isset(Ecore_X_Window win) +{ + return ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_HIDDEN) + || (ecore_x_icccm_state_get(win) != ECORE_X_WINDOW_STATE_HINT_NORMAL); } void @@ -277,6 +354,27 @@ e_hints_window_shaded_isset(Ecore_X_Window win) return ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SHADED); } +void +e_hints_window_shade_direction_set(Ecore_X_Window win, E_Direction dir) +{ + ecore_x_window_prop_card32_set(win, E_ATOM_SHADE_DIRECTION, &dir, 1); +} + +E_Direction +e_hints_window_shade_direction_get(Ecore_X_Window win) +{ + int ret; + E_Direction dir; + + ret = ecore_x_window_prop_card32_get(win, + E_ATOM_SHADE_DIRECTION, + &dir, 1); + if (ret == 1) + return dir; + + return E_DIRECTION_UP; +} + void e_hints_window_maximized_set(Ecore_X_Window win, int on) { @@ -312,52 +410,6 @@ ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_ABOVE, on); ecore_x_netwm_window_state_set(win, ECORE_X_WINDOW_STATE_BELOW, on); */ -void -e_hints_window_state_get(Ecore_X_Window win) -{ - E_Border *bd; - int above, below; - - bd = e_border_find_by_client_window(win); - - bd->client.netwm.state.modal = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MODAL); - bd->sticky = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_STICKY); - bd->client.netwm.state.maximized_v = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MAXIMIZED_VERT); - bd->client.netwm.state.maximized_h = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ); - bd->shaded = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SHADED); - bd->client.netwm.state.skip_taskbar = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SKIP_TASKBAR); - bd->client.netwm.state.skip_pager = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_SKIP_PAGER); - bd->visible = - !ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_HIDDEN); - bd->client.netwm.state.fullscreen = - ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_FULLSCREEN); - - above = ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_ABOVE); - below = ecore_x_netwm_window_state_isset(win, ECORE_X_WINDOW_STATE_BELOW); - bd->client.netwm.state.stacking = (above << 0) + (below << 1); -} - -void -e_hints_window_name_get(Ecore_X_Window win) -{ - E_Border *bd; - char *name; - - name = ecore_x_netwm_name_get(win); - bd = e_border_find_by_client_window(win); - if (bd->client.icccm.name) - free(bd->client.icccm.name); - bd->client.icccm.name = name; - bd->changed = 1; -} - void e_hints_window_icon_name_get(Ecore_X_Window win) { diff --git a/src/bin/e_hints.h b/src/bin/e_hints.h index ec5e21301..2a3b872f1 100644 --- a/src/bin/e_hints.h +++ b/src/bin/e_hints.h @@ -11,17 +11,25 @@ EAPI void e_hints_client_list_set(void); EAPI void e_hints_client_stacking_set(void); EAPI void e_hints_active_window_set(E_Manager *man, Ecore_X_Window win); EAPI void e_hints_window_name_set(Ecore_X_Window win, const char *name); +EAPI char *e_hints_window_name_get(Ecore_X_Window win); EAPI void e_hints_desktop_config_set(void); EAPI void e_hints_window_state_set(Ecore_X_Window win); -EAPI void e_hints_window_name_get(Ecore_X_Window win); -EAPI void e_hints_window_icon_name_get(Ecore_X_Window win); -EAPI void e_hints_window_visible_set(Ecore_X_Window win, int on); +EAPI void e_hints_window_visible_set(Ecore_X_Window win); +EAPI int e_hints_window_visible_isset(Ecore_X_Window win); +EAPI void e_hints_window_iconic_set(Ecore_X_Window win); +EAPI int e_hints_window_iconic_isset(Ecore_X_Window win); +EAPI void e_hints_window_hidden_set(Ecore_X_Window win); +EAPI int e_hints_window_hidden_isset(Ecore_X_Window win); EAPI void e_hints_window_shaded_set(Ecore_X_Window win, int on); EAPI int e_hints_window_shaded_isset(Ecore_X_Window win); +EAPI void e_hints_window_shade_direction_set(Ecore_X_Window win, E_Direction dir); +EAPI E_Direction e_hints_window_shade_direction_get(Ecore_X_Window win); + EAPI void e_hints_window_maximized_set(Ecore_X_Window win, int on); EAPI int e_hints_window_maximized_isset(Ecore_X_Window win); EAPI void e_hints_window_sticky_set(Ecore_X_Window win, int on); EAPI int e_hints_window_sticky_isset(Ecore_X_Window win); +EAPI void e_hints_window_icon_name_get(Ecore_X_Window win); #endif #endif