Hi, don't you miss the good old times? Where men where men and awesome upgrades were awful? Where the config broke every time you sneezed? Where there was a land flowing with milk and honey?
Fear no more, the breakage is back! In August 2010, I made git/master use oocairo. That brought us a new widget system (again...) and gave people all of cairo's power for drawing stuff! That was back then. Now, the new kid in town is lgi[0] and attached are the patches which make awesome us that instead of oocairo/oopango. People might wonder why this switch should happen. "Why not?" is what I reply. :-P Also, lgi uses GObject introspection for most of its magic. This means that it is way easier to add bindings, because most of the stuff is done automagically. Currently, lgi provides bindings for cairo, pango, gtk, clutter and gstreamer (but others might work without any magic and out-of-the-box). Yet another reason is that oocairo and lgi.cairo do the same thing. Why would we want two lua bindings for cairo? That just duplicates effort! And finally, the upstream dev for oocairo and oopango is a lazy bastard who lets it slowly bitrot away. oopango never was in a good state and adding cairo 1.12's new function to oocairo needs way more work/lines than with lgi. Now the downside: Current lgi.cairo's user_to_device() binding is broken. This function is needed for my hacky widget system and thus awesome doesn't work. One of the patch 0001's that I attached are for lgi and should fix this (already sent upstream, but upstream is offline for a week). The other patch 0001 and patch 0002 port over awesome. However, one more downside: No configs should break and no config changes are needed (unless you do weird things in your config, e.g. I had to change something!). Once the lgi patch is upstream (and perhaps even got into some release), I intend to push this. So now that I talked so much nonsense: What do others think about these patches? Any major objections which I will have to ignore when I push? :-P Cheers, Uli P.S.: Yes, I did exaggerate when I said "breakage". This just changes some dependencies. [0]: https://github.com/pavouk/lgi -- - He made himself, me nothing, you nothing out of the dust - Er machte sich mir nichts, dir nichts aus dem Staub
>From d0612cfd5bf71d7c331d7c9db9230f085b4b19f5 Mon Sep 17 00:00:00 2001 From: Uli Schlachter <[email protected]> Date: Sat, 26 May 2012 23:24:32 +0200 Subject: [PATCH 1/1] cairo: Fix cr:user_to_device() and friends All of these functions have inout params, not just out. Also, user_to_device_distance was missing. Signed-off-by: Uli Schlachter <[email protected]> --- lgi/override/cairo.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lgi/override/cairo.lua b/lgi/override/cairo.lua index 4b9e2a8..32e9c75 100644 --- a/lgi/override/cairo.lua +++ b/lgi/override/cairo.lua @@ -245,12 +245,14 @@ for _, info in ipairs { set_matrix = { cairo.Matrix }, get_matrix = { cairo.Matrix }, identity_matrix = {}, - user_to_device = { { ti.double, dir = 'out' }, - { ti.double, dir = 'out' } }, - device_to_user = { { ti.double, dir = 'out' }, - { ti.double, dir = 'out' } }, - device_to_user_distance = { { ti.double, dir = 'out' }, - { ti.double, dir = 'out' } }, + user_to_device = { { ti.double, dir = 'inout' }, + { ti.double, dir = 'inout' } }, + user_to_device_distance = { { ti.double, dir = 'inout' }, + { ti.double, dir = 'inout' } }, + device_to_user = { { ti.double, dir = 'inout' }, + { ti.double, dir = 'inout' } }, + device_to_user_distance = { { ti.double, dir = 'inout' }, + { ti.double, dir = 'inout' } }, select_font_face = { ti.utf8, cairo.FontSlant, cairo.FontWeight }, set_font_size = { ti.double }, -- 1.7.10
>From 4f30dfd198cacd08df062813e705ebb687b3d9a4 Mon Sep 17 00:00:00 2001 From: Uli Schlachter <[email protected]> Date: Sun, 27 May 2012 19:20:34 +0200 Subject: [PATCH 1/2] Switch from oocairo to lgi.cairo Signed-off-by: Uli Schlachter <[email protected]> --- awesomeConfig.cmake | 2 - draw.c | 8 ++-- draw.h | 2 +- lib/awful/menu.lua.in | 18 ++++---- lib/awful/widget/button.lua.in | 21 +++------ lib/awful/widget/layoutbox.lua.in | 1 - lib/awful/widget/taglist.lua.in | 7 +-- lib/beautiful.lua.in | 22 ++++------ lib/gears/color.lua.in | 20 ++++----- lib/gears/init.lua.in | 1 + lib/gears/surface.lua.in | 35 +++++++++++++++ lib/naughty.lua.in | 21 ++++----- lib/wibox/init.lua.in | 15 ++++--- lib/wibox/widget/background.lua.in | 14 ++---- lib/wibox/widget/imagebox.lua.in | 12 +++--- lib/wibox/widget/textbox.lua.in | 82 ++++++++++++------------------------ luaa.c | 17 -------- luadoc/awesome.lua | 2 +- luadoc/drawin.lua | 2 +- objects/client.c | 24 +++++------ objects/drawin.c | 4 +- root.c | 8 ++-- 22 files changed, 151 insertions(+), 187 deletions(-) create mode 100644 lib/gears/surface.lua.in diff --git a/awesomeConfig.cmake b/awesomeConfig.cmake index c50295e..fc8492d 100644 --- a/awesomeConfig.cmake +++ b/awesomeConfig.cmake @@ -132,8 +132,6 @@ pkg_check_modules(AWESOME_REQUIRED REQUIRED glib-2.0 cairo x11 - oocairo - oopango xcb-randr xcb-xtest xcb-xinerama diff --git a/draw.c b/draw.c index a2dd511..dc8a60d 100644 --- a/draw.c +++ b/draw.c @@ -133,12 +133,10 @@ luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data) /* This makes sure that buffer will be freed */ cairo_surface_set_user_data(surface, &data_key, buffer, &free_data); - /* This will increase the reference count of the surface */ - int ret = oocairo_surface_push(globalconf.L, surface); - /* So we have to drop our own reference */ - cairo_surface_destroy(surface); + /* lua has to make sure to free the ref or we have a leak */ + lua_pushlightuserdata(L, surface); - return ret; + return 1; } /** Duplicate the specified image surface. diff --git a/draw.h b/draw.h index c039d55..c87db2d 100644 --- a/draw.h +++ b/draw.h @@ -23,7 +23,7 @@ #define AWESOME_COMMON_DRAW_H #include <xcb/xcb.h> -#include <oocairo.h> +#include <cairo.h> #include "common/util.h" diff --git a/lib/awful/menu.lua.in b/lib/awful/menu.lua.in index 76e5278..07a4953 100644 --- a/lib/awful/menu.lua.in +++ b/lib/awful/menu.lua.in @@ -13,6 +13,8 @@ local tags = require("awful.tag") local keygrabber = require("awful.keygrabber") local beautiful = require("beautiful") local object = require("gears.object") +local surface = require("gears.surface") +local cairo = require("lgi").cairo local setmetatable = setmetatable local tonumber = tonumber local string = string @@ -27,9 +29,7 @@ local capi = { timer = timer, screen = screen, mouse = mouse, - client = client, - awesome = awesome, - oocairo = oocairo } + client = client } module("awful.menu") @@ -515,7 +515,7 @@ function entry(parent, args) if args.icon then icon = args.icon if type(icon) == "string" then - icon = capi.awesome.load_image(icon) + icon = surface.load(icon) end end if icon then @@ -529,10 +529,10 @@ function entry(parent, args) w, h = (args.theme.height / ih) * iw, args.theme.height end -- We need to scale the image to size w x h - local img = capi.oocairo.image_surface_create("argb32", w, h) - local cr = capi.oocairo.context_create(img) + local img = cairo.ImageSurface(cairo.Format.ARGB32, w, h) + local cr = cairo.Context(img) cr:scale(w / iw, h / ih) - cr:set_source(icon, 0, 0) + cr:set_source_surface(icon, 0, 0) cr:paint() icon = img end @@ -551,9 +551,7 @@ function entry(parent, args) if type(args.cmd) == "table" then if args.theme.submenu_icon then submenu = wibox.widget.imagebox() - submenu:set_image( - capi.awesome.load_image( - args.theme.submenu_icon)) + submenu:set_image(surface.load(args.theme.submenu_icon)) else submenu = wibox.widget.textbox() submenu:set_font(args.theme.font) diff --git a/lib/awful/widget/button.lua.in b/lib/awful/widget/button.lua.in index 7647cd0..29c5aeb 100644 --- a/lib/awful/widget/button.lua.in +++ b/lib/awful/widget/button.lua.in @@ -8,9 +8,9 @@ local setmetatable = setmetatable local type = type local button = require("awful.button") local imagebox = require("wibox.widget.imagebox") -local capi = { mouse = mouse, - awesome = awesome, - oocairo = oocairo } +local surface = require("gears.surface") +local cairo = require("lgi").cairo +local capi = { mouse = mouse } module("awful.widget.button") @@ -20,17 +20,10 @@ module("awful.widget.button") -- @return A textbox widget configured as a button. function new(args) if not args or not args.image then return end - local img_release - if type(args.image) == "string" then - img_release = capi.awesome.load_image(args.image) - elseif type(args.image) == "userdata" and args.image.type and args.image:type() == "cairo_surface_t" then - img_release = args.image - elseif type(args.image) == "userdata" and args.image._NAME and args.image._NAME == "cairo surface object" then - img_release = args.image - end - local img_press = capi.oocairo.image_surface_create("argb32", img_release:get_width(), img_release:get_height()) - local cr = capi.oocairo.context_create(img_press) - cr:set_source(img_release, 2, 2) + local img_release = surface.load(args.image) + local img_press = cairo.ImageSurface(cairo.Format.ARGB32, img_release.width, img_release.height) + local cr = cairo.Context(img_press) + cr:set_source_surface(img_release, 2, 2) cr:paint() local w = imagebox() diff --git a/lib/awful/widget/layoutbox.lua.in b/lib/awful/widget/layoutbox.lua.in index 1723ee5..43e98ba 100644 --- a/lib/awful/widget/layoutbox.lua.in +++ b/lib/awful/widget/layoutbox.lua.in @@ -11,7 +11,6 @@ local layout = require("awful.layout") local tag = require("awful.tag") local beautiful = require("beautiful") local imagebox = require("wibox.widget.imagebox") -local capi = { oocairo = oocairo } --- Layoutbox widget. module("awful.widget.layoutbox") diff --git a/lib/awful/widget/taglist.lua.in b/lib/awful/widget/taglist.lua.in index a6ec7f6..13f50fb 100644 --- a/lib/awful/widget/taglist.lua.in +++ b/lib/awful/widget/taglist.lua.in @@ -18,6 +18,7 @@ local util = require("awful.util") local tag = require("awful.tag") local beautiful = require("beautiful") local fixed = require("wibox.layout.fixed") +local surface = require("gears.surface") --- Taglist widget module for awful module("awful.widget.taglist") @@ -55,7 +56,7 @@ function taglist_label(t, args) local seltags = sel:tags() for _, v in ipairs(seltags) do if v == t then - bg_image = capi.awesome.load_image(taglist_squares_sel) + bg_image = surface.load(taglist_squares_sel) bg_resize = taglist_squares_resize == "true" is_selected = true break @@ -67,7 +68,7 @@ function taglist_label(t, args) local cls = t:clients() if #cls > 0 then if taglist_squares_unsel then - bg_image = capi.awesome.load_image(taglist_squares_unsel) + bg_image = surface.load(taglist_squares_unsel) bg_resize = taglist_squares_resize == "true" end if bg_occupied then bg_color = bg_occupied end @@ -93,7 +94,7 @@ function taglist_label(t, args) if tag.geticon(t) and type(tag.geticon(t)) == "image" then icon = tag.geticon(t) elseif tag.geticon(t) then - icon = capi.awesome.load_image(tag.geticon(t)) + icon = surface.load(tag.geticon(t)) end return text, bg_color, bg_image, icon diff --git a/lib/beautiful.lua.in b/lib/beautiful.lua.in index d67dcd3..8b7ddd5 100644 --- a/lib/beautiful.lua.in +++ b/lib/beautiful.lua.in @@ -14,12 +14,14 @@ local type = type local dofile = dofile local setmetatable = setmetatable local util = require("awful.util") +local lgi = require("lgi") +local cairo = lgi.cairo +local Pango = lgi.Pango +local PangoCairo = lgi.PangoCairo local capi = { screen = screen, - awesome = awesome, - oocairo = oocairo, - oopango = oopango + awesome = awesome } --- Theme library. @@ -40,19 +42,11 @@ local function load_font(name) return fonts[name] end -- load new font - local desc = capi.oopango.font_description_from_string(name) + local desc = Pango.FontDescription.from_string(name) -- Create a temporary surface that we need for computing the size :( - local surface = capi.oocairo.image_surface_create("argb32", 1, 1) - local cr = capi.oocairo.context_create(surface) - local layout - -- Api breakage in oopango - if capi.oopango.cairo_layout_create then - layout = capi.oopango.cairo_layout_create(cr) - else - layout = capi.oopango.cairo.layout_create(cr) - end - + local surface = cairo.ImageSurface(cairo.Format.ARGB32, 1, 1) + local layout = PangoCairo.create_layout(cairo.Context(surface)) layout:set_font_description(desc) local width, height = layout:get_pixel_size() diff --git a/lib/gears/color.lua.in b/lib/gears/color.lua.in index 1299ff6..14d1aa4 100644 --- a/lib/gears/color.lua.in +++ b/lib/gears/color.lua.in @@ -12,10 +12,8 @@ local unpack = unpack local ipairs = ipairs local pairs = pairs local type = type -local capi = { - awesome = awesome, - oocairo = oocairo -} +local cairo = require("lgi").cairo +local surface = require("gears.surface") module("gears.color") @@ -60,7 +58,7 @@ function create_solid_pattern(col) elseif type(col) == "table" then col = col.color end - return capi.oocairo.pattern_create_rgba(parse_color(col)) + return cairo.Pattern.create_rgba(parse_color(col)) end --- Create an image pattern from a png file @@ -71,8 +69,8 @@ function create_png_pattern(file) if type(file) == "table" then file = file.file end - local image = capi.awesome.load_image(file) - return capi.oocairo.pattern_create_for_surface(image) + local image = surface.load(file) + return cairo.Pattern.create_for_surface(image) end -- Add stops to the given pattern. @@ -125,12 +123,12 @@ function create_linear_pattern(arg) local pat if type(arg) == "string" then - return string_pattern(capi.oocairo.pattern_create_linear, arg) + return string_pattern(cairo.Pattern.create_linear, arg) elseif type(arg) ~= "table" then error("Wrong argument type: " .. type(arg)) end - pat = capi.oocairo.pattern_create_linear(arg.from[1], arg.from[2], arg.to[1], arg.to[2]) + pat = cairo.Pattern.create_linear(arg.from[1], arg.from[2], arg.to[1], arg.to[2]) add_stops_table(pat, arg.stops) return pat end @@ -150,12 +148,12 @@ function create_radial_pattern(arg) local pat if type(arg) == "string" then - return string_pattern(capi.oocairo.pattern_create_radial, arg) + return string_pattern(cairo.Pattern.create_radial, arg) elseif type(arg) ~= "table" then error("Wrong argument type: " .. type(arg)) end - pat = capi.oocairo.pattern_create_radial(arg.from[1], arg.from[2], arg.from[3], + pat = cairo.Pattern.create_radial(arg.from[1], arg.from[2], arg.from[3], arg.to[1], arg.to[2], arg.to[3]) add_stops_table(pat, arg.stops) return pat diff --git a/lib/gears/init.lua.in b/lib/gears/init.lua.in index dcc4c27..f8864a1 100644 --- a/lib/gears/init.lua.in +++ b/lib/gears/init.lua.in @@ -8,6 +8,7 @@ require("gears.color") require("gears.debug") require("gears.object") require("gears.sort") +require("gears.surface") module("gears") diff --git a/lib/gears/surface.lua.in b/lib/gears/surface.lua.in new file mode 100644 index 0000000..df38db8 --- /dev/null +++ b/lib/gears/surface.lua.in @@ -0,0 +1,35 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2012 Uli Schlachter +-- @release @AWESOME_VERSION@ +--------------------------------------------------------------------------- + +local setmetatable = setmetatable +local type = type +local capi = { awesome = awesome } +local cairo = require("lgi").cairo + +module("gears.surface") + +--- Try to convert the argument into an lgi cairo surface. +-- This is usually needed for loading images by file name. +function load(surface) + -- Nil is not changed + if not surface then + return nil + end + -- lgi cairo surfaces don't get changed either + if cairo.Surface:is_type_of(surface) then + return surface + end + -- Strings are assumed to be file names and get loaded + if type(surface) == "string" then + surface = capi.awesome.load_image(surface) + end + -- Everything else gets forced into a surface + return cairo.Surface(surface, true) +end + +setmetatable(_M, { __call = function(_, ...) return load(...) end }) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/naughty.lua.in b/lib/naughty.lua.in index cc6a374..7906638 100644 --- a/lib/naughty.lua.in +++ b/lib/naughty.lua.in @@ -14,12 +14,13 @@ local capi = { screen = screen, awesome = awesome, dbus = dbus, timer = timer, - awesome = awesome, - oocairo = oocairo } + awesome = awesome } local button = require("awful.button") local util = require("awful.util") local bt = require("beautiful") local wibox = require("wibox") +local surface = require("gears.surface") +local cairo = require("lgi").cairo --- Notification library module("naughty") @@ -399,17 +400,12 @@ function notify(args) if icon then iconbox = wibox.widget.imagebox() iconmargin = wibox.layout.margin(iconbox, margin, margin, margin, margin) - local img = icon - if type(icon) == "string" then - img = capi.awesome.load_image(icon) - else - img = icon - end + local img = surface.load(icon) if icon_size then - local scaled = capi.oocairo.image_surface_create("argb32", icon_size, icon_size) - local cr = capi.oocairo.context_create(scaled) + local scaled = cairo.ImageSurface(cairo.Format.ARGB32, icon_size, icon_size) + local cr = cairo.Context(scaled) cr:scale(icon_size / img:get_height(), icon_size / img:get_width()) - cr:set_source(img, 0, 0) + cr:set_source_surface(img, 0, 0) cr:paint() img = scaled end @@ -543,7 +539,8 @@ if capi.dbus then end end if imgdata then - args.icon = capi.oocairo.image_surface_create_from_data(imgdata, "argb32", hints.icon_data[1], hints.icon_data[2], hints.icon_data[1] * 4) + args.icon = cairo.ImageSurface.create_for_data(imgdata, + cairo.Format.ARGB32, hints.icon_data[1], hints.icon_data[2], hints.icon_data[1] * 4) end end if replaces_id and replaces_id ~= "" and replaces_id ~= 0 then diff --git a/lib/wibox/init.lua.in b/lib/wibox/init.lua.in index 02d7401..e02aa35 100644 --- a/lib/wibox/init.lua.in +++ b/lib/wibox/init.lua.in @@ -9,7 +9,6 @@ require("wibox.widget") local capi = { drawin = drawin, - oocairo = oocairo, root = root, awesome = awesome } @@ -17,11 +16,13 @@ local setmetatable = setmetatable local pairs = pairs local type = type local table = table +local string_format = string.format local color = require("gears.color") local object = require("gears.object") local sort = require("gears.sort") local beautiful = require("beautiful") -local string_format = string.format +local surface = require("gears.surface") +local cairo = require("lgi").cairo --- This provides widget box windows. Every wibox can also be used as if it were -- a drawin. All drawin functions and properties are also available on wiboxes! @@ -33,19 +34,19 @@ local function do_redraw(wibox) end local geom = wibox.drawin:geometry() - local cr = capi.oocairo.context_create(wibox.drawin.surface) + local cr = cairo.Context(surface(wibox.drawin.surface)) -- Draw the background cr:save() -- This is pseudo-transparency: We draw the wallpaper in the background - local wallpaper = capi.root.wallpaper() + local wallpaper = surface(capi.root.wallpaper()) if wallpaper then - cr:set_operator("source") - cr:set_source(wallpaper, -wibox.drawin.x, -wibox.drawin.y) + cr.operator = cairo.Operator.SOURCE + cr:set_source_surface(wallpaper, -wibox.drawin.x, -wibox.drawin.y) cr:paint() end - cr:set_operator("over") + cr.operator = cairo.Operator.OVER cr:set_source(wibox.background_color) cr:paint() cr:restore() diff --git a/lib/wibox/widget/background.lua.in b/lib/wibox/widget/background.lua.in index 89f9aa3..09ded3e 100644 --- a/lib/wibox/widget/background.lua.in +++ b/lib/wibox/widget/background.lua.in @@ -4,14 +4,14 @@ -- @release @AWESOME_VERSION@ --------------------------------------------------------------------------- -local oocairo = require("oocairo") local base = require("wibox.widget.base") local color = require("gears.color") local layout_base = require("wibox.layout.base") +local surface = require("gears.surface") +local cairo = require("lgi").cairo local setmetatable = setmetatable local pairs = pairs local type = type -local awesome = awesome module("wibox.widget.background") @@ -28,7 +28,7 @@ function draw(box, wibox, cr, width, height) cr:paint() end if box.bgimage then - local pattern = oocairo.pattern_create_for_surface(box.bgimage) + local pattern = cairo.Pattern.create_for_surface(box.bgimage) cr:set_source(pattern) cr:paint() end @@ -89,13 +89,7 @@ end --- Set the background image to use function set_bgimage(box, image) - local image = image - - if type(image) == "string" then - image = awesome.load_image(image) - end - - box.bgimage = image + box.bgimage = surface.load(image) box._emit_updated() end diff --git a/lib/wibox/widget/imagebox.lua.in b/lib/wibox/widget/imagebox.lua.in index 2e35ccb..14acb8a 100644 --- a/lib/wibox/widget/imagebox.lua.in +++ b/lib/wibox/widget/imagebox.lua.in @@ -5,12 +5,12 @@ --------------------------------------------------------------------------- local base = require("wibox.widget.base") +local surface = require("gears.surface") local setmetatable = setmetatable local pairs = pairs local type = type local pcall = pcall local print = print -local awesome = awesome module("wibox.widget.imagebox") @@ -30,7 +30,7 @@ function draw(box, wibox, cr, width, height) cr:scale(aspect, aspect) end - cr:set_source(box.image) + cr:set_source_surface(box.image, 0, 0) cr:paint() cr:restore() @@ -74,7 +74,7 @@ function set_image(box, image) local image = image if type(image) == "string" then - local success, result = pcall(awesome.load_image, image) + local success, result = pcall(surface.load, image) if not success then print("Error while reading '" .. image .. "': " .. result) return false @@ -82,9 +82,11 @@ function set_image(box, image) image = result end + image = surface.load(image) + if image then - local w = image:get_width() - local h = image:get_height() + local w = image.width + local h = image.height if w <= 0 or h <= 0 then return false end diff --git a/lib/wibox/widget/textbox.lua.in b/lib/wibox/widget/textbox.lua.in index 49f3958..e33bd4b 100644 --- a/lib/wibox/widget/textbox.lua.in +++ b/lib/wibox/widget/textbox.lua.in @@ -5,50 +5,30 @@ -- @release @AWESOME_VERSION@ --------------------------------------------------------------------------- -local oopango = require("oopango") -local oocairo = require("oocairo") local base = require("wibox.widget.base") local beautiful = require("beautiful") +local lgi = require("lgi") +local cairo = lgi.cairo +local Pango = lgi.Pango +local PangoCairo = lgi.PangoCairo local type = type local unpack = unpack local setmetatable = setmetatable local pairs = pairs +local error = error module("wibox.widget.textbox") -local function layout_create(cr) - if oopango.cairo_layout_create then - return oopango.cairo_layout_create(cr) - end - return oopango.cairo.layout_create(cr) -end - -local function layout_update(cr, layout) - if oopango.cairo_update_layout then - oopango.cairo_update_layout(cr, layout) - else - oopango.cairo.update_layout(cr, layout) - end -end - -local function layout_show(cr, layout) - if oopango.cairo_show_layout then - oopango.cairo_show_layout(cr, layout) - else - oopango.cairo.show_layout(cr, layout) - end -end - -- Setup a pango layout for the given textbox and cairo context local function setup_layout(box, width, height) local layout = box._layout - layout:set_width(oopango.units_from_number(width)) - layout:set_height(oopango.units_from_number(height)) + layout.width = Pango.units_from_double(width) + layout.height = Pango.units_from_double(height) end --- Draw the given textbox on the given cairo context in the given geometry function draw(box, wibox, cr, width, height) - layout_update(cr, box._layout) + cr:update_layout(box._layout) setup_layout(box, width, height) local ink, logical = box._layout:get_pixel_extents() local offset = 0 @@ -58,7 +38,7 @@ function draw(box, wibox, cr, width, height) offset = height - logical.height end cr:move_to(0, offset) - layout_show(cr, box._layout) + cr:show_layout(box._layout) end --- Fit the given textbox @@ -70,47 +50,37 @@ end -- Return a pango layout which can be used if no cairo context is available local function get_temp_layout() - local surface = oocairo.image_surface_create("argb32", 0, 0) - local cr = oocairo.context_create(surface) - return layout_create(cr) -end - -local temp_layout --- Test if a text is valid for a textbox. If it isn't, a lua error will be thrown. -local function check_text(text, markup) - if not temp_layout then - temp_layout = get_temp_layout() - end - - if markup then - temp_layout:set_markup(text) - else - temp_layout:set_text(text) - end + local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0) + local cr = cairo.Context(surface) + return PangoCairo.create_layout(cr) end --- Set a textbox' text. -- @param text The text to set. This can contain pango markup (e.g. <b>bold</b>) function set_markup(box, text) - check_text(text, true) - box._layout:set_markup(text) + local attr, parsed = Pango.parse_markup(text, -1, 0) + -- In case of error, attr is false and parsed is an error message + if not attr then error(parsed) end + + box._layout.text = parsed + box._layout.attributes = attr box:emit_signal("widget::updated") end --- Set a textbox' text. -- @param text The text to display. Pango markup is ignored and shown as-is. function set_text(box, text) - check_text(text, false) - box._layout:set_text(text) + box._layout.text = text + box._layout.attributes = nil box:emit_signal("widget::updated") end --- Set a textbox' ellipsize mode. -- @param mode Where should long lines be shortened? "start", "middle" or "end" function set_ellipsize(box, mode) - local allowed = { none = true, start = true, middle = true, ["end"] = true } + local allowed = { none = "NONE", start = "START", middle = "MIDDLE", ["end"] = "END" } if allowed[mode] then - box._layout:set_ellipsize(mode) + box._layout:set_ellipsize(allowed[mode]) box:emit_signal("widget::updated") end end @@ -118,9 +88,9 @@ end --- Set a textbox' wrap mode. -- @param mode Where to wrap? After "word", "char" or "word_char" function set_wrap(box, mode) - local allowed = { word = true, char = true, word_char = true } + local allowed = { word = "WORD", char = "CHAR", word_char = "WORD_CHAR" } if allowed[mode] then - box._layout:set_wrap(mode) + box._layout:set_wrap(allowed[mode]) box:emit_signal("widget::updated") end end @@ -138,9 +108,9 @@ end --- Set a textbox' horizontal alignment -- @param mode Where should the textbox be drawn? "left", "center" or "right" function set_align(box, mode) - local allowed = { left = true, center = true, right = true } + local allowed = { left = "LEFT", center = "CENTER", right = "RIGHT" } if allowed[mode] then - box._layout:set_alignment(mode) + box._layout:set_alignment(allowed[mode]) box:emit_signal("widget::updated") end end diff --git a/luaa.c b/luaa.c index 2b61289..6fe8c1c 100644 --- a/luaa.c +++ b/luaa.c @@ -29,9 +29,6 @@ #include <basedir_fs.h> -#include <oopango.h> -#include <oocairo.h> - #include "awesome.h" #include "config.h" #include "objects/timer.h" @@ -637,20 +634,6 @@ luaA_init(xdgHandle* xdg) lua_getfield(L, 1, "loaded"); - /* Load oocairo */ - if (luaopen_oocairo(L) != 1) - fatal("Loading oocairo failed"); - lua_pushvalue(L, 3); /* Copy the module */ - lua_setglobal(L, "oocairo"); /* Set the global entry */ - lua_setfield(L, 2, "oocairo"); /* Make it require()able */ - - /* Load oopango */ - if (luaopen_oopango(L) != 1) - fatal("Loading oopango failed"); - lua_pushvalue(L, 3); /* Copy the module */ - lua_setglobal(L, "oopango"); /* Set the global entry */ - lua_setfield(L, 2, "oopango"); /* Make it require()able */ - lua_pop(L, 2); /* pop "package" and "package.loaded" */ signal_add(&global_signals, "debug::error"); diff --git a/luadoc/awesome.lua b/luadoc/awesome.lua index 2e509c9..667cb52 100644 --- a/luadoc/awesome.lua +++ b/luadoc/awesome.lua @@ -37,7 +37,7 @@ module("awesome") --- Load an image -- @param name The file name --- @return An oocairo image surface +-- @return A cairo image surface as light user datum -- @name load_image -- @class function diff --git a/luadoc/drawin.lua b/luadoc/drawin.lua index e8e71cb..8c527fa 100644 --- a/luadoc/drawin.lua +++ b/luadoc/drawin.lua @@ -15,7 +15,7 @@ module("drawin") -- @field y The y coordinates. -- @field width The width of the drawin. -- @field height The height of the drawin. --- @field surface A oocairo surface that can be used for drawing. +-- @field surface A cairo surface as light user datum that can be used for drawing. -- @class table -- @name drawin diff --git a/objects/client.c b/objects/client.c index 0bb0a51..237ce24 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1043,17 +1043,15 @@ void client_set_icon(lua_State *L, int cidx, int iidx) { client_t *c = luaA_checkudata(L, cidx, &client_class); - if(lua_isnil(L, iidx)) + cairo_surface_t *surf = NULL; + if(!lua_isnil(L, iidx)) { - if(c->icon) - cairo_surface_destroy(c->icon); - c->icon = NULL; - } else { - cairo_surface_t **cairo_surface = (cairo_surface_t **)luaL_checkudata(L, iidx, OOCAIRO_MT_NAME_SURFACE); - if(c->icon) - cairo_surface_destroy(c->icon); - c->icon = draw_dup_image_surface(*cairo_surface); + cairo_surface_t **cairo_surface = (cairo_surface_t **)lua_touserdata(L, iidx); + surf = draw_dup_image_surface(*cairo_surface); } + if(c->icon) + cairo_surface_destroy(c->icon); + c->icon = surf; luaA_object_emit_signal(L, cidx < iidx ? cidx : cidx - 1, "property::icon", 0); } @@ -1431,9 +1429,11 @@ luaA_client_get_screen(lua_State *L, client_t *c) static int luaA_client_get_icon(lua_State *L, client_t *c) { - if(c->icon) - return oocairo_surface_push(L, c->icon); - return 0; + if(!c->icon) + return 0; + /* lua gets its own reference which it will have to destroy */ + lua_pushlightuserdata(L, cairo_surface_reference(c->icon)); + return 1; } static int diff --git a/objects/drawin.c b/objects/drawin.c index 69178ff..d4770bd 100644 --- a/objects/drawin.c +++ b/objects/drawin.c @@ -532,7 +532,9 @@ luaA_drawin_set_visible(lua_State *L, drawin_t *drawin) static int luaA_drawin_get_surface(lua_State *L, drawin_t *drawin) { - return oocairo_surface_push(L, drawin->surface); + /* Lua gets its own reference which it will have to destroy */ + lua_pushlightuserdata(L, cairo_surface_reference(drawin->surface)); + return 1; } /** Refresh a drawin's content. This has to be called whenever some drawing to diff --git a/root.c b/root.c index c6f5704..a1aeb2b 100644 --- a/root.c +++ b/root.c @@ -263,7 +263,6 @@ luaA_root_wallpaper(lua_State *L) xcb_get_property_reply_t *prop_r; xcb_pixmap_t *rootpix; cairo_surface_t *surface; - int ret; prop_c = xcb_get_property_unchecked(globalconf.connection, false, globalconf.screen->root, _XROOTPMAP_ID, XCB_ATOM_PIXMAP, 0, 1); @@ -282,9 +281,10 @@ luaA_root_wallpaper(lua_State *L) */ surface = cairo_xcb_surface_create(globalconf.connection, *rootpix, globalconf.default_visual, globalconf.screen->width_in_pixels, globalconf.screen->height_in_pixels); - ret = oocairo_surface_push(globalconf.L, surface); - cairo_surface_destroy(surface); - return ret; + + /* lua has to make sure this surface gets destroyed */ + lua_pushlightuserdata(L, surface); + return 1; } const struct luaL_reg awesome_root_lib[] = -- 1.7.10
>From 68d630c32a98061a907d5ba290cd388e051c6ab2 Mon Sep 17 00:00:00 2001 From: Uli Schlachter <[email protected]> Date: Sun, 27 May 2012 20:14:56 +0200 Subject: [PATCH 2/2] Remove a pango hack Instead of creating unused cairo image surfaces, we create our temporary layouts now via the (PangoCairo) font map. Way less ugly. Signed-off-by: Uli Schlachter <[email protected]> --- lib/beautiful.lua.in | 5 ++--- lib/wibox/widget/textbox.lua.in | 12 +++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/beautiful.lua.in b/lib/beautiful.lua.in index 8b7ddd5..cf512fd 100644 --- a/lib/beautiful.lua.in +++ b/lib/beautiful.lua.in @@ -44,9 +44,8 @@ local function load_font(name) -- load new font local desc = Pango.FontDescription.from_string(name) - -- Create a temporary surface that we need for computing the size :( - local surface = cairo.ImageSurface(cairo.Format.ARGB32, 1, 1) - local layout = PangoCairo.create_layout(cairo.Context(surface)) + local ctx = PangoCairo.font_map_get_default():create_context() + local layout = Pango.Layout.new(ctx) layout:set_font_description(desc) local width, height = layout:get_pixel_size() diff --git a/lib/wibox/widget/textbox.lua.in b/lib/wibox/widget/textbox.lua.in index e33bd4b..b09987f 100644 --- a/lib/wibox/widget/textbox.lua.in +++ b/lib/wibox/widget/textbox.lua.in @@ -48,13 +48,6 @@ function fit(box, width, height) return logical.width, logical.height end --- Return a pango layout which can be used if no cairo context is available -local function get_temp_layout() - local surface = cairo.ImageSurface(cairo.Format.ARGB32, 0, 0) - local cr = cairo.Context(surface) - return PangoCairo.create_layout(cr) -end - --- Set a textbox' text. -- @param text The text to set. This can contain pango markup (e.g. <b>bold</b>) function set_markup(box, text) @@ -131,8 +124,9 @@ local function new() end end - -- Spot the hack: Temporary surface to make pango happy - ret._layout = get_temp_layout() + local ctx = PangoCairo.font_map_get_default():create_context() + ret._layout = Pango.Layout.new(ctx) + ret:set_ellipsize("end") ret:set_wrap("word_char") ret:set_valign("center") -- 1.7.10
