add a configurable default policy (default: extend) for screen hotplugging
make an effort to "just work" instead of the classic enlightenment ux of being as annoying as possible ref T5707
This commit is contained in:
parent
e65c64ff63
commit
48a7181089
|
@ -752,6 +752,7 @@ e_comp_x_randr_create(void)
|
|||
}
|
||||
}
|
||||
free(modes);
|
||||
e_randr2_screen_modes_sort(s);
|
||||
}
|
||||
cs = NULL;
|
||||
priority = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "e.h"
|
||||
|
||||
#define E_RANDR_CONFIG_VERSION 1
|
||||
#define E_RANDR_CONFIG_VERSION 2
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
static Eina_Bool _screen_closed(E_Randr2_Screen *s);
|
||||
|
@ -13,7 +13,7 @@ static void _info_free(E_Randr2 *r);
|
|||
static E_Config_Randr2 *_config_load(void);
|
||||
static void _config_free(E_Config_Randr2 *cfg);
|
||||
static Eina_Bool _config_save(E_Randr2 *r, E_Config_Randr2 *cfg);
|
||||
static void _config_update(E_Randr2 *r, E_Config_Randr2 *cfg);
|
||||
static Eina_Bool _config_update(E_Randr2 *r, E_Config_Randr2 *cfg, Eina_Bool );
|
||||
static void _config_apply(E_Randr2 *r, E_Config_Randr2 *cfg);
|
||||
static int _config_screen_match_count(E_Randr2 *r, E_Config_Randr2 *cfg);
|
||||
static char *_screens_fingerprint(E_Randr2 *r);
|
||||
|
@ -44,6 +44,8 @@ E_API int E_EVENT_RANDR_CHANGE = 0;
|
|||
EINTERN Eina_Bool
|
||||
e_randr2_init(void)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (!E_EVENT_RANDR_CHANGE) E_EVENT_RANDR_CHANGE = ecore_event_type_new();
|
||||
if ((!e_comp->screen) || (!e_comp->screen->available) || (!e_comp->screen->available())) return EINA_FALSE;
|
||||
// create data descriptors for config storage
|
||||
|
@ -76,6 +78,7 @@ e_randr2_init(void)
|
|||
E_CONFIG_VAL(D, T, restore, UCHAR);
|
||||
E_CONFIG_VAL(D, T, ignore_hotplug_events, UCHAR);
|
||||
E_CONFIG_VAL(D, T, ignore_acpi_events, UCHAR);
|
||||
E_CONFIG_VAL(D, T, default_policy, UINT);
|
||||
|
||||
// set up events from the driver
|
||||
if (e_comp->screen->init)
|
||||
|
@ -88,14 +91,20 @@ e_randr2_init(void)
|
|||
e_randr2_cfg = _config_load();
|
||||
// only apply if restore is set AND at least one configured screen
|
||||
// matches one we have
|
||||
if ((e_randr2_cfg->restore) &&
|
||||
(_config_screen_match_count(e_randr2, e_randr2_cfg) > 0))
|
||||
|
||||
count = _config_screen_match_count(e_randr2, e_randr2_cfg);
|
||||
if (e_randr2_cfg->restore && count)
|
||||
{
|
||||
if (count != (int)eina_list_count(e_randr2->screens))
|
||||
{
|
||||
if (_config_update(e_randr2, e_randr2_cfg, 1))
|
||||
e_randr2_config_save();
|
||||
}
|
||||
_do_apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
_config_update(e_randr2, e_randr2_cfg);
|
||||
_config_update(e_randr2, e_randr2_cfg, 0);
|
||||
e_randr2_config_save();
|
||||
}
|
||||
ecore_event_add(E_EVENT_RANDR_CHANGE, NULL, NULL, NULL);
|
||||
|
@ -314,6 +323,13 @@ _info_free(E_Randr2 *r)
|
|||
free(r);
|
||||
}
|
||||
|
||||
static void
|
||||
_config_upgrade(E_Config_Randr2 *cfg)
|
||||
{
|
||||
if (cfg->version < 2)
|
||||
cfg->default_policy = E_RANDR2_POLICY_EXTEND;
|
||||
}
|
||||
|
||||
static E_Config_Randr2 *
|
||||
_config_load(void)
|
||||
{
|
||||
|
@ -324,15 +340,9 @@ _config_load(void)
|
|||
if (cfg)
|
||||
{
|
||||
if (cfg->version < E_RANDR_CONFIG_VERSION)
|
||||
{
|
||||
_config_free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("RRR: loaded existing config\n");
|
||||
return cfg;
|
||||
}
|
||||
_config_upgrade(cfg);
|
||||
printf("RRR: loaded existing config\n");
|
||||
return cfg;
|
||||
}
|
||||
|
||||
// need new config
|
||||
|
@ -342,6 +352,7 @@ _config_load(void)
|
|||
cfg->restore = 1;
|
||||
cfg->ignore_hotplug_events = 0;
|
||||
cfg->ignore_acpi_events = 0;
|
||||
cfg->default_policy = E_RANDR2_POLICY_EXTEND;
|
||||
printf("RRR: fresh config\n");
|
||||
return cfg;
|
||||
}
|
||||
|
@ -371,12 +382,20 @@ _config_save(E_Randr2 *r, E_Config_Randr2 *cfg)
|
|||
return e_config_domain_save("e_randr2", _e_randr2_cfg_edd, cfg);
|
||||
}
|
||||
|
||||
static void
|
||||
_config_update(E_Randr2 *r, E_Config_Randr2 *cfg)
|
||||
static Eina_Bool
|
||||
_config_ask_dialog()
|
||||
{
|
||||
e_configure_registry_call("screen/screen_setup", NULL, NULL);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_config_update(E_Randr2 *r, E_Config_Randr2 *cfg, Eina_Bool update_only)
|
||||
{
|
||||
Eina_List *l;
|
||||
E_Randr2_Screen *s;
|
||||
E_Config_Randr2_Screen *cs;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
printf("--------------------------------------------------\n");
|
||||
EINA_LIST_FOREACH(r->screens, l, s)
|
||||
|
@ -384,6 +403,7 @@ _config_update(E_Randr2 *r, E_Config_Randr2 *cfg)
|
|||
printf("RRR: out id=%s: connected=%i\n", s->id, s->info.connected);
|
||||
if ((!s->id) || (!s->info.connected) || (_screen_closed(s))) continue;
|
||||
cs = e_randr2_config_screen_find(s, cfg);
|
||||
if (cs && update_only) continue;
|
||||
if (!cs)
|
||||
{
|
||||
cs = calloc(1, sizeof(E_Config_Randr2_Screen));
|
||||
|
@ -395,16 +415,60 @@ _config_update(E_Randr2 *r, E_Config_Randr2 *cfg)
|
|||
}
|
||||
if (cs)
|
||||
{
|
||||
if (s->config.relative.to)
|
||||
cs->rel_to = eina_stringshare_add(s->config.relative.to);
|
||||
cs->rel_align = s->config.relative.align;
|
||||
cs->mode_refresh = s->config.mode.refresh;
|
||||
cs->mode_w = s->config.mode.w;
|
||||
cs->mode_h = s->config.mode.h;
|
||||
if (update_only)
|
||||
{
|
||||
switch (cfg->default_policy)
|
||||
{
|
||||
case E_RANDR2_POLICY_EXTEND:
|
||||
if (s->config.relative.mode < E_RANDR2_RELATIVE_TO_LEFT)
|
||||
cs->rel_mode = E_RANDR2_RELATIVE_TO_RIGHT;
|
||||
else
|
||||
cs->rel_mode = s->config.relative.mode;
|
||||
break;
|
||||
case E_RANDR2_POLICY_CLONE:
|
||||
cs->rel_mode = E_RANDR2_RELATIVE_CLONE;
|
||||
break;
|
||||
case E_RANDR2_POLICY_ASK:
|
||||
ecore_timer_loop_add(2, _config_ask_dialog, NULL);
|
||||
case E_RANDR2_POLICY_NONE:
|
||||
cs->rel_mode = E_RANDR2_RELATIVE_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
cs->rel_mode = s->config.relative.mode;
|
||||
if (update_only &&
|
||||
((cfg->default_policy == E_RANDR2_POLICY_CLONE) ||
|
||||
(cfg->default_policy == E_RANDR2_POLICY_EXTEND)))
|
||||
{
|
||||
E_Randr2_Mode *m = eina_list_data_get(s->info.modes);
|
||||
|
||||
cs->enabled = !!m;
|
||||
cs->mode_refresh = m->refresh;
|
||||
cs->mode_w = m->w;
|
||||
cs->mode_h = m->h;
|
||||
if (s->config.relative.to)
|
||||
cs->rel_to = eina_stringshare_add(s->config.relative.to);
|
||||
else
|
||||
{
|
||||
/* find right-most screen */
|
||||
E_Zone *zone = eina_list_last_data_get(e_comp->zones);
|
||||
eina_stringshare_replace(&cs->rel_to, zone->randr2_id);
|
||||
}
|
||||
cs->rel_align = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs->enabled = s->config.enabled;
|
||||
cs->mode_refresh = s->config.mode.refresh;
|
||||
cs->mode_w = s->config.mode.w;
|
||||
cs->mode_h = s->config.mode.h;
|
||||
if (s->config.relative.to)
|
||||
cs->rel_to = eina_stringshare_add(s->config.relative.to);
|
||||
cs->rel_align = s->config.relative.align;
|
||||
}
|
||||
cs->rotation = s->config.rotation;
|
||||
cs->priority = s->config.priority;
|
||||
cs->rel_mode = s->config.relative.mode;
|
||||
cs->enabled = s->config.enabled;
|
||||
if (cs->profile)
|
||||
{
|
||||
printf("RRR: store config profile '%s'\n", cs->profile);
|
||||
|
@ -418,9 +482,11 @@ _config_update(E_Randr2 *r, E_Config_Randr2 *cfg)
|
|||
}
|
||||
printf("RRR: store scale mul %1.5f\n", cs->scale_multiplier);
|
||||
s->config.scale_multiplier = cs->scale_multiplier;
|
||||
ret = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
printf("--------------------------------------------------\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -591,19 +657,28 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2)
|
|||
static Eina_Bool
|
||||
_cb_screen_change_delay(void *data EINA_UNUSED)
|
||||
{
|
||||
Eina_Bool change = EINA_FALSE;
|
||||
_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))
|
||||
{
|
||||
E_Randr2 *rtemp;
|
||||
Eina_Bool change = EINA_FALSE;
|
||||
|
||||
printf("RRR: reconfigure screens due to event...\n");
|
||||
rtemp = e_comp->screen->create();
|
||||
if (rtemp)
|
||||
{
|
||||
if (_screens_differ(e_randr2, rtemp)) change = EINA_TRUE;
|
||||
if (e_randr2_cfg->default_policy != E_RANDR2_POLICY_NONE)
|
||||
{
|
||||
if (_config_update(rtemp, e_randr2_cfg, 1))
|
||||
{
|
||||
e_randr2_config_save();
|
||||
if (e_randr2_cfg->default_policy != E_RANDR2_POLICY_ASK)
|
||||
change = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
_info_free(rtemp);
|
||||
}
|
||||
printf("RRR: change = %i\n", change);
|
||||
|
@ -1268,3 +1343,22 @@ e_randr2_screen_dpi_get(E_Randr2_Screen *s)
|
|||
dpi2 = (25.4 * (double)(s->config.mode.h)) / (double)(s->info.size.h);
|
||||
return (dpi1 + dpi2) / 2.0;
|
||||
}
|
||||
|
||||
static int
|
||||
_modelist_sort(const void *a, const void *b)
|
||||
{
|
||||
const E_Randr2_Mode *ma = a, *mb = b;
|
||||
|
||||
/* largest resolutions first */
|
||||
if ((ma->w * ma->h) > (mb->w * mb->h)) return -1;
|
||||
/* highest refresh first */
|
||||
if (ma->refresh > mb->refresh) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
e_randr2_screen_modes_sort(E_Randr2_Screen *s)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(s);
|
||||
s->info.modes = eina_list_sort(s->info.modes, 0, _modelist_sort);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,14 @@ typedef struct _E_Config_Randr2_Screen E_Config_Randr2_Screen;
|
|||
#ifndef E_RANDR2_H
|
||||
#define E_RAND2R_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_RANDR2_POLICY_NONE,
|
||||
E_RANDR2_POLICY_EXTEND,
|
||||
E_RANDR2_POLICY_CLONE,
|
||||
E_RANDR2_POLICY_ASK,
|
||||
} E_Randr2_Policy;
|
||||
|
||||
typedef enum _E_Randr2_Relative
|
||||
{
|
||||
E_RANDR2_RELATIVE_UNKNOWN,
|
||||
|
@ -92,6 +100,7 @@ struct _E_Config_Randr2
|
|||
unsigned char restore;
|
||||
unsigned char ignore_hotplug_events;
|
||||
unsigned char ignore_acpi_events;
|
||||
E_Randr2_Policy default_policy;
|
||||
};
|
||||
|
||||
struct _E_Config_Randr2_Screen
|
||||
|
@ -128,6 +137,6 @@ E_API E_Config_Randr2_Screen *e_randr2_config_screen_find(E_Randr2_Screen *s, E_
|
|||
E_API void e_randr2_screens_setup(int rw, int rh);
|
||||
E_API E_Randr2_Screen *e_randr2_screen_id_find(const char *id);
|
||||
E_API double e_randr2_screen_dpi_get(E_Randr2_Screen *s);
|
||||
|
||||
E_API void e_randr2_screen_modes_sort(E_Randr2_Screen *s);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -27,10 +27,12 @@ struct _E_Config_Dialog_Data
|
|||
Evas_Object *profile_list_obj;
|
||||
Evas_Object *scale_custom_obj;
|
||||
Evas_Object *scale_value_obj;
|
||||
Evas_Object *policy_obj;
|
||||
int restore;
|
||||
int hotplug;
|
||||
int acpi;
|
||||
int screen;
|
||||
E_Randr2_Policy policy;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
@ -101,6 +103,7 @@ _create_data(E_Config_Dialog *cfd EINA_UNUSED)
|
|||
cfdata->restore = e_randr2_cfg->restore;
|
||||
cfdata->hotplug = !e_randr2_cfg->ignore_hotplug_events;
|
||||
cfdata->acpi = !e_randr2_cfg->ignore_acpi_events;
|
||||
cfdata->policy = e_randr2_cfg->default_policy;
|
||||
return cfdata;
|
||||
}
|
||||
|
||||
|
@ -742,6 +745,66 @@ _cb_enabled_changed(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
|||
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_policy_text_update(E_Config_Dialog_Data *cfdata)
|
||||
{
|
||||
char pbuf[128];
|
||||
const char *policy[] =
|
||||
{
|
||||
_("Ignore"),
|
||||
_("Extend"),
|
||||
_("Clone"),
|
||||
_("Ask")
|
||||
};
|
||||
|
||||
snprintf(pbuf, sizeof(pbuf), _("Hotplug Policy (%s)"), policy[cfdata->policy]);
|
||||
elm_object_text_set(cfdata->policy_obj, pbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_policy_ignore(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_Data *cfdata = data;
|
||||
|
||||
if (cfdata->policy == E_RANDR2_POLICY_NONE) return;
|
||||
cfdata->policy = E_RANDR2_POLICY_NONE;
|
||||
_policy_text_update(cfdata);
|
||||
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_policy_ask(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_Data *cfdata = data;
|
||||
|
||||
if (cfdata->policy == E_RANDR2_POLICY_ASK) return;
|
||||
cfdata->policy = E_RANDR2_POLICY_ASK;
|
||||
_policy_text_update(cfdata);
|
||||
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_policy_extend(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_Data *cfdata = data;
|
||||
|
||||
if (cfdata->policy == E_RANDR2_POLICY_EXTEND) return;
|
||||
cfdata->policy = E_RANDR2_POLICY_EXTEND;
|
||||
_policy_text_update(cfdata);
|
||||
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_policy_clone(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_Data *cfdata = data;
|
||||
|
||||
if (cfdata->policy == E_RANDR2_POLICY_CLONE) return;
|
||||
cfdata->policy = E_RANDR2_POLICY_CLONE;
|
||||
_policy_text_update(cfdata);
|
||||
e_config_dialog_changed_set(cfdata->cfd, EINA_TRUE);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data *cfdata)
|
||||
{
|
||||
|
@ -1045,6 +1108,17 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas EINA_UNUSED, E_Config_Dialog_Data
|
|||
evas_object_show(o);
|
||||
evas_object_smart_callback_add(o, "changed", _cb_acpi_changed, cfdata);
|
||||
|
||||
cfdata->policy_obj = o = elm_hoversel_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);
|
||||
_policy_text_update(cfdata);
|
||||
elm_hoversel_item_add(o, _("Clone"), NULL, ELM_ICON_NONE, _cb_policy_clone, cfdata);
|
||||
elm_hoversel_item_add(o, _("Extend"), NULL, ELM_ICON_NONE, _cb_policy_extend, cfdata);
|
||||
elm_hoversel_item_add(o, _("Ask"), NULL, ELM_ICON_NONE, _cb_policy_ask, cfdata);
|
||||
elm_hoversel_item_add(o, _("Ignore"), NULL, ELM_ICON_NONE, _cb_policy_ignore, cfdata);
|
||||
elm_box_pack_end(bx2, o);
|
||||
evas_object_show(o);
|
||||
|
||||
evas_smart_objects_calculate(evas_object_evas_get(win));
|
||||
|
||||
e_util_win_auto_resize_fill(win);
|
||||
|
@ -1062,6 +1136,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
|
|||
e_randr2_cfg->restore = cfdata->restore;
|
||||
e_randr2_cfg->ignore_hotplug_events = !cfdata->hotplug;
|
||||
e_randr2_cfg->ignore_acpi_events = !cfdata->acpi;
|
||||
e_randr2_cfg->default_policy = cfdata->policy;
|
||||
|
||||
printf("APPLY....................\n");
|
||||
EINA_LIST_FOREACH(cfdata->screens, l, cs2)
|
||||
|
|
Loading…
Reference in New Issue