patch from Deon Thomas to fix lost window warp behavior

ticket #1680


SVN revision: 78693
This commit is contained in:
Mike Blumenkrantz 2012-10-31 08:44:50 +00:00
parent 7826261e19
commit 64fc140c78
6 changed files with 155 additions and 86 deletions

View File

@ -209,7 +209,7 @@ 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_move_lost_window_to_center(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 */
@ -1424,9 +1424,6 @@ 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);
}
/**
@ -3497,6 +3494,12 @@ e_border_idler_before(void)
_e_border_show(bd);
bd->changes.visible = 0;
}
if((bd->changed) && (bd->zone))
{
if(e_config->screen_limits == E_SCREEN_LIMITS_PARTLY)
_e_border_move_lost_window_to_center(bd);
}
}
e_container_border_list_free(bl);
@ -4315,59 +4318,117 @@ e_border_lost_windows_get(E_Zone *zone)
return list;
}
static Eina_Bool
_e_border_lost_window_internal_get(E_Border *bd)
static void
_e_border_zones_layout_calc(E_Border *bd, int *zx, int *zy, int *zw, int *zh)
{
int x, y, w, h;
E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
x = bd->zone->x;
y = bd->zone->y;
w = bd->zone->w;
h = bd->zone->h;
if (eina_list_count(bd->zone->container->zones) == 1)
{
if (zx) *zx = x;
if (zy) *zy = y;
if (zw) *zw = w;
if (zh) *zh = h;
return;
}
zone_left = e_container_zone_at_point_get(bd->zone->container, (x - w + 5), y);
zone_right = e_container_zone_at_point_get(bd->zone->container, (x + w + 5), y);
zone_above = e_container_zone_at_point_get(bd->zone->container, x, (y - h + 5));
zone_below = e_container_zone_at_point_get(bd->zone->container, x, (y + h + 5));
if (!(zone_above) && (y))
zone_above = e_container_zone_at_point_get(bd->zone->container, x, (h - 5));
if (!(zone_left) &&(x))
zone_left = e_container_zone_at_point_get(bd->zone->container, (x - 5), y);
if (zone_right)
w = zone_right->x + zone_right->w;
if (zone_left)
w = bd->zone->x + bd->zone->w;
if (zone_below)
h = zone_below->y + zone_below->h;
if (zone_above)
h = bd->zone->y + bd->zone->h;
if ((zone_left) && (zone_right))
w = bd->zone->w + zone_right->x;
if ((zone_above) && (zone_below))
h = bd->zone->h + zone_below->y;
if (x) x -= bd->zone->w;
if (y) y -= bd->zone->h;
if (zx) *zx = x > 0 ? x : 0;
if (zy) *zy = y > 0 ? y : 0;
if (zw) *zw = w;
if (zh) *zh = h;
}
static void
_e_border_move_lost_window_to_center(E_Border *bd)
{
int loss_overlap = 5;
int zw, zh, zx, zy;
if (bd->during_lost) return EINA_FALSE;
if (e_config->window_out_of_vscreen_limits) return EINA_FALSE;
if (!(bd->zone))
return EINA_FALSE;
if (bd->during_lost) return;
if (!(bd->zone)) return;
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),
_e_border_zones_layout_calc(bd, &zx, &zy, &zw, &zh);
if (!E_INTERSECTS(zx + loss_overlap,
zy + loss_overlap,
zw - (2 * loss_overlap),
zh - (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)
if (e_config->edge_flip_dragging || bd->zone->flip.switching)
{
int ok;
Eina_Bool lf, rf, tf, bf;
ok = 0;
for (i = 0; i < num; i++)
lf = rf = tf = bf = EINA_TRUE;
if (bd->zone->desk_x_count <= 1) lf = rf = EINA_FALSE;
else if (!e_config->desk_flip_wrap)
{
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;
}
if (bd->zone->desk_x_current == 0) lf = EINA_FALSE;
if (bd->zone->desk_x_current == (bd->zone->desk_x_count - 1)) rf = EINA_FALSE;
}
free(rect);
if (!ok)
return EINA_TRUE;
}
}
return EINA_FALSE;
if (bd->zone->desk_y_count <= 1) tf = bf = EINA_FALSE;
else if (!e_config->desk_flip_wrap)
{
if (bd->zone->desk_y_current == 0) tf = EINA_FALSE;
if (bd->zone->desk_y_current == (bd->zone->desk_y_count - 1)) bf = EINA_FALSE;
}
if (!(lf) && (bd->x <= loss_overlap))
_e_border_reset_lost_window(bd);
if (!(rf) && (bd->x >= (bd->zone->w - loss_overlap)))
_e_border_reset_lost_window(bd);
if (!(tf) && (bd->y <= loss_overlap))
_e_border_reset_lost_window(bd);
if (!(bf) && (bd->y >= (bd->zone->h - loss_overlap)))
_e_border_reset_lost_window(bd);
}
if (!e_config->edge_flip_dragging)
_e_border_reset_lost_window(bd);
}
}
static void
@ -5575,9 +5636,6 @@ _e_border_cb_window_property(void *data __UNUSED__,
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) &&
@ -6666,13 +6724,23 @@ 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;
int zw, zh;
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(!bd->zone)
{
if (new_x) *new_x = x;
if (new_y) *new_y = y;
return;
}
_e_border_zones_layout_calc(bd, NULL, NULL, &zw, &zh);
new_x_max = zw - bd->w;
new_y_max = zh - bd->h;
lw = bd->w > zw ? EINA_TRUE : EINA_FALSE;
lh = bd->h > zh ? EINA_TRUE : EINA_FALSE;
if (lw)
{
if (x <= new_x_max)
@ -6748,17 +6816,16 @@ _e_border_cb_mouse_move(void *data,
new_x = x;
new_y = y;
if (e_config->window_out_of_vscreen_limits_partly)
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->screen_limits == E_SCREEN_LIMITS_WITHIN)
_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

@ -1,5 +1,12 @@
#ifdef E_TYPEDEFS
typedef enum _E_Screen_Limits
{
E_SCREEN_LIMITS_PARTLY = 0,
E_SCREEN_LIMITS_COMPLETELY = 1,
E_SCREEN_LIMITS_WITHIN = 2
} E_Screen_Limits;
typedef enum _E_Icon_Preference
{
E_ICON_PREF_E_DEFAULT,

View File

@ -840,8 +840,7 @@ 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, screen_limits, INT);
E_CONFIG_VAL(D, T, thumb_nice, INT);
@ -1364,8 +1363,7 @@ e_config_load(void)
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->screen_limits, 0, 2);
E_CONFIG_LIMIT(e_config->dpms_enable, 0, 1);
E_CONFIG_LIMIT(e_config->dpms_standby_enable, 0, 1);

View File

@ -37,7 +37,7 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme;
/* increment this whenever a new set of config values are added but the users
* config doesn't need to be wiped - simply new values need to be put in
*/
#define E_CONFIG_FILE_GENERATION 0x0160
#define E_CONFIG_FILE_GENERATION 0x0161
#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION)
struct _E_Config
@ -254,8 +254,7 @@ 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 screen_limits;
int thumb_nice;

View File

@ -1339,7 +1339,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) && (e_config->window_out_of_vscreen_limits))
if ((dat) && (e_config->screen_limits == E_SCREEN_LIMITS_COMPLETELY))
{
mi = e_menu_item_new(m);
e_menu_item_separator_set(mi, 1);

View File

@ -21,8 +21,7 @@ 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;
int screen_limits;
Eina_List *shading_list;
};
@ -69,8 +68,7 @@ _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->screen_limits = e_config->screen_limits;
cfdata->border_shade_animate = e_config->border_shade_animate;
cfdata->border_shade_transition = e_config->border_shade_transition;
@ -101,9 +99,7 @@ _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->screen_limits = cfdata->screen_limits;
e_config_save_queue();
return 1;
}
@ -122,8 +118,7 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda
(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->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->screen_limits != cfdata->screen_limits);
}
static Evas_Object *
@ -261,13 +256,16 @@ _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data
/* 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);
rg = e_widget_radio_group_new(&(cfdata->screen_limits));
oc = e_widget_check_add(evas, _("Keep windows within the visual screen limits"),
&(cfdata->window_out_of_vscreen_limits_partly));
e_widget_list_object_append(ol, oc, 1, 1, 0.5);
ow = e_widget_radio_add(evas, _("Keep windows within the visual screen limits"), E_SCREEN_LIMITS_WITHIN, rg);
e_widget_list_object_append(ol, ow, 1, 1, 0.5);
ow = e_widget_radio_add(evas, _("Allow windows partly out of the visual screen limits"), E_SCREEN_LIMITS_PARTLY, rg);
e_widget_list_object_append(ol, ow, 1, 1, 0.5);
ow = e_widget_radio_add(evas, _("Allow windows completely out of visual screen limits"), E_SCREEN_LIMITS_COMPLETELY, rg);
e_widget_list_object_append(ol, ow, 1, 1, 0.5);
e_widget_toolbook_page_append(otb, NULL, _("Screen Limits"), ol,
0, 0, 1, 0, 0.5, 0.0);