Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: gears.timer {call_now=true} doesn't pass self (ret) #3904

Closed
aarondill opened this issue Mar 18, 2024 · 1 comment · Fixed by #3933
Closed

BUG: gears.timer {call_now=true} doesn't pass self (ret) #3904

aarondill opened this issue Mar 18, 2024 · 1 comment · Fixed by #3933

Comments

@aarondill
Copy link
Contributor

Output of awesome --version:

Tested in both 4.3 and HEAD
> awesome --version
awesome v4.3 (Too long)
 • Compiled against Lua 5.3.6 (running with Lua 5.3)
 • D-Bus support: ✔
 • execinfo support: ✔
 • xcb-randr version: 1.6
 • LGI version: 0.9.2
> ./build/awesome --version
awesome v4.3-1647-ge6f5c798-dirty (Too long)
 • Compiled against Lua 5.4.6 (running with 0.9.2)
 • API level: 4
 • D-Bus support: yes
 • xcb-errors support: no
 • execinfo support: yes
 • xcb-randr version: 1.6
 • LGI version: /usr/share/lua/5.4/lgi/version.lua
 • Transparency enabled: yes
 • Custom search paths: no

How to reproduce the issue:

local gtimer = require("gears.timer")
local naughty = require("naughty")
local function notify(val) --- A simple shim around naughty to support the V5 or V4 apis
  if naughty.notification then return naughty.notification({ message = tostring(val) }) end
  return naughty.notify({ text = tostring(val) })
end

gtimer.new({
  call_now = true, -- This introduces the broken behavior
  autostart = true, -- Call :start() for me, required to show the correct behavior (through :emit_signal('timeout'))
  timeout = 1, -- A short timeout to easily reproduce the issue
  single_shot = true, -- Only run this once, not needed, but simplifies cleanup after the demonstration
  callback = notify, -- Call notify on timeout, just notifies the first value
})

Actual result:

A notification is received nil from the call_now
A second notification is received 1 second later (due to timeout) table: <address> (the timer)

Expected result:

call_now passes the timer to the callback like :emit_signal('timeout') does, resulting in two identical notifications both displaying the timer's memory address.

Possible implementation:
The code currently looks like this:

    if args.callback then
        if args.call_now then
            args.callback()
        end
        ret:connect_signal("timeout", args.callback)
    end

    if args.single_shot then
        ret:connect_signal("timeout", function() ret:stop() end)
    end

It would be simpler and avoid this sort of issue in the future to do this:

    if args.callback then
        ret:connect_signal("timeout", args.callback)
    end
    if args.call_now then
            ret:emit_signal("timeout")
    end
    if args.single_shot then
        ret:connect_signal("timeout", function() ret:stop() end)
    end

This makes call_now call :emit_signal("timeout") which would pass the timer to args.callback (the only connected listener)

This would also be more future-proof to potential changes to :emit_signal(), as it would make the actual timer behavior (in :start()) and the .call_now behavior match exactly.

alternatively, keep the current code and just call args.callback(ret)

@aarondill
Copy link
Contributor Author

The current hack to avoid this is:

-gtimer.new({
-  call_now = true,
+local timer = gtimer.new({
+  call_now = false,
  autostart = true,
  timeout = 1,
  single_shot = true,
  callback = notify,
})
+notify(timer)

which adds an additional variable declaration and error-prone call to callback, which call_now is intended to avoid.

aarondill added a commit to aarondill/awesome-1 that referenced this issue Jun 30, 2024
This ensures that the timer gets passed on the first call of callback.
fixes: awesomeWM#3904

Signed-off-by: aarondill <[email protected]>
@Elv13 Elv13 closed this as completed in 220ae79 Aug 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant