forked from enlightenment/enlightenment
e - randr - handle missing relative display and use priority for zone
this makes highest priority screen the lowest (0) zone. this also handles missing screesn that you are relative "of". missing clones are not working atm. also zone reconfigure moves windows now too
This commit is contained in:
parent
2fe0ac249d
commit
054adb6351
|
@ -4560,35 +4560,114 @@ _e_comp_x_pre_swap(void *data, Evas *e EINA_UNUSED)
|
||||||
c->grabbed = 0;
|
c->grabbed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_e_comp_x_cinerama_screen_sort_cb(const void *data1, const void *data2)
|
||||||
|
{
|
||||||
|
const E_Randr2_Screen *s1 = data1, *s2 = data2;
|
||||||
|
int dif;
|
||||||
|
|
||||||
|
dif = -(s1->config.priority - s2->config.priority);
|
||||||
|
if (dif == 0)
|
||||||
|
{
|
||||||
|
dif = s1->config.geom.x - s2->config.geom.x;
|
||||||
|
if (dif == 0)
|
||||||
|
dif = s1->config.geom.y - s2->config.geom.y;
|
||||||
|
}
|
||||||
|
return dif;
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_e_comp_x_xinerama_setup(int rw, int rh)
|
_e_comp_x_xinerama_setup(int rw, int rh)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
E_Screen *screen;
|
E_Screen *screen;
|
||||||
|
Eina_List *screens = NULL, *screens_rem;
|
||||||
Eina_List *all_screens = NULL;
|
Eina_List *all_screens = NULL;
|
||||||
Eina_List *l;
|
Eina_List *l, *ll;
|
||||||
E_Randr2_Screen *s;
|
E_Randr2_Screen *s, *s2, *s_chosen;
|
||||||
|
Eina_Bool removed;
|
||||||
|
|
||||||
i = 0;
|
// put screens in tmp list
|
||||||
EINA_LIST_FOREACH(e_randr2->screens, l, s)
|
EINA_LIST_FOREACH(e_randr2->screens, l, s)
|
||||||
{
|
{
|
||||||
if ((s->config.enabled) &&
|
if ((s->config.enabled) &&
|
||||||
(s->config.geom.w > 0) &&
|
(s->config.geom.w > 0) &&
|
||||||
(s->config.geom.h > 0))
|
(s->config.geom.h > 0))
|
||||||
{
|
{
|
||||||
screen = E_NEW(E_Screen, 1);
|
screens = eina_list_append(screens, s);
|
||||||
screen->escreen = screen->screen = i;
|
|
||||||
screen->x = s->config.geom.x;
|
|
||||||
screen->y = s->config.geom.y;
|
|
||||||
screen->w = s->config.geom.w;
|
|
||||||
screen->h = s->config.geom.h;
|
|
||||||
all_screens = eina_list_append(all_screens, screen);
|
|
||||||
printf("xinerama screen %i %i %ix%i\n", screen->x, screen->y, screen->w, screen->h);
|
|
||||||
INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i",
|
|
||||||
i, i, screen->w, screen->h, screen->x, screen->y);
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// remove overlapping screens - if a set of screens overlap, keep the
|
||||||
|
// smallest/lowest res
|
||||||
|
do
|
||||||
|
{
|
||||||
|
removed = EINA_FALSE;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(screens, l, s)
|
||||||
|
{
|
||||||
|
screens_rem = NULL;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(l->next, ll, s2)
|
||||||
|
{
|
||||||
|
if (E_INTERSECTS(s->config.geom.x, s->config.geom.y,
|
||||||
|
s->config.geom.w, s->config.geom.h,
|
||||||
|
s2->config.geom.x, s2->config.geom.y,
|
||||||
|
s2->config.geom.w, s2->config.geom.h))
|
||||||
|
{
|
||||||
|
if (!screens_rem)
|
||||||
|
screens_rem = eina_list_append(screens_rem, s);
|
||||||
|
screens_rem = eina_list_append(screens_rem, s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we have intersecting screens - choose the lowest res one
|
||||||
|
if (screens_rem)
|
||||||
|
{
|
||||||
|
removed = EINA_TRUE;
|
||||||
|
// find the smallest screen (chosen one)
|
||||||
|
s_chosen = NULL;
|
||||||
|
EINA_LIST_FOREACH(screens_rem, ll, s2)
|
||||||
|
{
|
||||||
|
if (!s_chosen) s_chosen = s2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((s_chosen->config.geom.w *
|
||||||
|
s_chosen->config.geom.h) >
|
||||||
|
(s2->config.geom.w *
|
||||||
|
s2->config.geom.h))
|
||||||
|
s_chosen = s2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove all from screens but the chosen one
|
||||||
|
EINA_LIST_FREE(screens_rem, s2)
|
||||||
|
{
|
||||||
|
if (s2 != s_chosen)
|
||||||
|
screens = eina_list_remove_list(screens, l);
|
||||||
|
}
|
||||||
|
// break our list walk and try again
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (removed);
|
||||||
|
// sort screens by priority etc.
|
||||||
|
screens = eina_list_sort(screens, eina_list_count(screens),
|
||||||
|
_e_comp_x_cinerama_screen_sort_cb);
|
||||||
|
i = 0;
|
||||||
|
EINA_LIST_FOREACH(screens, l, s)
|
||||||
|
{
|
||||||
|
screen = E_NEW(E_Screen, 1);
|
||||||
|
screen->escreen = screen->screen = i;
|
||||||
|
screen->x = s->config.geom.x;
|
||||||
|
screen->y = s->config.geom.y;
|
||||||
|
screen->w = s->config.geom.w;
|
||||||
|
screen->h = s->config.geom.h;
|
||||||
|
all_screens = eina_list_append(all_screens, screen);
|
||||||
|
printf("xinerama screen %i %i %ix%i\n", screen->x, screen->y, screen->w, screen->h);
|
||||||
|
INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i",
|
||||||
|
i, i, screen->w, screen->h, screen->x, screen->y);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
eina_list_free(screens);
|
||||||
// if we have NO screens at all (above - i will be 0) AND we have no
|
// if we have NO screens at all (above - i will be 0) AND we have no
|
||||||
// existing screens set up in xinerama - then just say root window size
|
// existing screens set up in xinerama - then just say root window size
|
||||||
// is the entire screen. this should handle the case where you unplug ALL
|
// is the entire screen. this should handle the case where you unplug ALL
|
||||||
|
|
|
@ -423,6 +423,7 @@ _config_apply(E_Randr2 *r, E_Config_Randr2 *cfg)
|
||||||
s->config.mode.preferred = EINA_FALSE;
|
s->config.mode.preferred = EINA_FALSE;
|
||||||
s->config.rotation = cs->rotation;
|
s->config.rotation = cs->rotation;
|
||||||
s->config.priority = cs->priority;
|
s->config.priority = cs->priority;
|
||||||
|
printf("RRR: ... priority = %i\n", cs->priority);
|
||||||
free(s->config.relative.to);
|
free(s->config.relative.to);
|
||||||
if (cs->rel_to) s->config.relative.to = strdup(cs->rel_to);
|
if (cs->rel_to) s->config.relative.to = strdup(cs->rel_to);
|
||||||
else s->config.relative.to = NULL;
|
else s->config.relative.to = NULL;
|
||||||
|
@ -659,6 +660,49 @@ _screen_config_takeover(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static E_Config_Randr2_Screen *_config_screen_string_find(E_Config_Randr2 *cfg, const char *id);
|
||||||
|
static E_Randr2_Screen *_screen_fuzzy_fallback_find(E_Config_Randr2 *cfg, const char *id);
|
||||||
|
|
||||||
|
static E_Config_Randr2_Screen *
|
||||||
|
_config_screen_string_find(E_Config_Randr2 *cfg, const char *id)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
E_Config_Randr2_Screen *cs;
|
||||||
|
|
||||||
|
if ((!id) || (!cfg)) return NULL;
|
||||||
|
EINA_LIST_FOREACH(cfg->screens, l, cs)
|
||||||
|
{
|
||||||
|
if (!cs->id) continue;
|
||||||
|
if (!strcmp(cs->id, id)) return cs;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static E_Randr2_Screen *
|
||||||
|
_screen_fuzzy_fallback_find(E_Config_Randr2 *cfg, const char *id)
|
||||||
|
{
|
||||||
|
E_Randr2_Screen *s = NULL;
|
||||||
|
char *p, *name;
|
||||||
|
|
||||||
|
// strip out everythng in the string from / on as that is edid
|
||||||
|
// and fall back to finding just the output name in the rel
|
||||||
|
// to identifier, rather than the specific screen id
|
||||||
|
name = alloca(strlen(id) + 1);
|
||||||
|
strcpy(name, id);
|
||||||
|
if ((p = strchr(name, '/'))) *p = 0;
|
||||||
|
|
||||||
|
s = _screen_id_find(id);
|
||||||
|
if (!s) s = _screen_id_find(name);
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
E_Config_Randr2_Screen *cs;
|
||||||
|
|
||||||
|
cs = _config_screen_string_find(cfg, id);
|
||||||
|
if ((cs) && (cs->id)) return _screen_fuzzy_fallback_find(cfg, cs->id);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
static int _config_do_recurse = 0;
|
static int _config_do_recurse = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -680,18 +724,7 @@ _screen_config_do(E_Randr2_Screen *s)
|
||||||
{
|
{
|
||||||
// if this screen is relative TO something (clone or left/right etc.
|
// if this screen is relative TO something (clone or left/right etc.
|
||||||
// then calculate what it is relative to first
|
// then calculate what it is relative to first
|
||||||
s2 = _screen_id_find(s->config.relative.to);
|
s2 = _screen_fuzzy_fallback_find(e_randr2_cfg, s->config.relative.to);
|
||||||
printf("RRR: '%s' is relative to %p\n", s->info.name, s2);
|
|
||||||
if (!s2)
|
|
||||||
{
|
|
||||||
// strip out everythng in the string from / on as that is edid
|
|
||||||
// and fall back to finding just the output name in the rel
|
|
||||||
// to identifier, rather than the specific screen id
|
|
||||||
char *p, *str = alloca(strlen(s->config.relative.to) + 1);
|
|
||||||
strcpy(str, s->config.relative.to);
|
|
||||||
if ((p = strchr(str, '/'))) *p = 0;
|
|
||||||
s2 = _screen_output_find(str);
|
|
||||||
}
|
|
||||||
printf("RRR: '%s' is relative to %p\n", s->info.name, s2);
|
printf("RRR: '%s' is relative to %p\n", s->info.name, s2);
|
||||||
if (s2) _screen_config_do(s2);
|
if (s2) _screen_config_do(s2);
|
||||||
}
|
}
|
||||||
|
@ -1137,9 +1170,11 @@ _info_get(void)
|
||||||
{
|
{
|
||||||
Ecore_X_Randr_Mode *modes;
|
Ecore_X_Randr_Mode *modes;
|
||||||
Ecore_X_Randr_Edid_Display_Interface_Type conn;
|
Ecore_X_Randr_Edid_Display_Interface_Type conn;
|
||||||
int modes_num = 0, modes_pref = 0;
|
int modes_num = 0, modes_pref = 0, priority;
|
||||||
|
E_Config_Randr2_Screen *cs;
|
||||||
E_Randr2_Screen *s = calloc(1, sizeof(E_Randr2_Screen));
|
E_Randr2_Screen *s = calloc(1, sizeof(E_Randr2_Screen));
|
||||||
if (!s) continue;
|
if (!s) continue;
|
||||||
|
|
||||||
s->info.name = _output_name_get(root, outputs[i]);
|
s->info.name = _output_name_get(root, outputs[i]);
|
||||||
printf("RRR: ...... out %s\n", s->info.name);
|
printf("RRR: ...... out %s\n", s->info.name);
|
||||||
if (!s->info.name)
|
if (!s->info.name)
|
||||||
|
@ -1215,8 +1250,14 @@ _info_get(void)
|
||||||
}
|
}
|
||||||
free(modes);
|
free(modes);
|
||||||
}
|
}
|
||||||
if (ecore_x_randr_primary_output_get(root) == outputs[i])
|
cs = NULL;
|
||||||
s->config.priority = 100;
|
priority = 0;
|
||||||
|
if (e_randr2_cfg) cs = _config_screen_find(s, e_randr2_cfg);
|
||||||
|
if (cs)
|
||||||
|
priority = cs->priority;
|
||||||
|
else if (ecore_x_randr_primary_output_get(root) == outputs[i])
|
||||||
|
priority = 100;
|
||||||
|
s->config.priority = priority;
|
||||||
for (j = 0; j < crtcs_num; j++)
|
for (j = 0; j < crtcs_num; j++)
|
||||||
{
|
{
|
||||||
Eina_Bool ok, possible;
|
Eina_Bool ok, possible;
|
||||||
|
|
|
@ -132,8 +132,6 @@ _e_xinerama_update(void)
|
||||||
INF("======================= screens:");
|
INF("======================= screens:");
|
||||||
EINA_LIST_FOREACH(chosen_screens, l, scr)
|
EINA_LIST_FOREACH(chosen_screens, l, scr)
|
||||||
{
|
{
|
||||||
scr->screen = n;
|
|
||||||
scr->escreen = n;
|
|
||||||
INF("E INIT: XINERAMA CHOSEN: [%i][%i], %ix%i+%i+%i",
|
INF("E INIT: XINERAMA CHOSEN: [%i][%i], %ix%i+%i+%i",
|
||||||
scr->screen, scr->escreen, scr->w, scr->h, scr->x, scr->y);
|
scr->screen, scr->escreen, scr->w, scr->h, scr->x, scr->y);
|
||||||
n++;
|
n++;
|
||||||
|
|
|
@ -270,17 +270,40 @@ e_zone_name_set(E_Zone *zone,
|
||||||
zone->name = eina_stringshare_add(name);
|
zone->name = eina_stringshare_add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy, int dw, int dh)
|
||||||
|
{
|
||||||
|
E_Client *ec;
|
||||||
|
|
||||||
|
E_CLIENT_FOREACH(zone->comp, ec)
|
||||||
|
{
|
||||||
|
if (ec->zone != zone) continue;
|
||||||
|
|
||||||
|
if ((dx != 0) || (dy != 0))
|
||||||
|
evas_object_move(ec->frame, ec->x + dx, ec->y + dy);
|
||||||
|
// we shrank the zone - adjust windows more
|
||||||
|
if ((dw < 0) || (dh < 0))
|
||||||
|
{
|
||||||
|
e_client_res_change_geometry_save(ec);
|
||||||
|
e_client_res_change_geometry_restore(ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
e_zone_move(E_Zone *zone,
|
e_zone_move(E_Zone *zone,
|
||||||
int x,
|
int x,
|
||||||
int y)
|
int y)
|
||||||
{
|
{
|
||||||
E_Event_Zone_Move_Resize *ev;
|
E_Event_Zone_Move_Resize *ev;
|
||||||
|
int dx, dy;
|
||||||
|
|
||||||
E_OBJECT_CHECK(zone);
|
E_OBJECT_CHECK(zone);
|
||||||
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
|
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
|
||||||
|
|
||||||
if ((x == zone->x) && (y == zone->y)) return;
|
if ((x == zone->x) && (y == zone->y)) return;
|
||||||
|
dx = x - zone->x;
|
||||||
|
dy = y - zone->y;
|
||||||
zone->x = x;
|
zone->x = x;
|
||||||
zone->y = y;
|
zone->y = y;
|
||||||
evas_object_move(zone->bg_object, x, y);
|
evas_object_move(zone->bg_object, x, y);
|
||||||
|
@ -294,6 +317,7 @@ e_zone_move(E_Zone *zone,
|
||||||
|
|
||||||
_e_zone_edge_move_resize(zone);
|
_e_zone_edge_move_resize(zone);
|
||||||
e_zone_bg_reconfigure(zone);
|
e_zone_bg_reconfigure(zone);
|
||||||
|
e_zone_reconfigure_clients(zone, dx, dy, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
@ -302,11 +326,15 @@ e_zone_resize(E_Zone *zone,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
E_Event_Zone_Move_Resize *ev;
|
E_Event_Zone_Move_Resize *ev;
|
||||||
|
int dw, dh;
|
||||||
|
|
||||||
E_OBJECT_CHECK(zone);
|
E_OBJECT_CHECK(zone);
|
||||||
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
|
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
|
||||||
|
|
||||||
if ((w == zone->w) && (h == zone->h)) return;
|
if ((w == zone->w) && (h == zone->h)) return;
|
||||||
|
|
||||||
|
dw = w - zone->w;
|
||||||
|
dh = h - zone->h;
|
||||||
zone->w = w;
|
zone->w = w;
|
||||||
zone->h = h;
|
zone->h = h;
|
||||||
evas_object_resize(zone->bg_object, w, h);
|
evas_object_resize(zone->bg_object, w, h);
|
||||||
|
@ -321,6 +349,7 @@ e_zone_resize(E_Zone *zone,
|
||||||
|
|
||||||
_e_zone_edge_move_resize(zone);
|
_e_zone_edge_move_resize(zone);
|
||||||
e_zone_bg_reconfigure(zone);
|
e_zone_bg_reconfigure(zone);
|
||||||
|
e_zone_reconfigure_clients(zone, 0, 0, dw, dh);
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
|
@ -331,6 +360,7 @@ e_zone_move_resize(E_Zone *zone,
|
||||||
int h)
|
int h)
|
||||||
{
|
{
|
||||||
E_Event_Zone_Move_Resize *ev;
|
E_Event_Zone_Move_Resize *ev;
|
||||||
|
int dx, dy, dw, dh;
|
||||||
|
|
||||||
E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
|
E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
|
||||||
E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
|
E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
|
||||||
|
@ -338,6 +368,10 @@ e_zone_move_resize(E_Zone *zone,
|
||||||
if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
|
if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
dx = x - zone->x;
|
||||||
|
dy = y - zone->y;
|
||||||
|
dw = w - zone->w;
|
||||||
|
dh = h - zone->h;
|
||||||
zone->x = x;
|
zone->x = x;
|
||||||
zone->y = y;
|
zone->y = y;
|
||||||
zone->w = w;
|
zone->w = w;
|
||||||
|
@ -357,8 +391,8 @@ e_zone_move_resize(E_Zone *zone,
|
||||||
_e_zone_event_generic_free, NULL);
|
_e_zone_event_generic_free, NULL);
|
||||||
|
|
||||||
_e_zone_edge_move_resize(zone);
|
_e_zone_edge_move_resize(zone);
|
||||||
|
|
||||||
e_zone_bg_reconfigure(zone);
|
e_zone_bg_reconfigure(zone);
|
||||||
|
e_zone_reconfigure_clients(zone, dx, dy, dw, dh);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue