Merge pull request #1111 from psychon/assorted-fixes

Some assorted fixes
This commit is contained in:
Daniel Hahler 2016-09-25 01:35:55 +02:00 committed by GitHub
commit 9b7e655afe
8 changed files with 120 additions and 21 deletions

View File

@ -165,8 +165,7 @@ mytasklist.buttons = awful.util.table.join(
awful.client.focus.byidx(-1)
end))
awful.screen.connect_for_each_screen(function(s)
-- Wallpaper
local function set_wallpaper(s)
if beautiful.wallpaper then
local wallpaper = beautiful.wallpaper
-- If wallpaper is a function, call it with the screen
@ -175,6 +174,14 @@ awful.screen.connect_for_each_screen(function(s)
end
gears.wallpaper.maximized(wallpaper, s, true)
end
end
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
screen.connect_signal("property::geometry", set_wallpaper)
awful.screen.connect_for_each_screen(function(s)
-- Wallpaper
set_wallpaper(s)
-- Each screen has its own tag table.
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])

View File

@ -163,6 +163,32 @@ luaA_class_add_property(lua_class_t *lua_class,
});
}
/** Newindex meta function for objects after they were GC'd.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
*/
static int
luaA_class_newindex_invalid(lua_State *L)
{
return luaL_error(L, "attempt to index an object that was already garbage collected");
}
/** Index meta function for objects after they were GC'd.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
*/
static int
luaA_class_index_invalid(lua_State *L)
{
const char *attr = luaL_checkstring(L, 2);
if (A_STREQ(attr, "valid"))
{
lua_pushboolean(L, false);
return 1;
}
return luaA_class_newindex_invalid(L);
}
/** Garbage collect a Lua object.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
@ -181,8 +207,13 @@ luaA_class_gc(lua_State *L)
class->collector(item);
/* Unset its metatable so that e.g. luaA_toudata() will no longer accept
* this object. This is needed since other __gc methods can still use this.
* We also make sure that `item.valid == false`.
*/
lua_newtable(L);
lua_pushcfunction(L, luaA_class_index_invalid);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, luaA_class_newindex_invalid);
lua_setfield(L, -2, "__newindex");
lua_setmetatable(L, 1);
return 0;
}

View File

@ -62,13 +62,8 @@ function magnifier.arrange(p)
-- Check that the focused window is on the right screen
if focus and focus.screen ~= p.screen then focus = nil end
if not focus and #cls > 0 then
focus = cls[1]
fidx = 1
end
-- If focused window is not tiled, take the first one which is tiled.
if focus.floating then
-- If no window is focused or focused window is not tiled, take the first tiled one.
if (not focus or focus.floating) and #cls > 0 then
focus = cls[1]
fidx = 1
end

View File

@ -24,7 +24,8 @@ local matrix = require("gears.matrix")
local hierarchy = require("wibox.hierarchy")
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
local drawables = setmetatable({}, { __mode = 'k' })
local drawables_draw = setmetatable({}, { __mode = 'k' })
local drawables_force_complete_repaint = setmetatable({}, { __mode = 'k' })
-- Get the widget context. This should always return the same table (if
-- possible), so that our draw and fit caches can work efficiently.
@ -46,20 +47,20 @@ local function get_widget_context(self)
screen = s,
dpi = dpi,
drawable = self,
widget_at = function(_, ...)
self:widget_at(...)
end
}
for k, v in pairs(self._widget_context_skeleton) do
context[k] = v
end
self._widget_context = context
-- Give widgets a chance to react to the new context
self._need_complete_repaint = true
end
return context
end
local function do_redraw(self)
if type(self.drawable) ~= "drawable" then return end --FIXME See #1070
if not self.drawable.valid then return end
local surf = surface.load_silently(self.drawable.surface, false)
-- The surface can be nil if the drawable's parent was already finalized
@ -357,9 +358,18 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
ret._need_complete_repaint = true
ret:draw()
end
drawables[ret._do_complete_repaint] = true
drawables_draw[ret.draw] = true
drawables_force_complete_repaint[ret._do_complete_repaint] = true
-- Do a full redraw if the surface changes (the new surface has no content yet)
d:connect_signal("property::surface", ret._do_complete_repaint)
-- Do a normal redraw when the drawable moves. This will likely do nothing
-- in most cases, but it makes us do a complete repaint when we are moved to
-- a different screen.
d:connect_signal("property::x", ret.draw)
d:connect_signal("property::y", ret.draw)
-- Currently we aren't redrawing on move (signals not connected).
-- :set_bg() will later recompute this.
ret._redraw_on_move = false
@ -390,6 +400,15 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
-- Set up our callbacks for repaints
ret._redraw_callback = function(hierar, arg)
-- XXX: lgi will lead us into memory-corruption-land when we use an
-- object after it was GC'd. Try to detect this situation by checking if
-- the drawable is still valid. This is only a weak indication, but it
-- seems to be the best that we can do. The problem is that the drawable
-- could not yet be GC'd, but is pending finalisation, while the
-- cairo.Region below was already GC'd. This would still lead to corruption.
if not ret.drawable.valid then
return
end
if ret._widget_hierarchy_callback_arg ~= arg then
return
end
@ -427,11 +446,21 @@ end
-- Redraw all drawables when the wallpaper changes
capi.awesome.connect_signal("wallpaper_changed", function()
for k in pairs(drawables) do
for k in pairs(drawables_force_complete_repaint) do
k()
end
end)
-- Give drawables a chance to react to screen changes
local function draw_all()
for k in pairs(drawables_draw) do
k()
end
end
screen.connect_signal("property::geometry", draw_all)
screen.connect_signal("added", draw_all)
screen.connect_signal("removed", draw_all)
return setmetatable(drawable, { __call = function(_, ...) return drawable.new(...) end })
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -23,6 +23,7 @@ local function hierarchy_new(redraw_callback, layout_callback, callback_arg)
_matrix_to_device = matrix.identity,
_need_update = true,
_widget = nil,
_context = nil,
_redraw_callback = redraw_callback,
_layout_callback = layout_callback,
_callback_arg = callback_arg,
@ -73,6 +74,7 @@ end
local hierarchy_update
function hierarchy_update(self, context, widget, width, height, region, matrix_to_parent, matrix_to_device)
if (not self._need_update) and self._widget == widget and
self._context == context and
self._size.width == width and self._size.height == height and
matrix.equals(self._matrix, matrix_to_parent) and
matrix.equals(self._matrix_to_device, matrix_to_device) then
@ -101,6 +103,7 @@ function hierarchy_update(self, context, widget, width, height, region, matrix_t
-- Save the arguments we need to save
self._widget = widget
self._context = context
self._size.width = width
self._size.height = height
self._matrix = matrix_to_parent

View File

@ -177,9 +177,6 @@ local function new(args)
setup_signals(ret)
ret.draw = ret._drawable.draw
ret.widget_at = function(_, widget, x, y, width, height)
return ret._drawable:widget_at(widget, x, y, width, height)
end
-- Set the default background
ret:set_bg(args.bg or beautiful.bg_normal)

View File

@ -1138,7 +1138,7 @@ client_border_refresh(void)
static void
client_geometry_refresh(void)
{
client_ignore_enterleave_events();
bool ignored_enterleave = false;
foreach(_c, globalconf.clients)
{
client_t *c = *_c;
@ -1164,6 +1164,11 @@ client_geometry_refresh(void)
&& AREA_EQUAL(real_geometry, c->x11_client_geometry))
continue;
if (!ignored_enterleave) {
client_ignore_enterleave_events();
ignored_enterleave = true;
}
xcb_configure_window(globalconf.connection, c->frame_window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
(uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height });
@ -1177,6 +1182,7 @@ client_geometry_refresh(void)
/* ICCCM 4.2.3 says something else, but Java always needs this... */
client_send_configure(c);
}
if (ignored_enterleave)
client_restore_enterleave_events();
}

View File

@ -0,0 +1,31 @@
-- Test behaviour of C objects after they were finalized
local runner = require("_runner")
local done
do
local obj
local func = function()
assert(obj.valid == false)
assert(not pcall(function()
print(obj.visible)
end))
assert(not pcall(function()
obj.visible = true
end))
done = true
end
if _VERSION >= "Lua 5.2" then
setmetatable({}, { __gc = func })
else
local newproxy = newproxy -- luacheck: globals newproxy
getmetatable(newproxy(true)).__gc = func
end
obj = drawin({})
end
collectgarbage("collect")
assert(done)
runner.run_steps({ function() return true end })
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80