randr - add option to ignore disconnects on specific screens...

work around kvm's that like to disconenct screens... be able to force
an ignore on disconnects on specific screens.
This commit is contained in:
Carsten Haitzler 2020-06-15 22:27:34 +01:00
parent c4ab23511e
commit b55fa736ed
4 changed files with 96 additions and 15 deletions

View File

@ -724,6 +724,7 @@ e_comp_x_randr_create(void)
E_Randr2_Screen *s = calloc(1, sizeof(E_Randr2_Screen));
if (!s) continue;
printf("RRR: NEW SCREEN ...\n");
s->info.name = _output_name_get(root, outputs[i]);
printf("RRR: .... out %s\n", s->info.name);
if (!s->info.name)

View File

@ -72,6 +72,7 @@ e_randr2_init(void)
E_CONFIG_VAL(D, T, priority, INT);
E_CONFIG_VAL(D, T, rel_mode, UCHAR);
E_CONFIG_VAL(D, T, enabled, UCHAR);
E_CONFIG_VAL(D, T, ignore_disconnect, UCHAR);
E_CONFIG_VAL(D, T, profile, STR);
E_CONFIG_VAL(D, T, scale_multiplier, DOUBLE);
@ -154,12 +155,46 @@ e_randr2_config_apply(void)
_animated_apply();
}
static E_Randr2_Screen *
_randr_screen_find(E_Randr2 *r, E_Randr2_Screen *src)
{
Eina_List *l;
E_Randr2_Screen *s;
EINA_LIST_FOREACH(r->screens, l, s)
{
if ((s->info.name) && (src->info.name) &&
(!strcmp(s->info.name, src->info.name)))
return s;
}
return NULL;
}
static void
_randr_screen_props_copyover(E_Randr2 *rold, E_Randr2 *rnew)
{
Eina_List *l;
E_Randr2_Screen *s, *s2;
// copy s->config.ignore_disconnect over from tr to e_randr2
EINA_LIST_FOREACH(rnew->screens, l, s)
{
s2 = _randr_screen_find(rold, s);
if (s2) s->config.ignore_disconnect = s2->config.ignore_disconnect;
}
}
E_API void
e_randr2_screeninfo_update(void)
{
E_Randr2 *tr = e_randr2;
// re-fetch/update current screen info
_info_free(e_randr2);
e_randr2 = e_comp->screen->create();
if ((tr) && (e_randr2))
{
_randr_screen_props_copyover(tr, e_randr2);
_info_free(tr);
}
_screen_config_maxsize();
}
@ -265,10 +300,16 @@ _animated_apply(void)
static void
_do_apply(void)
{
E_Randr2 *tr = e_randr2;
// take current screen config and apply it to the driver
printf("RRR: re-get info before applying..\n");
_info_free(e_randr2);
tr = e_randr2;
e_randr2 = e_comp->screen->create();
if ((tr) && (e_randr2))
{
_randr_screen_props_copyover(tr, e_randr2);
_info_free(tr);
}
_screen_config_maxsize();
printf("RRR: apply config...\n");
_config_apply(e_randr2, e_randr2_cfg);
@ -381,8 +422,13 @@ _config_update(E_Randr2 *r, E_Config_Randr2 *cfg, Eina_Bool update_only)
printf("--------------------------------------------------\n");
EINA_LIST_FOREACH(r->screens, l, s)
{
printf("RRR: out id=%s: connected=%i\n", s->id, s->info.connected);
if ((!s->id) || (!s->info.connected) || (_screen_closed(s))) continue;
printf("RRR: out id=%s: connected=%i enabled=%i configured=%i\n",
s->id, s->info.connected,
s->config.enabled, s->config.configured);
if (!s->id) continue;
if (!s->info.connected) continue;
if (_screen_closed(s)) continue;
cs = e_randr2_config_screen_find(s, cfg);
if (cs && update_only) continue;
if (!cs)
@ -469,6 +515,7 @@ _config_update(E_Randr2 *r, E_Config_Randr2 *cfg, Eina_Bool update_only)
}
printf("RRR: store scale mul %1.5f\n", cs->scale_multiplier);
s->config.scale_multiplier = cs->scale_multiplier;
s->config.ignore_disconnect = cs->ignore_disconnect;
ret = EINA_TRUE;
}
}
@ -498,6 +545,8 @@ _config_really_apply(E_Randr2_Screen *s, E_Config_Randr2_Screen *cs)
if (cs->profile) s->config.profile = strdup(cs->profile);
else s->config.profile = NULL;
s->config.scale_multiplier = cs->scale_multiplier;
s->config.ignore_disconnect = cs->ignore_disconnect;
printf("RRR: really apply '%s' ignore discon %i\n", s->info.name, s->config.ignore_disconnect);
}
else
{
@ -519,6 +568,7 @@ _config_really_apply(E_Randr2_Screen *s, E_Config_Randr2_Screen *cs)
free(s->config.profile);
s->config.profile = NULL;
s->config.scale_multiplier = 0.0;
s->config.ignore_disconnect = EINA_FALSE;
}
}
@ -546,7 +596,10 @@ _config_apply(E_Randr2 *r, E_Config_Randr2 *cfg)
else
{
printf("RRR: ... disabled\n");
if (!s->config.ignore_disconnect)
_config_really_apply(s, NULL);
else
printf("RRR: ... ignore disconnected\n");
}
s->config.configured = EINA_TRUE;
}
@ -734,6 +787,7 @@ _cb_screen_change_delay(void *data EINA_UNUSED)
rtemp = e_comp->screen->create();
if (rtemp)
{
if (e_randr2) _randr_screen_props_copyover(e_randr2, rtemp);
if (_screens_differ(e_randr2, rtemp)) change = EINA_TRUE;
if (e_randr2_cfg->default_policy != E_RANDR2_POLICY_NONE)
{
@ -752,7 +806,7 @@ _cb_screen_change_delay(void *data EINA_UNUSED)
{
printf("RRR: is lid, lid++\n");
lid_screens++;
if (s->info.lid_closed)
if ((s->info.lid_closed) && (!s->config.ignore_disconnect))
{
printf("RRR: is lid, is closed, closed++\n");
close_lid_screens++;

View File

@ -87,6 +87,7 @@ struct _E_Randr2_Screen
int priority; // larger num == more important
Eina_Bool enabled E_BITFIELD; // should this monitor be enabled?
Eina_Bool configured E_BITFIELD; // has screen been configured by e?
Eina_Bool ignore_disconnect E_BITFIELD; // ignore disconnects for this screen...
char *profile; // profile name to use on this screen
double scale_multiplier; // if 0.0 - then dont multiply scale
@ -115,6 +116,7 @@ struct _E_Config_Randr2_Screen
int priority;
unsigned char rel_mode;
unsigned char enabled;
unsigned char ignore_disconnect;
const char *profile;
double scale_multiplier;

View File

@ -19,6 +19,7 @@ struct _E_Config_Dialog_Data
Evas_Object *modes_obj;
Evas_Object *rotations_obj;
Evas_Object *enabled_obj;
Evas_Object *ignore_disconnect_obj;
Evas_Object *priority_obj;
Evas_Object *rel_mode_obj;
Evas_Object *rel_to_obj;
@ -442,6 +443,7 @@ _basic_screen_info_fill(E_Config_Dialog_Data *cfdata, E_Config_Randr2_Screen *cs
elm_list_go(cfdata->rotations_obj);
elm_check_state_set(cfdata->enabled_obj, cs->enabled);
elm_check_state_set(cfdata->ignore_disconnect_obj, cs->ignore_disconnect);
elm_slider_value_set(cfdata->priority_obj, cs->priority);
@ -745,6 +747,17 @@ _cb_enabled_changed(void *data, Evas_Object *obj, void *event EINA_UNUSED)
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_cb_ignore_disconnect_changed(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata = data;
E_Config_Randr2_Screen *cs = _config_screen_find(cfdata);
if (!cs) return;
cs->ignore_disconnect = elm_check_state_get(obj);
printf("RR: ignore_disconnect = %i\n", cs->ignore_disconnect);
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
}
static void
_policy_text_update(E_Config_Dialog_Data *cfdata)
{
@ -861,6 +874,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
cs->priority = s->config.priority;
cs->rel_mode = s->config.relative.mode;
cs->enabled = s->config.enabled;
cs->ignore_disconnect = s->config.ignore_disconnect;
if (s->config.profile)
cs->profile = eina_stringshare_add(s->config.profile);
cs->scale_multiplier = s->config.scale_multiplier;
@ -965,6 +979,15 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
evas_object_smart_callback_add(o, "changed", _cb_enabled_changed, cfdata);
cfdata->enabled_obj = o;
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, _("Ignore Disconnect"));
elm_table_pack(tb, o, 2, 5, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_ignore_disconnect_changed, cfdata);
cfdata->ignore_disconnect_obj = o;
o = elm_slider_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
@ -972,7 +995,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
elm_slider_unit_format_set(o, "%3.0f");
elm_slider_span_size_set(o, 100);
elm_slider_min_max_set(o, 0, 100);
elm_table_pack(tb, o, 2, 5, 1, 1);
elm_table_pack(tb, o, 2, 6, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_priority_changed, cfdata);
cfdata->priority_obj = o;
@ -987,7 +1010,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
elm_hoversel_item_add(o, _("Right of"), NULL, ELM_ICON_NONE, _cb_rel_mode_right_of, cfdata);
elm_hoversel_item_add(o, _("Above"), NULL, ELM_ICON_NONE, _cb_rel_mode_above, cfdata);
elm_hoversel_item_add(o, _("Below"), NULL, ELM_ICON_NONE, _cb_rel_mode_below, cfdata);
elm_table_pack(tb, o, 2, 6, 1, 1);
elm_table_pack(tb, o, 2, 7, 1, 1);
evas_object_show(o);
cfdata->rel_mode_obj = o;
@ -1007,7 +1030,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
cfdata->screen_items2 = eina_list_append(cfdata->screen_items2, it);
}
}
elm_table_pack(tb, o, 2, 7, 1, 1);
elm_table_pack(tb, o, 2, 8, 1, 1);
evas_object_show(o);
cfdata->rel_to_obj = o;
@ -1018,7 +1041,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
elm_slider_unit_format_set(o, "%1.1f");
elm_slider_span_size_set(o, 100);
elm_slider_min_max_set(o, 0.0, 1.0);
elm_table_pack(tb, o, 2, 8, 1, 1);
elm_table_pack(tb, o, 2, 9, 1, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed", _cb_rel_align_changed, cfdata);
cfdata->rel_align_obj = o;
@ -1028,14 +1051,14 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
elm_separator_horizontal_set(o, EINA_TRUE);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_table_pack(tb, o, 2, 9, 1, 1);
elm_table_pack(tb, o, 2, 10, 1, 1);
evas_object_show(o);
o = elm_check_add(win);
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, _("Use Profile"));
elm_table_pack(tb, o, 2, 10, 1, 1);
elm_table_pack(tb, o, 2, 11, 1, 1);
evas_object_show(o);
cfdata->use_profile_obj = o;
evas_object_smart_callback_add(o, "changed", _cb_profile_enabled_changed, cfdata);
@ -1043,7 +1066,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
o = elm_list_add(win);
evas_object_size_hint_weight_set(o, 0.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_table_pack(tb, o, 2, 11, 1, 1);
elm_table_pack(tb, o, 2, 12, 1, 1);
evas_object_show(o);
cfdata->profile_list_obj = o;
@ -1051,7 +1074,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, _("Custom Scale"));
elm_table_pack(tb, o, 2, 12, 1, 1);
elm_table_pack(tb, o, 2, 13, 1, 1);
evas_object_show(o);
cfdata->scale_custom_obj = o;
evas_object_smart_callback_add(o, "changed", _cb_custom_scale_changed, cfdata);
@ -1064,7 +1087,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
elm_slider_span_size_set(o, 100);
elm_slider_min_max_set(o, 0.5, 5.5);
elm_slider_value_set(o, elm_config_scale_get());
elm_table_pack(tb, o, 2, 13, 1, 1);
elm_table_pack(tb, o, 2, 14, 1, 1);
evas_object_show(o);
cfdata->scale_value_obj = o;
evas_object_smart_callback_add(o, "changed", _cb_scale_value_changed, cfdata);
@ -1167,6 +1190,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
cs->scale_multiplier = cs2->scale_multiplier;
printf("APPLY %s .... rel mode %i\n", cs->id, cs->rel_mode);
cs->enabled = cs2->enabled;
cs->ignore_disconnect = cs2->ignore_disconnect;
}
e_randr2_config_save();
e_randr2_config_apply();