From c094541aef17af74aa835afbae8f484102980cd5 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 11 Oct 2012 12:53:15 +0000 Subject: [PATCH] patch from PrinceAMD which adds config options to warp lost windows back to center screen when enabled video: http://dl.dropbox.com/u/7371269/lost_window_feature_2.ogv SVN revision: 77878 --- src/bin/e_border.c | 151 +++++++++++++++++- src/bin/e_config.c | 6 + src/bin/e_config.h | 3 + src/bin/e_int_menus.c | 2 +- .../e_int_config_window_display.c | 25 ++- 5 files changed, 179 insertions(+), 8 deletions(-) diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 1926a2cf3..5ff8a936f 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -209,6 +209,9 @@ static void _e_border_shape_input_rectangle_set(E_Border* bd); static void _e_border_show(E_Border *bd); static void _e_border_hide(E_Border *bd); +static Eina_Bool _e_border_lost_window_internal_get(E_Border *bd); +static void _e_border_reset_lost_window(E_Border *bd); +static Eina_Bool _e_border_pointer_warp_to_center_timer(void *data); /* local subsystem globals */ static Eina_List *handlers = NULL; static Eina_List *borders = NULL; @@ -1419,6 +1422,9 @@ e_border_move(E_Border *bd, return; _e_border_move_internal(bd, x, y, 0); + + if(_e_border_lost_window_internal_get(bd)) + _e_border_reset_lost_window(bd); } @@ -4294,6 +4300,87 @@ e_border_lost_windows_get(E_Zone *zone) return list; } +static Eina_Bool +_e_border_lost_window_internal_get(E_Border *bd) +{ + int loss_overlap = 5; + + if(e_config->window_out_of_vscreen_limits) return EINA_FALSE; + if(!(bd->zone)) + return EINA_FALSE; + + 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)) + { + return EINA_TRUE; + } + 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, + (int)rect[i].width, (int)rect[i].height)) + { + ok = 1; + break; + } + } + free(rect); + if (!ok) + return EINA_TRUE; + } + } + + return EINA_FALSE; +} + +static void +_e_border_reset_lost_window(E_Border *bd) +{ + int x, y, w, h; + E_OBJECT_CHECK(bd); + + if(bd->iconic) e_border_uniconify(bd); + if(!bd->moving) e_border_center(bd); + + e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h); + ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y); + + warp_to_x = bd->w + x + ((w / 2) - (bd->w / 2)) + ((warp_x - bd->w) - bd->x); + warp_to_y = bd->h + y + ((h / 2) - (bd->h / 2)) + ((warp_y - bd->h) - bd->y); + + warp_to = 1; + warp_to_win = bd->zone->container->win; + + if(!warp_timer) + warp_timer = ecore_timer_add(0.01, + _e_border_pointer_warp_to_center_timer, (const void *) bd); + + e_border_raise(bd); + if(!bd->lock_focus_out) + e_border_focus_set(bd, 1, 1); +} + EAPI void e_border_ping(E_Border *bd) { @@ -5463,6 +5550,10 @@ _e_border_cb_window_property(void *data __UNUSED__, e = ev; bd = e_border_find_by_client_window(e->win); if (!bd) return ECORE_CALLBACK_PASS_ON; + + if(_e_border_lost_window_internal_get(bd)) + _e_border_reset_lost_window(bd); + if (e->atom == ECORE_X_ATOM_WM_NAME) { if ((!bd->client.netwm.name) && @@ -6546,6 +6637,47 @@ _e_border_cb_mouse_up(void *data, return ECORE_CALLBACK_PASS_ON; } +static void +_e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y) +{ + int new_x_max, new_y_max; + Eina_Bool lw, lh; + + new_x_max = bd->zone->w - bd->w; + new_y_max = bd->zone->h - bd->h; + lw = bd->w > bd->zone->w ? EINA_TRUE : EINA_FALSE; + lh = bd->h > bd->zone->h ? EINA_TRUE : EINA_FALSE; + + if(lw) + { + if (x <= new_x_max) + *new_x = new_x_max; + else if (x >= 0) + *new_x = 0; + } + else + { + if (x >= new_x_max) + *new_x = new_x_max; + else if (x <= 0) + *new_x = 0; + } + + if(lh) + { + if (y <= new_y_max) + *new_y = new_y_max; + else if (y >= 0) + *new_y = 0; + } + else + { + if (y >= new_y_max) + *new_y = new_y_max; + else if (y <= 0) + *new_y = 0; + } +} static Eina_Bool _e_border_cb_mouse_move(void *data, int type __UNUSED__, @@ -6589,12 +6721,19 @@ _e_border_cb_mouse_move(void *data, } new_x = x; new_y = y; - skiplist = eina_list_append(skiplist, bd); - e_resist_container_border_position(bd->zone->container, skiplist, - bd->x, bd->y, bd->w, bd->h, - x, y, bd->w, bd->h, - &new_x, &new_y, &new_w, &new_h); - eina_list_free(skiplist); + + + if(e_config->window_out_of_vscreen_limits_partly) + _e_border_stay_within_container(bd, x, y, &new_x, &new_y); + else + { + skiplist = eina_list_append(skiplist, bd); + e_resist_container_border_position(bd->zone->container, skiplist, + bd->x, bd->y, bd->w, bd->h, + x, y, bd->w, bd->h, + &new_x, &new_y, &new_w, &new_h); + eina_list_free(skiplist); + } bd->shelf_fix.x = 0; bd->shelf_fix.y = 0; bd->shelf_fix.modified = 0; diff --git a/src/bin/e_config.c b/src/bin/e_config.c index 70129d9e3..f8c2026e3 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -838,6 +838,9 @@ e_config_init(void) E_CONFIG_VAL(D, T, desk_auto_switch, INT); + E_CONFIG_VAL(D, T, window_out_of_vscreen_limits, INT); + E_CONFIG_VAL(D, T, window_out_of_vscreen_limits_partly, INT); + E_CONFIG_VAL(D, T, thumb_nice, INT); E_CONFIG_VAL(D, T, menu_favorites_show, INT); @@ -1353,6 +1356,9 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->icon_theme_overrides, 0, 1); E_CONFIG_LIMIT(e_config->remember_internal_windows, 0, 3); E_CONFIG_LIMIT(e_config->desk_auto_switch, 0, 1); + + E_CONFIG_LIMIT(e_config->window_out_of_vscreen_limits, 0, 1); + E_CONFIG_LIMIT(e_config->window_out_of_vscreen_limits_partly, 0, 1); E_CONFIG_LIMIT(e_config->dpms_enable, 0, 1); E_CONFIG_LIMIT(e_config->dpms_standby_enable, 0, 1); diff --git a/src/bin/e_config.h b/src/bin/e_config.h index 1fd91dc3c..77f66bdde 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -251,6 +251,9 @@ struct _E_Config Eina_List *mime_icons; // GUI int desk_auto_switch; // GUI; + + int window_out_of_vscreen_limits; + int window_out_of_vscreen_limits_partly; int thumb_nice; diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 4095d4d66..b839d7590 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -1299,7 +1299,7 @@ _e_int_menus_clients_pre_cb(void *data __UNUSED__, E_Menu *m) e_util_menu_item_theme_icon_set(mi, "preferences-system-windows"); e_menu_item_callback_set(mi, _e_int_menus_clients_cleanup_cb, zone); - if (dat) + if ((dat) && (e_config->window_out_of_vscreen_limits)) { mi = e_menu_item_new(m); e_menu_item_separator_set(mi, 1); diff --git a/src/modules/conf_window_manipulation/e_int_config_window_display.c b/src/modules/conf_window_manipulation/e_int_config_window_display.c index b0bcec595..bd3c3e637 100644 --- a/src/modules/conf_window_manipulation/e_int_config_window_display.c +++ b/src/modules/conf_window_manipulation/e_int_config_window_display.c @@ -21,6 +21,8 @@ struct _E_Config_Dialog_Data int window_placement_policy; int window_grouping; int desk_auto_switch; + int window_out_of_vscreen_limits; + int window_out_of_vscreen_limits_partly; Eina_List *shading_list; }; @@ -67,6 +69,9 @@ _create_data(E_Config_Dialog *cfd __UNUSED__) cfdata->window_grouping = e_config->window_grouping; cfdata->desk_auto_switch = e_config->desk_auto_switch; + cfdata->window_out_of_vscreen_limits = e_config->window_out_of_vscreen_limits; + cfdata->window_out_of_vscreen_limits_partly = e_config->window_out_of_vscreen_limits_partly; + cfdata->border_shade_animate = e_config->border_shade_animate; cfdata->border_shade_transition = e_config->border_shade_transition; cfdata->border_shade_speed = e_config->border_shade_speed; @@ -96,6 +101,9 @@ _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) e_config->use_app_icon = cfdata->use_app_icon; e_config->desk_auto_switch = cfdata->desk_auto_switch; + + e_config->window_out_of_vscreen_limits = cfdata->window_out_of_vscreen_limits; + e_config->window_out_of_vscreen_limits_partly = cfdata->window_out_of_vscreen_limits_partly; e_config_save_queue(); return 1; } @@ -113,7 +121,9 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda (e_config->border_shade_transition != cfdata->border_shade_transition) || (e_config->border_shade_speed != cfdata->border_shade_speed) || (e_config->use_app_icon != cfdata->use_app_icon) || - (e_config->desk_auto_switch != cfdata->desk_auto_switch)); + (e_config->desk_auto_switch != cfdata->desk_auto_switch) || + (e_config->window_out_of_vscreen_limits != cfdata->window_out_of_vscreen_limits) || + (e_config->window_out_of_vscreen_limits_partly != cfdata->window_out_of_vscreen_limits_partly)); } static Evas_Object * @@ -248,6 +258,19 @@ _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data e_widget_on_change_hook_set(oc, _cb_disable_check_list, cfdata->shading_list); + /* Screen Limits */ + ol = e_widget_list_add(evas, 0, 0); + + oc = e_widget_check_add(evas, _("Allow windows out of visual screen limits"), + &(cfdata->window_out_of_vscreen_limits)); + e_widget_list_object_append(ol, oc, 1, 1, 0.5); + + oc = e_widget_check_add(evas, _("Allow windows partly out of screen limits"), + &(cfdata->window_out_of_vscreen_limits_partly)); + e_widget_list_object_append(ol, oc, 1, 1, 0.5); + + e_widget_toolbook_page_append(otb, NULL, _("Screen Limits"), ol, + 0, 0, 1, 0, 0.5, 0.0); e_widget_toolbook_page_show(otb, 0); return otb;