diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 9037a8010..3116ff74e 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -136,7 +136,8 @@ e_int_config_modules.h \ e_exehist.h \ e_color_class.h \ e_widget_textblock.h \ -e_apps_error.h +e_apps_error.h \ +e_stolen.h enlightenment_src = \ e_user.c \ @@ -254,6 +255,7 @@ e_exehist.c \ e_color_class.c \ e_widget_textblock.c \ e_apps_error.c \ +e_stolen.c \ $(ENLIGHTENMENTHEADERS) enlightenment_SOURCES = \ diff --git a/src/bin/e_border.c b/src/bin/e_border.c index ba27dd824..aec219803 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -3161,6 +3161,7 @@ _e_border_cb_window_configure_request(void *data, int ev_type, void *ev) bd = e_border_find_by_client_window(e->win); if (!bd) { + if (e_stolen_win_get(e->win)) return 1; // printf("generic config request 0x%x 0x%lx %i %i %ix%i %i 0x%x 0x%x...\n", // e->win, e->value_mask, e->x, e->y, e->w, e->h, e->border, e->abovewin, e->detail); if (!e_util_container_window_find(e->win)) @@ -3366,6 +3367,7 @@ _e_border_cb_window_resize_request(void *data, int ev_type, void *ev) bd = e_border_find_by_client_window(e->win); if (!bd) { + if (e_stolen_win_get(e->win)) return 1; // printf("generic resize request %x %ix%i ...\n", // e->win, e->w, e->h); ecore_x_window_resize(e->win, e->w, e->h); @@ -3429,6 +3431,7 @@ _e_border_cb_window_stack_request(void *data, int ev_type, void *ev) // printf("stack req for %0x bd %p\n", e->win, bd); if (!bd) { + if (e_stolen_win_get(e->win)) return 1; if (!e_util_container_window_find(e->win)) { if (e->detail == ECORE_X_WINDOW_STACK_ABOVE) diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 89dae7186..92d5aaf45 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -115,3 +115,4 @@ #include "e_color_class.h" #include "e_widget_textblock.h" #include "e_apps_error.h" +#include "e_stolen.h" diff --git a/src/bin/e_manager.c b/src/bin/e_manager.c index 8f7c241c7..9e487ec66 100644 --- a/src/bin/e_manager.c +++ b/src/bin/e_manager.c @@ -462,6 +462,7 @@ _e_manager_cb_window_show_request(void *data, int ev_type __UNUSED__, void *ev) man = data; e = ev; + if (e_stolen_win_get(e->win)) return 1; #if 0 if (e->parent != man->root) return 1; /* try other handlers for this */ diff --git a/src/bin/e_stolen.c b/src/bin/e_stolen.c new file mode 100644 index 000000000..17460f894 --- /dev/null +++ b/src/bin/e_stolen.c @@ -0,0 +1,86 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +static char *_e_stolen_winid_str_get(Ecore_X_Window win); + +typedef struct _E_Stolen_Window E_Stolen_Window; + +struct _E_Stolen_Window +{ + Ecore_X_Window win; + int refcount; +}; + +static Evas_Hash *_e_stolen_windows = NULL; + +/* externally accessible functions */ +EAPI int +e_stolen_win_get(Ecore_X_Window win) +{ + E_Stolen_Window *esw; + + esw = evas_hash_find(_e_stolen_windows, _e_stolen_winid_str_get(win)); + if (esw) return 1; + return 0; +} + +EAPI void +e_stolen_win_add(Ecore_X_Window win) +{ + E_Stolen_Window *esw; + + esw = evas_hash_find(_e_stolen_windows, _e_stolen_winid_str_get(win)); + if (esw) + { + esw->refcount++; + } + else + { + esw = E_NEW(E_Stolen_Window, 1); + esw->win = win; + esw->refcount = 1; + _e_stolen_windows = evas_hash_add(_e_stolen_windows, _e_stolen_winid_str_get(win), esw); + } + return; +} + +EAPI void +e_stolen_win_del(Ecore_X_Window win) +{ + E_Stolen_Window *esw; + + esw = evas_hash_find(_e_stolen_windows, _e_stolen_winid_str_get(win)); + if (esw) + { + esw->refcount--; + if (esw->refcount == 0) + { + _e_stolen_windows = evas_hash_del(_e_stolen_windows, _e_stolen_winid_str_get(win), esw); + free(esw); + } + } + return; +} + +/* local subsystem functions */ +static char * +_e_stolen_winid_str_get(Ecore_X_Window win) +{ + const char *vals = "qWeRtYuIoP5-$&<~"; + static char id[9]; + unsigned int val; + + val = (unsigned int)win; + id[0] = vals[(val >> 28) & 0xf]; + id[1] = vals[(val >> 24) & 0xf]; + id[2] = vals[(val >> 20) & 0xf]; + id[3] = vals[(val >> 16) & 0xf]; + id[4] = vals[(val >> 12) & 0xf]; + id[5] = vals[(val >> 8) & 0xf]; + id[6] = vals[(val >> 4) & 0xf]; + id[7] = vals[(val ) & 0xf]; + id[8] = 0; + return id; +} diff --git a/src/bin/e_stolen.h b/src/bin/e_stolen.h new file mode 100644 index 000000000..66827bd25 --- /dev/null +++ b/src/bin/e_stolen.h @@ -0,0 +1,14 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS +#else +#ifndef E_STOLEN_H +#define E_STOLEN_H + +EAPI int e_stolen_win_get(Ecore_X_Window win); +EAPI void e_stolen_win_add(Ecore_X_Window win); +EAPI void e_stolen_win_del(Ecore_X_Window win); + +#endif +#endif diff --git a/src/modules/itray/e_mod_main.c b/src/modules/itray/e_mod_main.c index 4a0e9aa75..574fbedd0 100644 --- a/src/modules/itray/e_mod_main.c +++ b/src/modules/itray/e_mod_main.c @@ -21,7 +21,7 @@ #define XEMBED_EMBEDDED_NOTIFY 0 -#define TRAY_ICON_SIZE 24 +#define TRAY_ICON_SIZE 27 /* Bug List: * @@ -1030,20 +1030,87 @@ _itray_tray_active_set(ITray_Box *itb, int active) static void _itray_tray_add(ITray_Box *itb, Ecore_X_Window win) { + if (!win) return; if (evas_list_find(itb->tray->wins, (void *)win)) return; + e_stolen_win_add(win); ecore_x_window_show(itb->tray->win); evas_object_show(itb->item_object); - /* FIXME: need a way to register managed windows so the - * managers default configure request handler doesnt do anything + /* FIXME: adding a window id AS a pointer - BAD! */ + /* FIXME: add property to the window so on restart we can pick it up again */ + /* FIXME: need to listen for shape change events on icons */ + /* FIXME: on shape change need to inherit shape */ + /* FIXME: need to solve the windows above canvas event problem */ + /* FIXME: need to handle min/max size of tray client window? */ + /* FIXME: properties u might find on sample windows: + * + * GDK_TIMESTAMP_PROP(GDK_TIMESTAMP_PROP) = 0x61 + * _NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 29360209 + * _XEMBED_INFO(_XEMBED_INFO) = 0x1, 0x1 + * WM_CLIENT_LEADER(WINDOW): window id # 0x1c00001 + * _NET_WM_PID(CARDINAL) = 17802 + * WM_LOCALE_NAME(STRING) = "ja_JP.UTF-8" + * WM_CLIENT_MACHINE(STRING) = "icky" + * WM_NORMAL_HINTS(WM_SIZE_HINTS): + * program specified minimum size: 24 by 24 + * window gravity: NorthWest + * WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST + * WM_CLASS(STRING) = "gaim", "Gaim" + * WM_ICON_NAME(STRING) = "Gaim" + * _NET_WM_ICON_NAME(UTF8_STRING) = 0x47, 0x61, 0x69, 0x6d + * WM_NAME(STRING) = "Gaim" + * _NET_WM_NAME(UTF8_STRING) = 0x47, 0x61, 0x69, 0x6d + *--- + * GDK_TIMESTAMP_PROP(GDK_TIMESTAMP_PROP) = 0x61 + * _NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 29360172 + * _XEMBED_INFO(_XEMBED_INFO) = 0x1, 0x1 + * WM_CLIENT_LEADER(WINDOW): window id # 0x1c00001 + * _NET_WM_PID(CARDINAL) = 17841 + * WM_LOCALE_NAME(STRING) = "ja_JP.UTF-8" + * WM_CLIENT_MACHINE(STRING) = "icky" + * WM_NORMAL_HINTS(WM_SIZE_HINTS): + * program specified minimum size: 16 by 16 + * window gravity: NorthWest + * WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST + * WM_CLASS(STRING) = "gnomemeeting", "Gnomemeeting" + * WM_ICON_NAME(STRING) = "GnomeMeeting Tray Icon" + * _NET_WM_ICON_NAME(UTF8_STRING) = 0x47, 0x6e, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x54, 0x72, 0x61, 0x79, 0x20, 0x49, 0x63, 0x6f, 0x6e + * WM_NAME(STRING) = "GnomeMeeting Tray Icon" + * _NET_WM_NAME(UTF8_STRING) = 0x47, 0x6e, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x54, 0x72, 0x61, 0x79, 0x20, 0x49, 0x63, 0x6f, 0x6e + *--- + * _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR(WINDOW): window id # 0x0 + * KWM_DOCKWINDOW(KWM_DOCKWINDOW) = 0x0 + * WM_CLIENT_LEADER(WINDOW): window id # 0x1c00006 + * WM_WINDOW_ROLE(STRING) = "skypedock" + * _NET_WM_PID(CARDINAL) = 18018 + * _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL + * WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING + * WM_NAME(STRING) = "skype" + * WM_LOCALE_NAME(STRING) = "ja_JP.UTF-8" + * WM_CLASS(STRING) = "skypedock", "Skype" + * WM_HINTS(WM_HINTS): + * Initial state is Normal State. + * bitmap id # to use for icon: 0x1c00025 + * bitmap id # of mask for icon: 0x1c00026 + * window id # to use for icon: 0x1c000b1 + * window id # of group leader: 0x1c000b1 + * WM_NORMAL_HINTS(WM_SIZE_HINTS): + * user specified size: 22 by 22 + * program specified size: 22 by 22 + * program specified minimum size: 22 by 22 + * program specified maximum size: 22 by 22 + * window gravity: NorthWest + * WM_CLIENT_MACHINE(STRING) = "icky" + * */ /* we want to insert at the end, so as not to move all icons on each add */ itb->tray->wins = evas_list_append(itb->tray->wins, (void *)win); itb->tray->icons++; ecore_x_window_client_manage(win); ecore_x_window_resize(win, TRAY_ICON_SIZE, TRAY_ICON_SIZE); - + + ecore_x_window_save_set_add(win); ecore_x_window_reparent(win, itb->tray->win, 0, 0); _itray_tray_layout(itb); _itray_box_frame_resize(itb); @@ -1060,7 +1127,7 @@ _itray_tray_remove(ITray_Box *itb, Ecore_X_Window win) return; if (!evas_list_find(itb->tray->wins, (void *)win)) /* if was not found */ return; - + e_stolen_win_del(win); itb->tray->wins = evas_list_remove(itb->tray->wins, (void *)win); itb->tray->icons--; _itray_tray_layout(itb); @@ -1080,26 +1147,29 @@ _itray_tray_cb_msg(void *data, int type, void *event) ITray_Box *itb; itb = data; - if (type == ECORE_X_EVENT_CLIENT_MESSAGE) { + if (type == ECORE_X_EVENT_CLIENT_MESSAGE) + { ev = event; - if (ev->message_type == ecore_x_atom_get("_NET_SYSTEM_TRAY_OPCODE")) { - _itray_tray_add(itb, (Ecore_X_Window) ev->data.l[2]); - + if (ev->message_type == ecore_x_atom_get("_NET_SYSTEM_TRAY_OPCODE")) + { + _itray_tray_add(itb, (Ecore_X_Window)ev->data.l[2]); /* Should proto be set according to clients _XEMBED_INFO? */ - ecore_x_client_message32_send( - ev->data.l[2], - ecore_x_atom_get("_XEMBED"), - ECORE_X_EVENT_MASK_NONE, CurrentTime, - XEMBED_EMBEDDED_NOTIFY, 0, itb->con->bg_win, /*proto*/1); - - } else if (ev->message_type == ecore_x_atom_get("_NET_SYSTEM_TRAY_MESSAGE_DATA")) { + ecore_x_client_message32_send(ev->data.l[2], + ecore_x_atom_get("_XEMBED"), + ECORE_X_EVENT_MASK_NONE, CurrentTime, + XEMBED_EMBEDDED_NOTIFY, 0, itb->con->bg_win, /*proto*/1); + + } + else if (ev->message_type == ecore_x_atom_get("_NET_SYSTEM_TRAY_MESSAGE_DATA")) + { printf("got message\n"); - } - } else if (type == ECORE_X_EVENT_WINDOW_DESTROY) { + } + } + else if (type == ECORE_X_EVENT_WINDOW_DESTROY) + { dst = event; _itray_tray_remove(itb, (Ecore_X_Window) dst->win); - } - + } return 1; } @@ -1149,48 +1219,53 @@ _itray_tray_layout(ITray_Box *itb) } w = ((itb->tray->icons + (itb->tray->icons % c)) / c) * TRAY_ICON_SIZE; - if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_TOP) { + if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_TOP) + { edje_object_part_unswallow(itb->box_object, itb->item_object); evas_object_resize(itb->item_object, w, h); ecore_x_window_resize(itb->tray->win, (int) w, (int) h); - + edje_extern_object_min_size_set(itb->item_object, w, h); edje_extern_object_max_size_set(itb->item_object, w, h); edje_object_part_swallow(itb->box_object, "tray", itb->item_object); - } else { + } + else + { edje_object_part_unswallow(itb->box_object, itb->item_object); evas_object_resize(itb->item_object, h, w); ecore_x_window_resize(itb->tray->win, (int) h, (int) w); - + edje_extern_object_min_size_set(itb->item_object, w, h); edje_extern_object_max_size_set(itb->item_object, w, h); edje_object_part_swallow(itb->box_object, "tray", itb->item_object); - } - + } + x = 0; if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_RIGHT) y = h - TRAY_ICON_SIZE; else y = 0; d = 0; - for (wins = itb->tray->wins; wins; wins = wins->next) { + for (wins = itb->tray->wins; wins; wins = wins->next) + { if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_TOP) ecore_x_window_move((Ecore_X_Window) wins->data, x, y); else ecore_x_window_move((Ecore_X_Window) wins->data, y, x); - + d++; - if (d % c == 0) { + if (d % c == 0) + { x += TRAY_ICON_SIZE; if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_RIGHT) y = h - TRAY_ICON_SIZE; else y = 0; - } else - if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_RIGHT) - y -= TRAY_ICON_SIZE; - else - y += TRAY_ICON_SIZE; - } + } + else if (edge == E_GADMAN_EDGE_BOTTOM || edge == E_GADMAN_EDGE_RIGHT) + y -= TRAY_ICON_SIZE; + else + y += TRAY_ICON_SIZE; + } itb->tray->rows = c; }