diff --git a/src/conky.cc b/src/conky.cc index 45851928..4fad3cab 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -3909,7 +3909,8 @@ int main(int argc, char **argv) "print(conky.variables.asdf{}.text);\n" "print(conky.variables.asdf{}.xxx);\n" "conky.config = { alignment='bar', asdf=47, [42]=47, out_to_x=true,\n" - " own_window_hints='above, undecorated,,below'};\n" + " own_window_hints='above, undecorated,,below',\n" + " background_colour='pink'};\n" ); l.call(0, 0); conky::set_config_settings(l); diff --git a/src/x11.cc b/src/x11.cc index d7084948..b562d607 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -73,6 +73,166 @@ char window_created = 0; static void update_workarea(void); static Window find_desktop_window(Window *p_root, Window *p_desktop); static Window find_subwindow(Window win, int w, int h); +static void init_X11(); +static void deinit_X11(); + +/********************* ************************/ +namespace priv { + void out_to_x_setting::lua_setter(lua::state &l, bool init) + { + lua::stack_sentry s(l, -2); + + Base::lua_setter(l, init); + + if(init && do_convert(l, -1).first) + init_X11(); + + ++s; + } + + void out_to_x_setting::cleanup(lua::state &l) + { + lua::stack_sentry s(l, -1); + + if(do_convert(l, -1).first) + deinit_X11(); + + l.pop(); + } +} + +namespace { + struct colour_traits { + static const lua::Type type = lua::TSTRING; + + static std::pair convert(lua::state &l, int index, const std::string &) + { return {get_x11_color(l.tostring(index)), true}; } + }; + + class colour_setting: public conky::simple_config_setting { + typedef conky::simple_config_setting Base; + + protected: + virtual void lua_setter(lua::state &l, bool init) + { + lua::stack_sentry s(l, -2); + + if(not out_to_x.get(l)) { + // ignore if we're not using X + l.replace(-2); + } else + Base::lua_setter(l, init); + + ++s; + } + + public: + colour_setting(const std::string &name_, unsigned long default_value_ = 0) + : Base(name_, default_value_, true) + {} + + }; +} + +template<> +conky::lua_traits::Map conky::lua_traits::map = { + { "top_left", TOP_LEFT }, + { "top_right", TOP_RIGHT }, + { "top_middle", TOP_MIDDLE }, + { "bottom_left", BOTTOM_LEFT }, + { "bottom_right", BOTTOM_RIGHT }, + { "bottom_middle", BOTTOM_MIDDLE }, + { "middle_left", MIDDLE_LEFT }, + { "middle_middle", MIDDLE_MIDDLE }, + { "middle_right", MIDDLE_RIGHT }, + { "none", NONE } +}; + +template<> +conky::lua_traits::Map conky::lua_traits::map = { + { "normal", TYPE_NORMAL }, + { "dock", TYPE_DOCK }, + { "panel", TYPE_PANEL }, + { "desktop", TYPE_DESKTOP }, + { "override", TYPE_OVERRIDE } +}; + +template<> +conky::lua_traits::Map conky::lua_traits::map = { + { "undecorated", HINT_UNDECORATED }, + { "below", HINT_BELOW }, + { "above", HINT_ABOVE }, + { "sticky", HINT_STICKY }, + { "skip_taskbar", HINT_SKIP_TASKBAR }, + { "skip_pager", HINT_SKIP_PAGER } +}; + +std::pair +window_hints_traits::convert(lua::state &l, int index, const std::string &name) +{ + typedef conky::lua_traits Traits; + + lua::stack_sentry s(l); + l.checkstack(1); + + std::string hints = l.tostring(index); + // add a sentinel to simplify the following loop + hints += ','; + size_t pos = 0; + size_t newpos; + uint16_t ret = 0; + while((newpos = hints.find_first_of(", ", pos)) != std::string::npos) { + if(newpos > pos) { + l.pushstring(hints.substr(pos, newpos-pos)); + auto t = conky::lua_traits::convert(l, -1, name); + if(not t.second) + return {0, false}; + SET_HINT(ret, t.first); + l.pop(); + } + pos = newpos+1; + } + return {ret, true}; +} + +namespace { + // used to set the default value for own_window_title + std::string gethostnamecxx() + { update_uname(); return info.uname_s.nodename; } +} + +/* + * The order of these settings cannot be completely arbitrary. Some of them depend on others, and + * the setters are called in the order of in which they are defined. The ordering should be + * display_name -> out_to_x -> everything colour related + */ + +conky::simple_config_setting text_alignment("alignment", NONE, false); +conky::simple_config_setting display_name("display", std::string(), false); +priv::out_to_x_setting out_to_x; + +#ifdef OWN_WINDOW +conky::simple_config_setting own_window("own_window", false, false); +conky::simple_config_setting set_transparent("own_window_transparent", false, false); +conky::simple_config_setting own_window_class("own_window_class", + PACKAGE_NAME, false); + +conky::simple_config_setting own_window_title("own_window_title", + PACKAGE_NAME " (" + gethostnamecxx()+")", false); + +conky::simple_config_setting own_window_type("own_window_type", TYPE_NORMAL, false); +conky::simple_config_setting + own_window_hints("own_window_hints", 0, false); + +colour_setting background_colour("background_colour", 0); + +#ifdef BUILD_ARGB +conky::simple_config_setting use_argb_visual("own_window_argb_visual", false, false); +conky::range_config_setting own_window_argb_value("own_window_argb_value", + 0, 255, 255, false); +#endif +#endif /*OWN_WINDOW*/ +/******************** ************************/ #ifdef DEBUG /* WARNING, this type not in Xlib spec */ @@ -224,21 +384,11 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop) } namespace { - unsigned long colour_set = -1; - std::string colour_str_set; - int argb_set = -1; - /* helper function for set_transparent_background() */ void do_set_background(Window win, int argb) { - std::string t = background_colour.get(*state); - if(t == colour_str_set && argb_set == argb) - return; - colour_str_set = t; - argb_set = argb; - - colour_set = get_x11_color(colour_str_set) | (argb_set<<24); - XSetWindowBackground(display, win, colour_set); + unsigned long colour = background_colour.get(*state) | (argb<<24); + XSetWindowBackground(display, win, colour); } } @@ -249,8 +399,7 @@ void set_transparent_background(Window win) #ifdef BUILD_ARGB if (have_argb_visual) { // real transparency - do_set_background(win, set_transparent.get(*state) - ? 0 : (own_window_argb_value.get(*state) << 24)); + do_set_background(win, set_transparent.get(*state) ? 0 : own_window_argb_value.get(*state)); } else { #endif /* BUILD_ARGB */ // pseudo transparency @@ -315,7 +464,6 @@ void destroy_window(void) XFreeGC(display, window.gc); } memset(&window, 0, sizeof(struct conky_window)); - colour_set = -1; } void init_window(int w, int h, char **argv, int argc) @@ -960,120 +1108,3 @@ void xdbe_swap_buffers(void) } } #endif /* BUILD_XDBE */ - -namespace priv { - void out_to_x_setting::lua_setter(lua::state &l, bool init) - { - lua::stack_sentry s(l, -2); - - Base::lua_setter(l, init); - - if(init && do_convert(l, -1).first) - init_X11(); - - ++s; - } - - void out_to_x_setting::cleanup(lua::state &l) - { - lua::stack_sentry s(l, -1); - - if(do_convert(l, -1).first) - deinit_X11(); - - l.pop(); - } -} - -template<> -conky::lua_traits::Map conky::lua_traits::map = { - { "top_left", TOP_LEFT }, - { "top_right", TOP_RIGHT }, - { "top_middle", TOP_MIDDLE }, - { "bottom_left", BOTTOM_LEFT }, - { "bottom_right", BOTTOM_RIGHT }, - { "bottom_middle", BOTTOM_MIDDLE }, - { "middle_left", MIDDLE_LEFT }, - { "middle_middle", MIDDLE_MIDDLE }, - { "middle_right", MIDDLE_RIGHT }, - { "none", NONE } -}; -conky::simple_config_setting text_alignment("alignment", NONE, false); - -conky::simple_config_setting display_name("display", std::string(), false); - -priv::out_to_x_setting out_to_x; - -#ifdef OWN_WINDOW -conky::simple_config_setting own_window("own_window", false, false); -conky::simple_config_setting set_transparent("own_window_transparent", false, false); -conky::simple_config_setting own_window_class("own_window_class", - PACKAGE_NAME, false); - -namespace { - // used to set the default value for own_window_title - std::string gethostnamecxx() - { update_uname(); return info.uname_s.nodename; } -} -conky::simple_config_setting own_window_title("own_window_title", - PACKAGE_NAME " (" + gethostnamecxx()+")", false); - -template<> -conky::lua_traits::Map conky::lua_traits::map = { - { "normal", TYPE_NORMAL }, - { "dock", TYPE_DOCK }, - { "panel", TYPE_PANEL }, - { "desktop", TYPE_DESKTOP }, - { "override", TYPE_OVERRIDE } -}; -conky::simple_config_setting own_window_type("own_window_type", TYPE_NORMAL, false); - -template<> -conky::lua_traits::Map conky::lua_traits::map = { - { "undecorated", HINT_UNDECORATED }, - { "below", HINT_BELOW }, - { "above", HINT_ABOVE }, - { "sticky", HINT_STICKY }, - { "skip_taskbar", HINT_SKIP_TASKBAR }, - { "skip_pager", HINT_SKIP_PAGER } -}; - -std::pair -window_hints_traits::convert(lua::state &l, int index, const std::string &name) -{ - typedef conky::lua_traits Traits; - - lua::stack_sentry s(l); - l.checkstack(1); - - std::string hints = l.tostring(index); - // add a sentinel to simplify the following loop - hints += ','; - size_t pos = 0; - size_t newpos; - uint16_t ret = 0; - while((newpos = hints.find_first_of(", ", pos)) != std::string::npos) { - if(newpos > pos) { - l.pushstring(hints.substr(pos, newpos-pos)); - auto t = conky::lua_traits::convert(l, -1, name); - if(not t.second) - return {0, false}; - SET_HINT(ret, t.first); - l.pop(); - } - pos = newpos+1; - } - return {ret, true}; -} - -conky::simple_config_setting own_window_hints("own_window_hints", - 0, false); - -conky::simple_config_setting background_colour("background_colour", "black", false); - -#ifdef BUILD_ARGB -conky::simple_config_setting use_argb_visual("own_window_argb_visual", false, false); -conky::range_config_setting own_window_argb_value("own_window_argb_value", - 0, 255, 255, false); -#endif -#endif /*OWN_WINDOW*/ diff --git a/src/x11.h b/src/x11.h index 5a76b552..e7aba663 100644 --- a/src/x11.h +++ b/src/x11.h @@ -174,9 +174,6 @@ struct window_hints_traits { }; extern conky::simple_config_setting own_window_hints; -// this setting is not checked for validity when set, we leave that to the caller -// the reason for that is that we need to have X initialised in order to call XParseColor() -extern conky::simple_config_setting background_colour; #ifdef BUILD_ARGB extern conky::simple_config_setting use_argb_visual;