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
This commit is contained in:
Mike Blumenkrantz 2012-10-11 12:53:15 +00:00
parent 888e820aca
commit c094541aef
5 changed files with 179 additions and 8 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;