From 95e74747fff7f8738a45ed9c183f8777b9796fa8 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 19 Jun 2005 12:35:05 +0000 Subject: [PATCH] lost windows men TODO... answer seb's todo q. :) SVN revision: 15427 --- TODO | 8 ++-- src/bin/e.h | 1 + src/bin/e_border.c | 62 +++++++++++++++++++++++++ src/bin/e_border.h | 1 + src/bin/e_int_menus.c | 105 +++++++++++++++++++++++++++++++++++++++++- src/bin/e_int_menus.h | 1 + 6 files changed, 171 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 2bbc805ce..469994419 100644 --- a/TODO +++ b/TODO @@ -59,7 +59,9 @@ These are in no particular order: * add fullscreen support (e16 xvidmode or xrandr style) * implement thses maximise/fullscreen modes: Which of these should be different modes, and which should be options for - a mode? + a mode? i think they all should be distinct actions of their own bound + to a key, button etc. which one of these the maximize button on a window + will execute should be a configuration value though :) 1. fullscreen (no border - resizes to default screen res). window is locked, no mouse bindings work. any focus change out of thsi window will go out of fullscreen mode @@ -84,10 +86,6 @@ These are in no particular order: * dialogs for generic contents too * bug?: xine's ui window/panel is under its video window when u go fullscreen. is this correct? -* "lost windows" - windows that are moved outside the desktop coords BY an app - or are put there to start should be considered "lost windows" e should keep - a list of these and some sort of access to them so a user can forcibly get - them back by saying "get me that lost window" * netwm window types and states need addressing (do special/appropriate things) for each of them. * use ecore_x_netwm_ping_send() to windowsthat suport it regularly to see if diff --git a/src/bin/e.h b/src/bin/e.h index ac1dfbc39..6e63dec80 100644 --- a/src/bin/e.h +++ b/src/bin/e.h @@ -60,6 +60,7 @@ typedef struct _E_Rect E_Rect; #define E_FN_DEL(_fn, _h) if (_h) { _fn(_h); _h = NULL; } #define E_INTERSECTS(x, y, w, h, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && (((x) + (w)) > (xx)) && (((y) + (h)) > (yy))) #define E_INSIDE(x, y, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && ((x) >= (xx)) && ((y) >= (yy))) +#define E_CONTAINS(x, y, w, h, xx, yy, ww, hh) (((xx) >= (x)) && (((x) + (w)) <= ((xx) + (ww))) && ((yy) >= (y)) && (((y) + (h)) <= ((yy) + (hh)))) #define E_SPANS_COMMON(x1, w1, x2, w2) (!((((x2) + (w2)) <= (x1)) || ((x2) >= ((x1) + (w1))))) #define E_REALLOC(p, s, n) p = realloc(p, sizeof(s) * n) #define E_NEW(s, n) calloc(n, sizeof(s)) diff --git a/src/bin/e_border.c b/src/bin/e_border.c index f102ee571..8159a251d 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -1778,6 +1778,68 @@ e_border_focus_stack_get(void) return focus_stack; } +Evas_List * +e_border_lost_windows_get(E_Zone *zone) +{ + Evas_List *list = NULL, *l; + int loss_overlap = 5; + + for (l = borders; l; l = l->next) + { + E_Border *bd; + + bd = l->data; + if (bd->zone) + { + if ((bd->zone == zone) || + (bd->zone->container == zone->container)) + { + if (!E_INTERSECTS(bd->zone->x + loss_overlap, + bd->zone->y + loss_overlap, + bd->zone->w - (2 * loss_overlap), + bd->zone->h - (2 * loss_overlap), + bd->x, bd->y, bd->w, bd->h)) + { + list = evas_list_append(list, bd); + } + else if ((!E_CONTAINS(bd->zone->x, bd->zone->y, + bd->zone->w, bd->zone->h, + bd->x, bd->y, bd->w, bd->h)) && + (bd->shaped)) + { + Ecore_X_Rectangle *rect; + int i, num; + + rect = ecore_x_window_shape_rectangles_get(bd->win, &num); + if (rect) + { + int ok; + + ok = 0; + for (i = 0; i < num; i++) + { + if (E_INTERSECTS(bd->zone->x + loss_overlap, + bd->zone->y + loss_overlap, + bd->zone->w - (2 * loss_overlap), + bd->zone->h - (2 * loss_overlap), + rect[i].x, rect[i].y, + rect[i].width, rect[i].height)) + { + ok = 1; + break; + } + } + free(rect); + if (!ok) + list = evas_list_append(list, bd); + } + } + } + } + } + return list; +} + /* local subsystem functions */ static void _e_border_free(E_Border *bd) diff --git a/src/bin/e_border.h b/src/bin/e_border.h index 26c4b9672..ca00b29d8 100644 --- a/src/bin/e_border.h +++ b/src/bin/e_border.h @@ -454,6 +454,7 @@ EAPI void e_border_button_bindings_ungrab_all(void); EAPI void e_border_button_bindings_grab_all(void); EAPI Evas_List *e_border_focus_stack_get(void); +EAPI Evas_List *e_border_lost_windows_get(E_Zone *zone); extern EAPI int E_EVENT_BORDER_RESIZE; extern EAPI int E_EVENT_BORDER_MOVE; diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 29f15e711..ca2e748e0 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -15,6 +15,7 @@ struct _Main_Data E_Menu *gadgets; E_Menu *themes; E_Menu *config; + E_Menu *lost_clients; }; /* local subsystem functions */ @@ -42,6 +43,9 @@ static void _e_int_menus_gadgets_pre_cb (void *data, E_Menu *m); static void _e_int_menus_gadgets_edit_mode_cb(void *data, E_Menu *m, E_Menu_Item *mi); static void _e_int_menus_themes_pre_cb (void *data, E_Menu *m); static void _e_int_menus_themes_edit_mode_cb (void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_int_menus_lost_clients_pre_cb (void *data, E_Menu *m); +static void _e_int_menus_lost_clients_free_hook (void *obj); +static void _e_int_menus_lost_clients_item_cb (void *data, E_Menu *m, E_Menu_Item *mi); /* externally accessible functions */ E_Menu * @@ -97,6 +101,15 @@ e_int_menus_main_new(void) IF_FREE(s); e_menu_item_submenu_set(mi, subm); + subm = e_int_menus_lost_clients_new(); + dat->lost_clients = subm; + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Lost Windows")); + s = e_path_find(path_icons, "default.edj"); + e_menu_item_icon_edje_set(mi, s, "lost_windows"); + IF_FREE(s); + e_menu_item_submenu_set(mi, subm); + subm = e_int_menus_gadgets_new(); dat->gadgets = subm; mi = e_menu_item_new(m); @@ -245,6 +258,16 @@ e_int_menus_themes_new(void) return m; } +E_Menu * +e_int_menus_lost_clients_new(void) +{ + E_Menu *m; + + m = e_menu_new(); + e_menu_pre_activate_callback_set(m, _e_int_menus_lost_clients_pre_cb, NULL); + return m; +} + /* local subsystem functions */ static void _e_int_menus_main_del_hook(void *obj) @@ -263,6 +286,7 @@ _e_int_menus_main_del_hook(void *obj) e_object_del(E_OBJECT(dat->gadgets)); e_object_del(E_OBJECT(dat->themes)); e_object_del(E_OBJECT(dat->config)); + e_object_del(E_OBJECT(dat->lost_clients)); free(dat); } } @@ -529,7 +553,7 @@ _e_int_menus_clients_pre_cb(void *data, E_Menu *m) else if (bd->client.icccm.title) e_menu_item_label_set(mi, bd->client.icccm.title); else - e_menu_item_label_set(mi, "No name!!"); + e_menu_item_label_set(mi, _("No name!!")); /* ref the border as we implicitly unref it in the callback */ e_object_ref(E_OBJECT(bd)); e_menu_item_callback_set(mi, _e_int_menus_clients_item_cb, bd); @@ -569,7 +593,6 @@ _e_int_menus_clients_free_hook(void *obj) } } - static void _e_int_menus_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) { @@ -737,3 +760,81 @@ _e_int_menus_themes_edit_mode_cb(void *data, E_Menu *m, E_Menu_Item *mi) restart = 1; ecore_main_loop_quit(); } + +static void +_e_int_menus_lost_clients_pre_cb(void *data, E_Menu *m) +{ + E_Menu_Item *mi; + Evas_List *l, *borders = NULL; + E_Menu *root; + E_Zone *zone = NULL; + char *s; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + root = e_menu_root_get(m); + /* get the current clients */ + if (root) + zone = root->zone; + borders = e_border_lost_windows_get(zone); + + if (!borders) + { + /* FIXME here we want nothing, but that crashes!!! */ + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("(No Windows)")); + return; + } + for (l = borders; l; l = l->next) + { + E_Border *bd = l->data; + E_App *a; + + mi = e_menu_item_new(m); + if (bd->client.netwm.name) + e_menu_item_label_set(mi, bd->client.netwm.name); + else if (bd->client.icccm.title) + e_menu_item_label_set(mi, bd->client.icccm.title); + else + e_menu_item_label_set(mi, _("No name!!")); + /* ref the border as we implicitly unref it in the callback */ + e_object_ref(E_OBJECT(bd)); + e_menu_item_callback_set(mi, _e_int_menus_lost_clients_item_cb, bd); + a = e_app_window_name_class_find(bd->client.icccm.name, + bd->client.icccm.class); + if (a) e_menu_item_icon_edje_set(mi, a->path, "icon"); + } + e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_lost_clients_free_hook); + e_object_data_set(E_OBJECT(m), borders); +} + +static void +_e_int_menus_lost_clients_free_hook(void *obj) +{ + E_Menu *m; + Evas_List *borders; + + m = obj; + borders = e_object_data_get(E_OBJECT(m)); + while (borders) + { + E_Border *bd; + + bd = borders->data; + borders = evas_list_remove_list(borders, borders); + e_object_unref(E_OBJECT(bd)); + } +} + + +static void +_e_int_menus_lost_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) +{ + E_Border *bd = data; + + E_OBJECT_CHECK(bd); + if (bd->iconic) e_border_uniconify(bd); + if (bd->desk) e_desk_show(bd->desk); + e_border_move(bd, bd->zone->x + ((bd->zone->w - bd->w) / 2), bd->zone->y + ((bd->zone->h - bd->h) / 2)); + e_border_raise(bd); + e_border_focus_set(bd, 1, 1); +} diff --git a/src/bin/e_int_menus.h b/src/bin/e_int_menus.h index abac54d0b..78b497f22 100644 --- a/src/bin/e_int_menus.h +++ b/src/bin/e_int_menus.h @@ -14,6 +14,7 @@ EAPI E_Menu *e_int_menus_favorite_apps_new(void); EAPI E_Menu *e_int_menus_config_apps_new(void); EAPI E_Menu *e_int_menus_gadgets_new(void); EAPI E_Menu *e_int_menus_themes_new(void); +EAPI E_Menu *e_int_menus_lost_clients_new(void); #endif #endif