Merge pull request #1111 from psychon/assorted-fixes
Some assorted fixes
This commit is contained in:
commit
9b7e655afe
|
@ -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])
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,7 +1182,8 @@ client_geometry_refresh(void)
|
|||
/* ICCCM 4.2.3 says something else, but Java always needs this... */
|
||||
client_send_configure(c);
|
||||
}
|
||||
client_restore_enterleave_events();
|
||||
if (ignored_enterleave)
|
||||
client_restore_enterleave_events();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue