e17: add xsettings. add option to icon config to use same theme for applications

SVN revision: 63591
This commit is contained in:
Hannes Janetzek 2011-09-24 22:05:15 +00:00
parent 2e0c93bdc8
commit 1656a81310
10 changed files with 539 additions and 2 deletions

View File

@ -534,4 +534,6 @@ group "E_Config" struct {
value "device_desktop" int: 0;
value "device_auto_mount" int: 0;
value "device_auto_open" int: 0;
value "xsettings.match_e17_theme" uchar: 1;
value "xsettings.match_e17_icon_theme" uchar: 1;
}

View File

@ -1849,4 +1849,6 @@ group "E_Config" struct {
value "device_desktop" int: 1;
value "device_auto_mount" int: 0;
value "device_auto_open" int: 0;
value "xsettings.match_e17_theme" uchar: 1;
value "xsettings.match_e17_icon_theme" uchar: 1;
}

View File

@ -179,8 +179,10 @@ e_widget_toolbar.h \
e_widget_toolbook.h \
e_win.h \
e_xinerama.h \
e_xsettings.h \
e_zone.h
enlightenment_src = \
e_about.c \
e_acpi.c \
@ -323,6 +325,7 @@ e_widget_toolbar.c \
e_widget_toolbook.c \
e_win.c \
e_xinerama.c \
e_xsettings.c \
e_zone.c \
$(ENLIGHTENMENTHEADERS)

View File

@ -919,6 +919,11 @@ e_config_init(void)
E_CONFIG_VAL(D, T, deskenv.load_gnome, UCHAR);
E_CONFIG_VAL(D, T, deskenv.load_kde, UCHAR);
E_CONFIG_VAL(D, T, xsettings.match_e17_theme, UCHAR);
E_CONFIG_VAL(D, T, xsettings.match_e17_icon_theme, UCHAR);
E_CONFIG_VAL(D, T, xsettings.gtk_theme, STR);
E_CONFIG_VAL(D, T, xsettings.icon_theme, STR);
e_config_load();
e_config_save_queue();
@ -1184,6 +1189,11 @@ e_config_load(void)
COPYVAL(backlight.transition);
IFCFGEND;
IFCFG(0x0143);
COPYVAL(xsettings.match_e17_theme);
COPYVAL(xsettings.match_e17_icon_theme);
IFCFGEND;
e_config->config_version = E_CONFIG_FILE_VERSION;
_e_config_free(tcfg);
}
@ -2101,6 +2111,9 @@ _e_config_free(E_Config *ecf)
if (evr->val) eina_stringshare_del(evr->val);
E_FREE(evr);
}
if (ecf->xsettings.icon_theme) eina_stringshare_del(ecf->xsettings.icon_theme);
if (ecf->xsettings.gtk_theme) eina_stringshare_del(ecf->xsettings.gtk_theme);
E_FREE(ecf);
}

View File

@ -33,7 +33,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 0x0143
#define E_CONFIG_FILE_GENERATION 0x0144
#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION)
#define E_EVAS_ENGINE_DEFAULT 0
@ -360,6 +360,13 @@ struct _E_Config
unsigned char load_gnome;
unsigned char load_kde;
} deskenv;
struct {
unsigned char match_e17_theme;
unsigned char match_e17_icon_theme;
const char *gtk_theme;
const char *icon_theme;
} xsettings;
};
struct _E_Config_Env_Var
@ -492,6 +499,7 @@ struct _E_Config_Gadcon_Client
int orient;
unsigned char autoscroll;
unsigned char resizable;
const char *theme;
};
struct _E_Config_Shelf

View File

@ -140,3 +140,4 @@
#include "e_env.h"
#include "e_backlight.h"
#include "e_deskenv.h"
#include "e_xsettings.h"

View File

@ -860,6 +860,15 @@ main(int argc, char **argv)
TS("E_Thumb Init Done");
_e_main_shutdown_push(e_icon_shutdown);
TS("E_XSettings Init");
if (!e_xsettings_init())
{
e_error_message_show(_("Enlightenment cannot initialize the XSettings system.\n"));
_e_main_shutdown(-1);
}
TS("E_XSettings Init Done");
_e_main_shutdown_push(e_xsettings_shutdown);
if (!after_restart)
{
if (e_config->show_splash)

477
src/bin/e_xsettings.c Normal file
View File

@ -0,0 +1,477 @@
#include <e.h>
#include <X11/Xlib.h>
#include <X11/Xmd.h> /* For CARD16 */
#define RETRY_TIMEOUT 2.0
#define SETTING_TYPE_INT 0
#define SETTING_TYPE_STRING 1
#define SETTING_TYPE_COLOR 2
#define OFFSET_ADD(n) ((n + 4 - 1) & (~(4 - 1)))
typedef struct _Settings_Manger Settings_Manager;
typedef struct _Setting Setting;
struct _Settings_Manger
{
E_Manager *man;
Ecore_X_Window selection;
Ecore_Timer *timer_retry;
unsigned long serial;
Ecore_X_Atom _atom_xsettings_screen;
};
struct _Setting
{
unsigned short type;
const char *name;
struct { const char *value; } s;
struct { int value; } i;
struct { unsigned short red, green, blue, alpha; } c;
unsigned long length;
unsigned long last_change;
};
static void _xsettings_apply(Settings_Manager *sm);
static Ecore_X_Atom _atom_manager = 0;
static Ecore_X_Atom _atom_xsettings = 0;
static Eina_List *managers = NULL;
static Eina_List *handlers = NULL;
static Eina_List *settings = NULL;
static const char _setting_icon_theme_name[] = "Net/IconThemeName";
static const char _setting_theme_name[] = "Net/ThemeName";
static Ecore_X_Atom
_xsettings_atom_screen_get(int screen_num)
{
char buf[32];
snprintf(buf, sizeof(buf), "_XSETTINGS_S%d", screen_num);
return ecore_x_atom_get(buf);
}
static Eina_Bool
_xsettings_selection_owner_set(Settings_Manager *sm)
{
Ecore_X_Atom atom;
Ecore_X_Window cur_selection;
Eina_Bool ret;
atom = _xsettings_atom_screen_get(sm->man->num);
ecore_x_selection_owner_set(sm->selection, atom, ecore_x_current_time_get());
ecore_x_sync();
cur_selection = ecore_x_selection_owner_get(atom);
ret = (cur_selection == sm->selection);
if (!ret)
fprintf(stderr, "XSETTINGS: tried to set selection to %#x, but got %#x\n",
sm->selection, cur_selection);
return ret;
}
static void
_xsettings_deactivate(Settings_Manager *sm)
{
Ecore_X_Window old;
if (sm->selection == 0) return;
old = sm->selection;
sm->selection = 0;
_xsettings_selection_owner_set(sm);
ecore_x_sync();
ecore_x_window_free(old);
}
static Eina_Bool
_xsettings_activate(Settings_Manager *sm)
{
unsigned int visual;
Ecore_X_Atom atom;
Ecore_X_Window old_win;
Ecore_X_Window_Attributes attr;
if (sm->selection != 0) return 1;
atom = _xsettings_atom_screen_get(sm->man->num);
old_win = ecore_x_selection_owner_get(atom);
if (old_win != 0) return 0;
sm->selection = ecore_x_window_input_new(0, 0, 0, 1, 1);
if (sm->selection == 0)
return 0;
if (!_xsettings_selection_owner_set(sm))
{
ecore_x_window_free(sm->selection);
sm->selection = 0;
return 0;
}
ecore_x_client_message32_send(e_manager_current_get()->root, _atom_manager,
ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
ecore_x_current_time_get(), atom,
sm->selection, 0, 0);
_xsettings_apply(sm);
return 1;
}
static Eina_Bool
_xsettings_activate_retry(void *data)
{
Settings_Manager *sm = data;
Eina_Bool ret;
fputs("XSETTINGS: reactivate...\n", stderr);
ret = _xsettings_activate(sm);
if (ret)
fputs("XSETTINGS: activate success!\n", stderr);
else
fprintf(stderr, "XSETTINGS: activate failure! retrying in %0.1f seconds\n",
RETRY_TIMEOUT);
if (!ret)
return ECORE_CALLBACK_RENEW;
sm->timer_retry = NULL;
return ECORE_CALLBACK_CANCEL;
}
static void
_xsettings_retry(Settings_Manager *sm)
{
if (sm->timer_retry) return;
sm->timer_retry = ecore_timer_add
(RETRY_TIMEOUT, _xsettings_activate_retry, sm);
}
static void
_xsettings_string_set(const char *name, const char *value)
{
Setting *s;
Eina_List *l;
if (!name) return;
name = eina_stringshare_add(name);
EINA_LIST_FOREACH(settings, l, s)
{
if (s->type != SETTING_TYPE_STRING) continue;
if (s->name == name) break;
}
if (!value)
{
if (!s) return;
printf("remove %s\n", name);
eina_stringshare_del(name);
eina_stringshare_del(s->name);
eina_stringshare_del(s->s.value);
settings = eina_list_remove(settings, s);
E_FREE(s);
return;
}
if (s)
{
printf("update %s %s\n", name, value);
eina_stringshare_del(name);
eina_stringshare_replace(&s->s.value, value);
}
else
{
printf("add %s %s\n", name, value);
s = E_NEW(Setting, 1);
s->type = SETTING_TYPE_STRING;
s->name = name;
s->s.value = eina_stringshare_add(value);
settings = eina_list_append(settings, s);
}
/* type + pad + name-len + last-change-serial + str_len */
s->length = 12;
s->length += OFFSET_ADD(strlen(name));
s->length += OFFSET_ADD(strlen(value));
s->last_change = ecore_x_current_time_get();
}
static void
_xsettings_int_set(const char *name, int value)
{
Setting *s;
Eina_List *l;
if (!name) return;
name = eina_stringshare_add(name);
EINA_LIST_FOREACH(settings, l, s)
{
if (s->type != SETTING_TYPE_INT) continue;
if (s->name == name) break;
}
if (!value)
{
if (!s) return;
printf("remove %s\n", name);
eina_stringshare_del(name);
eina_stringshare_del(s->name);
settings = eina_list_remove(settings, s);
E_FREE(s);
return;
}
if (s)
{
printf("update %s %d\n", name, value);
eina_stringshare_del(name);
s->i.value = value;
}
else
{
printf("add %s %d\n", name, value);
s = E_NEW(Setting, 1);
s->type = SETTING_TYPE_INT;
s->name = name;
s->i.value = value;
settings = eina_list_append(settings, s);
}
/* type + pad + name-len + last-change-serial + value */
s->length = 12;
s->length += OFFSET_ADD(strlen(name));
}
static unsigned char *
_xsettings_copy(unsigned char *buffer, Setting *s)
{
size_t str_len;
size_t len;
buffer[0] = s->type;
buffer[1] = 0;
buffer += 2;
str_len = strlen(s->name);
*(CARD16 *)(buffer) = str_len;
buffer += 2;
memcpy(buffer, s->name, str_len);
buffer += str_len;
len = OFFSET_ADD(str_len) - str_len;
memset(buffer, 0, len);
buffer += len;
*(CARD32 *)(buffer) = s->last_change;
buffer += 4;
switch (s->type)
{
case SETTING_TYPE_INT:
*(CARD32 *)(buffer) = s->i.value;
buffer += 4;
break;
case SETTING_TYPE_STRING:
str_len = strlen (s->s.value);
*(CARD32 *)(buffer) = str_len;
buffer += 4;
memcpy(buffer, s->s.value, str_len);
buffer += str_len;
len = OFFSET_ADD(str_len) - str_len;
memset(buffer, 0, len);
buffer += len;
break;
case SETTING_TYPE_COLOR:
*(CARD16 *)(buffer) = s->c.red;
*(CARD16 *)(buffer + 2) = s->c.green;
*(CARD16 *)(buffer + 4) = s->c.blue;
*(CARD16 *)(buffer + 6) = s->c.alpha;
buffer += 8;
break;
}
return buffer;
}
static void
_xsettings_apply(Settings_Manager *sm)
{
unsigned char *data;
unsigned char *pos;
size_t len = 12;
Setting *s;
Eina_List *l;
EINA_LIST_FOREACH(settings, l, s)
len += s->length;
pos = data = malloc(len);
if (!data) return;
#if __BYTE_ORDER == __LITTLE_ENDIAN
*pos = LSBFirst;
#else
*pos = MSBFirst;
#endif
pos += 4;
*(CARD32*)pos = sm->serial++;
pos += 4;
*(CARD32*)pos = eina_list_count(settings);
pos += 4;
EINA_LIST_FOREACH(settings, l, s)
pos = _xsettings_copy(pos, s);
ecore_x_window_prop_property_set(sm->selection,
_atom_xsettings,
_atom_xsettings,
8, data, len);
free(data);
}
static void
_xsettings_update(void)
{
Settings_Manager *sm;
Eina_List *l;
EINA_LIST_FOREACH(managers, l, sm)
if (sm->selection) _xsettings_apply(sm);
}
static Eina_Bool
_cb_icon_theme_change(void *data, int type __UNUSED__, void *event)
{
E_Event_Config_Icon_Theme *ev = event;
if (e_config->xsettings.match_e17_icon_theme)
{
_xsettings_string_set(_setting_icon_theme_name,
ev->icon_theme);
_xsettings_update();
}
return ECORE_CALLBACK_PASS_ON;
}
static void
_xsettings_icon_theme_set(void)
{
if (e_config->xsettings.match_e17_icon_theme)
{
_xsettings_string_set(_setting_icon_theme_name,
e_config->icon_theme);
return;
}
else if (e_config->xsettings.icon_theme)
{
_xsettings_string_set(_setting_icon_theme_name,
e_config->xsettings.icon_theme);
return;
}
_xsettings_string_set(_setting_icon_theme_name, NULL);
}
static void
_xsettings_theme_set(void)
{
if (e_config->xsettings.match_e17_theme)
{
E_Config_Theme *ct;
if ((ct = e_theme_config_get("theme")))
{
char *theme;
if ((theme = edje_file_data_get(ct->file, "gtk-theme")))
{
_xsettings_string_set(_setting_theme_name, theme);
return;
}
}
}
else if (e_config->xsettings.gtk_theme)
{
_xsettings_string_set(_setting_theme_name,
e_config->xsettings.gtk_theme);
return;
}
_xsettings_string_set(_setting_theme_name, NULL);
}
EINTERN int
e_xsettings_init(void)
{
Eina_List *l;
E_Manager *man;
_atom_manager = ecore_x_atom_get("MANAGER");
_atom_xsettings = ecore_x_atom_get("_XSETTINGS_SETTINGS");
_xsettings_theme_set();
_xsettings_icon_theme_set();
EINA_LIST_FOREACH(e_manager_list(), l, man)
{
Settings_Manager *sm = E_NEW(Settings_Manager, 1);
sm->man = man;
if (!_xsettings_activate(sm))
_xsettings_retry(sm);
managers = eina_list_append(managers, sm);
}
handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME,
_cb_icon_theme_change, NULL));
return 1;
}
EINTERN int
e_xsettings_shutdown(void)
{
Settings_Manager *sm;
Ecore_Event_Handler *h;
Setting *s;
EINA_LIST_FREE(managers, sm)
{
if (sm->timer_retry)
ecore_timer_del(sm->timer_retry);
_xsettings_deactivate(sm);
E_FREE(sm);
}
EINA_LIST_FREE(settings, s)
{
if (s->name) eina_stringshare_del(s->name);
if (s->s.value) eina_stringshare_del(s->s.value);
E_FREE(s);
}
EINA_LIST_FREE(handlers, h)
ecore_event_handler_del(h);
return 1;
}
EAPI void
e_xsettings_config_update(void)
{
_xsettings_theme_set();
_xsettings_icon_theme_set();
_xsettings_update();
}

13
src/bin/e_xsettings.h Normal file
View File

@ -0,0 +1,13 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_XSETTINGS_H
# define E_XSETTINGS_H
EINTERN int e_xsettings_init(void);
EINTERN int e_xsettings_shutdown(void);
EAPI void e_xsettings_config_update(void);
# endif
#endif

View File

@ -15,6 +15,7 @@ struct _E_Config_Dialog_Data
const char *themename;
int overrides;
int enable_icon_theme;
int match_e17_icon_theme;
int populating;
struct
{
@ -74,6 +75,7 @@ _create_data(E_Config_Dialog *cfd)
cfdata->cfd = cfd;
cfdata->themename = eina_stringshare_add(e_config->icon_theme);
cfdata->overrides = e_config->icon_theme_overrides;
cfdata->match_e17_icon_theme = e_config->xsettings.match_e17_icon_theme;
cfdata->enable_icon_theme = !!(e_config->icon_theme);
return cfdata;
}
@ -95,6 +97,9 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda
if (cfdata->overrides != e_config->icon_theme_overrides)
return 1;
if (cfdata->match_e17_icon_theme != e_config->xsettings.match_e17_icon_theme)
return 1;
if (cfdata->enable_icon_theme != !!(e_config->icon_theme))
return 1;
@ -121,6 +126,7 @@ _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
e_config->icon_theme = NULL;
e_config->icon_theme_overrides = !!cfdata->overrides;
e_config->xsettings.match_e17_icon_theme = cfdata->match_e17_icon_theme;
e_config_save_queue();
e_util_env_set("E_ICON_THEME", e_config->icon_theme);
@ -273,9 +279,12 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
e_widget_on_change_hook_set(checkbox, _icon_theme_changed, cfdata);
e_widget_list_object_append(o, checkbox, 0, 0, 0.0);
checkbox = e_widget_check_add(evas, _("Use icon theme for applications"),
&(cfdata->match_e17_icon_theme));
e_widget_list_object_append(o, checkbox, 0, 0, 0.0);
checkbox = e_widget_check_add(evas, _("Icons override general theme"),
&(cfdata->overrides));
e_widget_on_change_hook_set(checkbox, _icon_theme_changed, cfdata);
e_widget_list_object_append(o, checkbox, 0, 0, 0.0);
e_dialog_resizable_set(cfd->dia, 1);