e - randr - laptop lids - handle plug/unplug and well as lid open/close

this fixes some issues in the new randr2 code that made it not work
right with plug/unplug and lid close/open. now it does work right and
plugging/unplugging displays is seamless (if your driver does not give
plug/unplug events bind a key to update screen config acvtion and e
will figure it out when you hit the key).
This commit is contained in:
Carsten Haitzler 2015-02-09 17:43:17 +09:00
parent 96b3a04192
commit 790183d74a
7 changed files with 75 additions and 10 deletions

View File

@ -851,6 +851,7 @@ _e_comp_screensaver_on(void *data EINA_UNUSED, int type EINA_UNUSED, void *event
Eina_List *l;
E_Zone *zone;
printf("_e_comp_screensaver_on\n");
ecore_frametime = ecore_animator_frametime_get();
if (e_comp->saver) return ECORE_CALLBACK_RENEW;
e_comp_override_add(e_comp);
@ -874,6 +875,7 @@ _e_comp_screensaver_off(void *data EINA_UNUSED, int type EINA_UNUSED, void *even
E_Zone *zone;
E_Client *ec;
printf("_e_comp_screensaver_off\n");
ecore_animator_frametime_set(ecore_frametime);
if (!e_comp->saver) return ECORE_CALLBACK_RENEW;
e_comp_override_del(e_comp);

View File

@ -346,17 +346,24 @@ e_comp_canvas_update(void)
{
zones = e_comp->zones;
e_comp->zones = NULL;
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
EINA_LIST_FOREACH(screens, l, scr)
{
zone = NULL;
printf("@ match screens %p[%i] = %i %i %ix%i -- %i\n",
scr, scr->escreen, scr->x, scr->y, scr->w, scr->h, scr->escreen);
EINA_LIST_FOREACH(zones, ll, zone)
{
if (zone->id == scr->escreen) break;
zone = NULL;
}
printf("@ matches existing zone %p\n", zone);
if (zone)
{
printf(" move resize %i %i %ix%i -> %i %i %ix%i\n",
zone->x, zone->y, zone->w, zone->h,
scr->x, scr->y, scr->w, scr->h);
changed |= e_zone_move_resize(zone, scr->x, scr->y, scr->w, scr->h);
if (changed)
printf("@@@ FOUND ZONE %i %i [%p]\n", zone->num, zone->id, zone);
@ -380,6 +387,7 @@ e_comp_canvas_update(void)
{
E_Zone *spare_zone;
printf("@zones have been deleted....\n");
changed = EINA_TRUE;
spare_zone = eina_list_data_get(e_comp->zones);
@ -387,6 +395,7 @@ e_comp_canvas_update(void)
{
E_Client *ec;
printf("reassign all clients from deleted zone %p\n", zone);
E_CLIENT_FOREACH(e_comp, ec)
{
if (ec->zone == zone)

View File

@ -4585,15 +4585,21 @@ _e_comp_x_xinerama_setup(int rw, int rh)
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++;
}
}
// XXX: what if we have zero screens? all unplugged? need to flag this
// keep all screens as-is for now and mark comp to hide everything
// and wait for a screen to come back
if (i == 0)
// 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
// is the entire screen. this should handle the case where you unplug ALL
// screens from an existing setup (unplug external monitors and/or close
// laptop lid), in which case as long as at least one screen is configured
// in xinerama, it will be left-as is until next time we re-eval screen
// setup and have at least one screen
printf("xinerama setup............... %i %p\n", i, e_xinerama_screens_all_get());
if ((i == 0) && (!e_xinerama_screens_all_get()))
{
screen = E_NEW(E_Screen, 1);
screen->escreen = screen->screen = 0;

View File

@ -186,8 +186,13 @@ static Evas_Object *_fade_obj = NULL;
static Eina_Bool
_screen_closed(E_Randr2_Screen *s)
{
printf("RRR: check lid for %s...\n", s->info.name);
if (!_lid_is_closed) return EINA_FALSE;
if (s->info.is_lid) return EINA_TRUE;
if (s->info.is_lid)
{
printf("RRR: is closed lid\n");
return EINA_TRUE;
}
return EINA_FALSE;
}
@ -510,6 +515,8 @@ _screens_fingerprint(E_Randr2 *r)
eina_strbuf_append(buf, ":");
eina_strbuf_append(buf, s->id);
eina_strbuf_append(buf, ":");
if (s->info.lid_closed) eina_strbuf_append(buf, ":LC:");
else eina_strbuf_append(buf, ":LO:");
}
}
str = eina_strbuf_string_steal(buf);
@ -529,7 +536,9 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2)
s1 = _screens_fingerprint(r1);
s2 = _screens_fingerprint(r2);
if ((!s1) && (!s2)) return EINA_FALSE;
printf("RRR: check fingerprint...\n");
if ((s1) && (s2) && (strcmp(s1, s2))) changed = EINA_TRUE;
printf("RRR: ... fingerprint says %i\n", changed);
free(s1);
free(s2);
// check screen config
@ -549,9 +558,11 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2)
(s->config.mode.w != ss->config.mode.w) ||
(s->config.mode.h != ss->config.mode.h) ||
(s->config.enabled != ss->config.enabled) ||
(s->config.rotation != ss->config.rotation))
(s->config.rotation != ss->config.rotation) ||
(s->info.lid_closed != ss->info.lid_closed))
changed = EINA_TRUE;
}
printf("RRR: changed = %i\n", changed);
return changed;
}
@ -559,6 +570,7 @@ static Eina_Bool
_cb_screen_change_delay(void *data EINA_UNUSED)
{
_screen_delay_timer = NULL;
printf("RRR: ... %i %i\n", event_screen, event_ignore);
// if we had a screen plug/unplug etc. event and we shouldnt ignore it...
if ((event_screen) && (!event_ignore))
{
@ -572,6 +584,7 @@ _cb_screen_change_delay(void *data EINA_UNUSED)
if (_screens_differ(e_randr2, rtemp)) change = EINA_TRUE;
_info_free(rtemp);
}
printf("RRR: change = %i\n", change);
// we plugged or unplugged some monitor - re-apply config so
// known screens can be coonfigured
if (change) e_randr2_config_apply();
@ -600,10 +613,13 @@ _cb_acpi(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
E_Event_Acpi *ev = event;
Eina_Bool lid_closed;
printf("RRR: acpi event\n");
if (ev->type != E_ACPI_TYPE_LID) return EINA_TRUE;
lid_closed = (ev->status == E_ACPI_LID_CLOSED);
if (lid_closed == _lid_is_closed) return EINA_TRUE;
printf("RRR: lid event for lid %i\n", lid_closed);
_lid_is_closed = lid_closed;
event_screen = EINA_TRUE;
_screen_change_delay();
return EINA_TRUE;
}
@ -650,12 +666,13 @@ _screen_config_do(E_Randr2_Screen *s)
{
E_Randr2_Screen *s2 = NULL;
_config_do_recurse++;
if (_config_do_recurse > 20)
printf("RRR: screen do '%s'\n", s->info.name);
if (_config_do_recurse > 10)
{
ERR("screen config loop!");
return;
}
_config_do_recurse++;
// if screen has a dependency...
if ((s->config.relative.mode != E_RANDR2_RELATIVE_UNKNOWN) &&
(s->config.relative.mode != E_RANDR2_RELATIVE_NONE) &&
@ -737,6 +754,7 @@ _screen_config_do(E_Randr2_Screen *s)
s->config.geom.y = s2->config.geom.y + s2->config.geom.h;
}
}
_config_do_recurse--;
}
static void
@ -1159,6 +1177,8 @@ _info_get(void)
else if (conn == ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT)
s->info.connector = E_RANDR2_CONNECTOR_DISPLAY_PORT;
s->info.is_lid = _is_lid_name(s->info.name);
s->info.lid_closed = s->info.is_lid && _lid_is_closed;
printf("RRR: .... lid_closed = %i (%i && %i)\n", s->info.lid_closed, s->info.is_lid, _lid_is_closed);
if (ecore_x_randr_output_connection_status_get(root, outputs[i]) ==
ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
s->info.connected = EINA_TRUE;
@ -1413,7 +1433,7 @@ _screen_config_apply(void)
Ecore_X_Randr_Crtc *crtcs = NULL;
Ecore_X_Randr_Output *outputs = NULL, out, *outconf;
E_Randr2_Screen **screenconf;
int crtcs_num = 0, outputs_num = 0, i;
int crtcs_num = 0, outputs_num = 0, i, numout;
Ecore_X_Randr_Crtc_Info *info;
int top_priority = 0;
@ -1492,6 +1512,13 @@ _screen_config_apply(void)
}
}
}
numout = 0;
for (i = 0; i < crtcs_num; i++)
{
if (outconf[i]) numout++;
}
if (numout)
{
// set up a crtc to drive each output (or not)
for (i = 0; i < crtcs_num; i++)
{
@ -1544,20 +1571,34 @@ _screen_config_apply(void)
ECORE_X_RANDR_ORIENTATION_ROT_0);
}
}
}
else
{
printf("RRR: EERRRRRROOOORRRRRRR no outputs to configure!\n");
}
}
free(outputs);
free(crtcs);
printf("RRR: set vsize: %ix%i\n", nw, nh);
ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1);
{
int ww = 0, hh = 0, ww2 = 0, hh2 = 0;
ecore_x_randr_screen_current_size_get(root, &ww, &hh, &ww2, &hh2);
printf("RRR: cur size: %ix%i\n", ww, hh);
// ecore_x_randr_screen_reset(root);
// ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1);
// ecore_x_sync();
// ecore_x_randr_screen_current_size_get(root, &ww, &hh, &ww2, &hh2);
// printf("RRR: cur size: %ix%i\n", ww, hh);
}
ecore_x_randr_screen_size_range_get(root, NULL, NULL, NULL, NULL);
ecore_x_ungrab();
ecore_x_sync();
// ignore the next batch of randr events - we caused them ourselves
event_ignore = EINA_TRUE;
// XXX: a problem. thew first time we configure the screen we may not
// get any events back to clear the ignore flag below, so only apply
// here if the randr config now doesnt match what we want to set up.
// event_ignore = EINA_TRUE;
}

View File

@ -59,6 +59,7 @@ struct _E_Randr2_Screen
char *edid; // full edid data
E_Randr2_Connector connector; // the connector type
Eina_Bool is_lid : 1; // is an internal screen
Eina_Bool lid_closed : 1; // is lid closed when screen qury'd
Eina_Bool connected : 1; // some screen is plugged in or not
Eina_Bool backlight : 1; // does it have backlight controls?
Eina_Bool can_rot_0 : 1; // can it do this rotation?

View File

@ -114,6 +114,7 @@ _e_sys_comp_emit_cb_wait(E_Sys_Action a, const char *sig, const char *rep, Eina_
if (nocomp_push) e_comp_override_add(e_comp);
else e_comp_override_timed_pop(e_comp);
printf("_e_sys_comp_emit_cb_wait - [%x] %s %s\n", a, sig, rep);
EINA_LIST_FOREACH(e_comp->zones, l, zone)
{
e_zone_fade_handle(zone, nocomp_push, 0.5);

View File

@ -378,6 +378,7 @@ _cb_rel_to_set(void *data, Evas_Object *obj, void *event)
E_Randr2_Screen *s = _screen_config_id_find(cs2->id);
if (s)
{
printf("SEt to %p [%s]\n", cs, cs->id);
printf("find s = %p\n", s);
printf("s id = %s\n", s->id);
elm_object_text_set(obj, s->info.name);
@ -710,9 +711,11 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
E_Config_Randr2_Screen *cs, *cs2;
e_randr2_cfg->restore = cfdata->restore;
printf("APPLY....................\n");
EINA_LIST_FOREACH(cfdata->screens, l, cs2)
{
if (!cs2->id) continue;
printf("APPLY .... %p\n", cs2);
cs = _screen_config_randr_id_find(cs2->id);
if (!cs)
{
@ -722,6 +725,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
}
if (cs->rel_to) eina_stringshare_del(cs->rel_to);
cs->rel_to = NULL;
printf("APPLY %s .... rel to %s\n", cs->id, cs2->rel_to);
if (cs2->rel_to) cs->rel_to = eina_stringshare_add(cs2->rel_to);
cs->rel_align = cs2->rel_align;
cs->mode_refresh = cs2->mode_refresh;
@ -731,6 +735,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
cs->rotation = cs2->rotation;
cs->priority = cs2->priority;
cs->rel_mode = cs2->rel_mode;
printf("APPLY %s .... rel mode %i\n", cs->id, cs->rel_mode);
cs->enabled = cs2->enabled;
}
e_randr2_config_save();