Add DPI support and 'xresources' theme

This makes awesome respect DPI settings, and adds a new theme based on
xrdb and xsettingsd color settings ("xresources").

Closes https://github.com/awesomeWM/awesome/pull/229
This commit is contained in:
actionless 2015-05-14 22:57:22 +02:00 committed by Daniel Hahler
parent 61275ccba0
commit cec04b2684
11 changed files with 479 additions and 2 deletions

View File

@ -55,6 +55,7 @@ set(AWE_SRCS
${BUILD_DIR}/systray.c ${BUILD_DIR}/systray.c
${BUILD_DIR}/xwindow.c ${BUILD_DIR}/xwindow.c
${BUILD_DIR}/xkb.c ${BUILD_DIR}/xkb.c
${BUILD_DIR}/xrdb.c
${BUILD_DIR}/common/atoms.c ${BUILD_DIR}/common/atoms.c
${BUILD_DIR}/common/backtrace.c ${BUILD_DIR}/common/backtrace.c
${BUILD_DIR}/common/buffer.c ${BUILD_DIR}/common/buffer.c
@ -136,6 +137,7 @@ add_custom_target(generated_sources
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/default) file(MAKE_DIRECTORY ${BUILD_DIR}/themes/default)
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/sky) file(MAKE_DIRECTORY ${BUILD_DIR}/themes/sky)
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/zenburn) file(MAKE_DIRECTORY ${BUILD_DIR}/themes/zenburn)
file(MAKE_DIRECTORY ${BUILD_DIR}/themes/xresources)
add_dependencies(${PROJECT_AWE_NAME} generated_sources) add_dependencies(${PROJECT_AWE_NAME} generated_sources)
# }}} # }}}

View File

@ -53,6 +53,9 @@
#include <xcb/xtest.h> #include <xcb/xtest.h>
#include <xcb/shape.h> #include <xcb/shape.h>
#include <X11/Xlib-xcb.h>
#include <X11/XKBlib.h>
#include <glib-unix.h> #include <glib-unix.h>
awesome_t globalconf; awesome_t globalconf;
@ -412,8 +415,16 @@ main(int argc, char **argv)
/* We have no clue where the input focus is right now */ /* We have no clue where the input focus is right now */
globalconf.focus.need_update = true; globalconf.focus.need_update = true;
/* XLib sucks */
XkbIgnoreExtension(True);
/* X stuff */ /* X stuff */
globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); globalconf.display = XOpenDisplay(NULL);
if (globalconf.display == NULL)
fatal("Cannot open display");
XSetEventQueueOwner(globalconf.display, XCBOwnsEventQueue);
globalconf.default_screen = XDefaultScreen(globalconf.display);
globalconf.connection = XGetXCBConnection(globalconf.display);;
if(xcb_connection_has_error(globalconf.connection)) if(xcb_connection_has_error(globalconf.connection))
fatal("cannot open display (error %d)", xcb_connection_has_error(globalconf.connection)); fatal("cannot open display (error %d)", xcb_connection_has_error(globalconf.connection));

View File

@ -130,6 +130,7 @@ pkg_check_modules(AWESOME_REQUIRED REQUIRED
gdk-pixbuf-2.0 gdk-pixbuf-2.0
cairo cairo
x11 x11
x11-xcb
xcb-cursor xcb-cursor
xcb-randr xcb-randr
xcb-xtest xcb-xtest

View File

@ -30,6 +30,7 @@
#include <xcb/xcb_icccm.h> #include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h> #include <xcb/xcb_keysyms.h>
#include <xcb/xcb_cursor.h> #include <xcb/xcb_cursor.h>
#include <X11/Xresource.h>
#include "objects/key.h" #include "objects/key.h"
#include "common/xembed.h" #include "common/xembed.h"
@ -65,6 +66,10 @@ ARRAY_TYPE(xproperty_t, xproperty)
/** Main configuration structure */ /** Main configuration structure */
typedef struct typedef struct
{ {
/** Xlib Display */
Display *display;
/** X Resources DB */
XrmDatabase xrmdb;
/** Connection ref */ /** Connection ref */
xcb_connection_t *connection; xcb_connection_t *connection;
/** Default screen number */ /** Default screen number */

View File

@ -27,7 +27,9 @@ local capi =
awesome = awesome awesome = awesome
} }
local beautiful = { mt = {} } local xresources = require("beautiful.xresources")
local beautiful = { xresources = xresources, mt = {} }
-- Local data -- Local data
local theme = {} local theme = {}
@ -50,6 +52,7 @@ local function load_font(name)
-- Load new font -- Load new font
local desc = Pango.FontDescription.from_string(name) local desc = Pango.FontDescription.from_string(name)
local ctx = PangoCairo.font_map_get_default():create_context() local ctx = PangoCairo.font_map_get_default():create_context()
ctx:set_resolution(beautiful.xresources.get_dpi())
-- Apply default values from the context (e.g. a default font size) -- Apply default values from the context (e.g. a default font size)
desc:merge(ctx:get_font_description(), false) desc:merge(ctx:get_font_description(), false)

View File

@ -0,0 +1,82 @@
----------------------------------------------------------------------------
--- Library for getting xrdb data.
--
-- @author Yauhen Kirylau &lt;yawghen@gmail.com&gt;
-- @copyright 2015 Yauhen Kirylau
-- @release @AWESOME_VERSION@
-- @module beautiful.xresources
----------------------------------------------------------------------------
-- Grab environment
local print = print
local awesome = awesome
local xresources = {}
local fallback = {
--black
color0 = '#000000',
color8 = '#465457',
--red
color1 = '#cb1578',
color9 = '#dc5e86',
--green
color2 = '#8ecb15',
color10 = '#9edc60',
--yellow
color3 = '#cb9a15',
color11 = '#dcb65e',
--blue
color4 = '#6f15cb',
color12 = '#7e5edc',
--purple
color5 = '#cb15c9',
color13 = '#b75edc',
--cyan
color6 = '#15b4cb',
color14 = '#5edcb4',
--white
color7 = '#888a85',
color15 = '#ffffff',
--
background = '#0e0021',
foreground = '#bcbcbc',
}
--- Get current base colorscheme from xrdb.
-- @treturn table Color table with keys 'background', 'foreground' and 'color0'..'color15'
function xresources.get_current_theme()
local keys = { 'background', 'foreground' }
for i=0,15 do table.insert(keys, "color"..i) end
local colors = {}
for _, key in ipairs(keys) do
colors[key] = awesome.xrdb_get_value("", key)
if not colors[key] then
print("W: beautiful: can't get colorscheme from xrdb (using fallback).")
return fallback
end
end
return colors
end
--- Get DPI value from xrdb.
-- @treturn number DPI value.
function xresources.get_dpi()
if not xresources.dpi then
xresources.dpi = tonumber(awesome.xrdb_get_value("", "Xft.dpi") or 96)
end
return xresources.dpi
end
--- Compute resulting size applying current DPI value.
-- @tparam number size Size
-- @treturn number Resulting size
function xresources.apply_dpi(size)
return size/96*xresources.get_dpi()
end
return xresources
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -132,6 +132,7 @@ local function new(text, ignore_markup)
end end
local ctx = PangoCairo.font_map_get_default():create_context() local ctx = PangoCairo.font_map_get_default():create_context()
ctx:set_resolution(beautiful.xresources.get_dpi())
ret._layout = Pango.Layout.new(ctx) ret._layout = Pango.Layout.new(ctx)
ret:set_ellipsize("end") ret:set_ellipsize("end")

2
luaa.c
View File

@ -46,6 +46,7 @@
#include "spawn.h" #include "spawn.h"
#include "systray.h" #include "systray.h"
#include "xkb.h" #include "xkb.h"
#include "xrdb.h"
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
@ -366,6 +367,7 @@ luaA_init(xdgHandle* xdg)
{ "xkb_set_layout_group", luaA_xkb_set_layout_group}, { "xkb_set_layout_group", luaA_xkb_set_layout_group},
{ "xkb_get_layout_group", luaA_xkb_get_layout_group}, { "xkb_get_layout_group", luaA_xkb_get_layout_group},
{ "xkb_get_group_names", luaA_xkb_get_group_names}, { "xkb_get_group_names", luaA_xkb_get_group_names},
{ "xrdb_get_value", luaA_xrdb_get_value},
{ NULL, NULL } { NULL, NULL }
}; };

267
themes/xresources/theme.lua Normal file
View File

@ -0,0 +1,267 @@
---------------------------------------------
-- Awesome theme which follows xrdb config --
-- by Yauhen Kirylau --
---------------------------------------------
local xresources = require("beautiful").xresources
local xrdb = xresources.get_current_theme()
local dpi = xresources.apply_dpi
local theme = {}
theme.font = "sans 8"
theme.bg_normal = xrdb.background
theme.bg_focus = xrdb.color12
theme.bg_urgent = xrdb.color9
theme.bg_minimize = xrdb.color8
theme.bg_systray = theme.bg_normal
theme.fg_normal = xrdb.foreground
theme.fg_focus = theme.bg_normal
theme.fg_urgent = theme.bg_normal
theme.fg_minimize = theme.bg_normal
theme.border_width = dpi(1)
theme.border_normal = xrdb.color0
theme.border_focus = theme.bg_focus
theme.border_marked = xrdb.color10
-- There are other variable sets
-- overriding the default one when
-- defined, the sets are:
-- taglist_[bg|fg]_[focus|urgent|occupied|empty]
-- tasklist_[bg|fg]_[focus|urgent]
-- titlebar_[bg|fg]_[normal|focus]
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
-- Example:
--theme.taglist_bg_focus = "#ff0000"
-- Variables set for theming the menu:
-- menu_[bg|fg]_[normal|focus]
-- menu_[border_color|border_width]
theme.menu_submenu_icon = "@AWESOME_THEMES_PATH@/default/submenu.png"
theme.menu_height = dpi(16)
theme.menu_width = dpi(100)
-- You can add as many variables as
-- you wish and access them by using
-- beautiful.variable in your rc.lua
--theme.bg_widget = "#cc0000"
-- Define the image to load
theme.titlebar_close_button_normal = "@AWESOME_THEMES_PATH@/default/titlebar/close_normal.png"
theme.titlebar_close_button_focus = "@AWESOME_THEMES_PATH@/default/titlebar/close_focus.png"
theme.titlebar_ontop_button_normal_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_active = "@AWESOME_THEMES_PATH@/default/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_active = "@AWESOME_THEMES_PATH@/default/titlebar/ontop_focus_active.png"
theme.titlebar_sticky_button_normal_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/sticky_normal_inactive.png"
theme.titlebar_sticky_button_focus_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_active = "@AWESOME_THEMES_PATH@/default/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_active = "@AWESOME_THEMES_PATH@/default/titlebar/sticky_focus_active.png"
theme.titlebar_floating_button_normal_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/floating_normal_inactive.png"
theme.titlebar_floating_button_focus_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_active = "@AWESOME_THEMES_PATH@/default/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active = "@AWESOME_THEMES_PATH@/default/titlebar/floating_focus_active.png"
theme.titlebar_maximized_button_normal_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive = "@AWESOME_THEMES_PATH@/default/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active = "@AWESOME_THEMES_PATH@/default/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_active = "@AWESOME_THEMES_PATH@/default/titlebar/maximized_focus_active.png"
-- Use 'w' postfix for dark background:
local bg_numberic_value = 0;
for s in theme.bg_normal:gmatch("[a-fA-F0-9][a-fA-F0-9]") do
bg_numberic_value = bg_numberic_value + tonumber("0x"..s);
end
local is_dark_bg = (bg_numberic_value < 383)
local pf = is_dark_bg and 'w' or ''
-- You can use your own layout icons like this:
theme.layout_fairh = "@AWESOME_THEMES_PATH@/default/layouts/fairh" .. pf .. ".png"
theme.layout_fairv = "@AWESOME_THEMES_PATH@/default/layouts/fairv" .. pf .. ".png"
theme.layout_floating = "@AWESOME_THEMES_PATH@/default/layouts/floating" .. pf .. ".png"
theme.layout_magnifier = "@AWESOME_THEMES_PATH@/default/layouts/magnifier" .. pf .. ".png"
theme.layout_max = "@AWESOME_THEMES_PATH@/default/layouts/max" .. pf .. ".png"
theme.layout_fullscreen = "@AWESOME_THEMES_PATH@/default/layouts/fullscreen" .. pf .. ".png"
theme.layout_tilebottom = "@AWESOME_THEMES_PATH@/default/layouts/tilebottom" .. pf .. ".png"
theme.layout_tileleft = "@AWESOME_THEMES_PATH@/default/layouts/tileleft" .. pf .. ".png"
theme.layout_tile = "@AWESOME_THEMES_PATH@/default/layouts/tile" .. pf .. ".png"
theme.layout_tiletop = "@AWESOME_THEMES_PATH@/default/layouts/tiletop" .. pf .. ".png"
theme.layout_spiral = "@AWESOME_THEMES_PATH@/default/layouts/spiral" .. pf .. ".png"
theme.layout_dwindle = "@AWESOME_THEMES_PATH@/default/layouts/dwindle" .. pf .. ".png"
-- Define the icon theme for application icons. If not set then the icons
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = nil
--------------------------------------------------
-- Generate vector assets using current colors: --
--------------------------------------------------
local cairo = require("lgi").cairo
local gears = require("gears")
local function awesome_icon()
local size = theme.menu_height
local img = cairo.ImageSurface(cairo.Format.ARGB32, size, size)
local cr = cairo.Context(img)
cr:set_source(gears.color(theme.bg_focus))
cr:paint()
cr:set_source(gears.color(theme.fg_focus))
cr:set_line_width(size/20)
cr:move_to(0, size/3)
cr:line_to(size*2/3, size/3)
cr:move_to(size/3, size*2/3)
cr:line_to(size*2/3, size*2/3)
cr:line_to(size*2/3, size)
cr:stroke()
return img
end
theme.awesome_icon = awesome_icon()
-- Taglist squares:
local taglist_square_size = dpi(4)
local function taglist_squares_sel()
local size = taglist_square_size
local img = cairo.ImageSurface(cairo.Format.ARGB32, size, size)
local cr = cairo.Context(img)
cr:set_source(gears.color(theme.fg_normal))
cr:paint()
return img
end
theme.taglist_squares_sel = taglist_squares_sel()
local function taglist_squares_unsel()
local size = taglist_square_size
local img = cairo.ImageSurface(cairo.Format.ARGB32, size, size)
local cr = cairo.Context(img)
cr:set_source(gears.color(theme.fg_normal))
cr:set_line_width(size/4)
cr:rectangle(0, 0, size, size)
cr:stroke()
return img
end
theme.taglist_squares_unsel = taglist_squares_unsel()
local function wallpaper()
local height = screen[1].workarea.height
local width = screen[1].workarea.width
local img = cairo.ImageSurface(cairo.Format.ARGB32, width, height)
local cr = cairo.Context(img)
local bg = xrdb.color8
local fg = xrdb.color7
local alt_fg = xrdb.color12
if not is_dark_bg then
bg, fg = fg, bg
end
local letter_size = height/10
local letter_line = letter_size/18
local letter_gap = letter_size/6
local letter_start_x = width - width / 10
local letter_start_y = height / 10
local function make_letter(n, lines, color)
local function make_line(coords)
for i, coord in ipairs(coords) do
if i == 1 then
cr:rel_move_to(coord[1], coord[2])
else
cr:rel_line_to(coord[1], coord[2])
end
end
cr:stroke()
end
lines = lines or {}
color = color or fg
cr:set_source(gears.color(color))
cr:rectangle(
letter_start_x, letter_start_y+(letter_size+letter_gap)*n,
letter_size, letter_size
)
cr:fill()
cr:set_source(gears.color(bg))
for _, line in ipairs(lines) do
cr:move_to(letter_start_x, letter_start_y+(letter_size+letter_gap)*n)
make_line(line)
end
end
-- bg
cr:set_source(gears.color(bg))
cr:paint()
cr:set_line_width(letter_line)
local ls = letter_size
-- a
make_letter(0, { {
{ 0, ls/3 },
{ ls*2/3, 0 },
}, {
{ ls/3, ls*2/3 },
{ ls/3, 0 },
{ 0, ls/3 },
} }, alt_fg)
-- w
make_letter(1, { {
{ ls/3, 0 },
{ 0,ls*2/3 },
}, {
{ ls*2/3, 0 },
{ 0,ls*2/3 },
} })
-- e
make_letter(2, { {
{ ls/3, ls/3 },
{ ls*2/3, 0 },
}, {
{ ls/3, ls*2/3 },
{ ls*2/3, 0 },
} })
-- s
make_letter(3, { {
{ ls/3, ls/3 },
{ ls*2/3, 0 },
}, {
{ 0, ls*2/3 },
{ ls*2/3, 0 },
} })
-- o
make_letter(4, { {
{ ls/2, ls/3 },
{ 0, ls/3 },
} })
-- m
make_letter(5, { {
{ ls/3, ls/3 },
{ 0,ls*2/3 },
}, {
{ ls*2/3, ls/3 },
{ 0,ls*2/3 },
} })
-- e
make_letter(6, { {
{ ls/3, ls/3 },
{ ls*2/3, 0 },
}, {
{ ls/3, ls*2/3 },
{ ls*2/3, 0 },
} })
return img
end
theme.wallpaper = wallpaper()
return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

73
xrdb.c Normal file
View File

@ -0,0 +1,73 @@
/*
* xrdb.c - X Resources DataBase communication functions
*
* Copyright © 2015 Yauhen Kirylau <yawghen@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "xrdb.h"
#include "globalconf.h"
#include <X11/Xresource.h>
#include <string.h>
/* \brief open X display and X Resources DB
*/
static void xrdb_init(void) {
XrmInitialize(); // @TODO: it works without it but in docs it's said what it's
// needed
if (!(globalconf.xrmdb = XrmGetDatabase(globalconf.display))) {
/* taken from xpbiff: */
/* >> what a hack; need to initialize dpy->db */
(void)XGetDefault(globalconf.display, "", "");
/**/
if (!(globalconf.xrmdb = XrmGetDatabase(globalconf.display)))
warn("Can't open xrdb\n");
}
}
/* \brief get value from X Resources DataBase
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam string xrdb class, ie "URxvt" or ""
* \lparam string xrdb name, ie "background" or "color0"
* \lreturn string xrdb value or nil if not exists. \
*/
int luaA_xrdb_get_value(lua_State *L) {
if (!globalconf.xrmdb)
xrdb_init();
char *resource_type;
int resource_code;
XrmValue resource_value;
const char *resource_class = luaL_checkstring(L, 1);
const char *resource_name = luaL_checkstring(L, 2);
resource_code = XrmGetResource(globalconf.xrmdb, resource_name, resource_class,
&resource_type, &resource_value);
if (resource_code && (strcmp(resource_type, "String") == 0)) {
lua_pushstring(L, (char *)resource_value.addr);
return 1;
} else {
luaA_warn(L, "Failed to get xrdb value");
return 0;
}
}

30
xrdb.h Normal file
View File

@ -0,0 +1,30 @@
/*
* xrdb.h - X Resources DataBase communication functions
*
* Copyright © 2015 Yauhen Kirylau <yawghen@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef AWESOME_XRDB_H
#define AWESOME_XRDB_H
#include <lua.h>
int luaA_xrdb_get_value(lua_State *L);
#endif