Skip to content

Increase default button timeout to 1000 milliseconds#720

Closed
albertvaka wants to merge 1 commit into
Pulse-Eight:masterfrom
albertvaka:patch-1
Closed

Increase default button timeout to 1000 milliseconds#720
albertvaka wants to merge 1 commit into
Pulse-Eight:masterfrom
albertvaka:patch-1

Conversation

@albertvaka

@albertvaka albertvaka commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Many interfaces make use of long-press of buttons, for example to open context menus.

Auto-releasing buttons after just 500 ms is too short for most applications to detect this as a long-press.

This change makes the default auto-release timeout long enough to not interfere with UIs that need long-press.

I am aware that this default has been like that for a long time, but I still think it is not a good default and, given we are going to release a new major version, it's a good opportunity to change it.

Many interfaces make use of long-press of buttons to open context menus. Auto-releasing buttons after just 500 ms is too short for most applications to detect this as a long-press.
@opdenkamp

Copy link
Copy Markdown
Contributor

The CEC specification defines press and hold repeat times of 200ms to 500ms, with a recommended value of 450ms, and this is one of the instances where the spec says shall instead of should. Do you have an example of this being a problem. Please post a full traffic log.

@albertvaka

albertvaka commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

The Youtube version for TVs [1] wants long-presses of 600ms. I'm using libcec to navigate this site with my TV remote, but because libcec injects a fake key release after just 500ms, it's not possible to ever do a long-press on Youtube TV. This probably affects other applications and websites too.

The CEC specification defines press and hold repeat times of 200ms to 500ms

Might this be referring to something else? I don't expect any "repeat", just a single press followed by a single release, spread more than 500ms apart so that it can be interpreted as a long-press by Youtube or whatever other application.

[1] https://www.youtube.com/tv, you need to change your User Agent to something like Mozilla/5.0 (Linux; Android 12) Cobalt/22.2.3-gold (PS4) to be able to see the page from a regular browser.

@opdenkamp

Copy link
Copy Markdown
Contributor

The CEC spec defines press & hold as:

  • send a key down once
  • repeat within 200ms to 500ms if the button is held down
  • send a key release when the key is released

Some devices didn't send any key release event, which is what this default timeout was supposed to address, automatically release if the CEC device "forgot" to send a key release, and this was kept as short as possible as default value in the library.

Which frontend application are you using that interfaces with your Youtube app? Does it allow you to override the timeout?

@albertvaka

albertvaka commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

I run Youtube TV on a regular browser (with the User Agent trick) on a Raspberry PI.

It seems my Samsung TV doesn't implement this "repeat within 200ms to 500ms", at least for the select and back buttons. The directional arrows do send repeated events.

This is what I receive when I long-press select on my Samsung TV remote (I've raised the timeout to 5000 ms in this run, and I kept it pressed for longer than that):

CEC Log message: CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE - rx_status=01 len=3 addr=01 opcode=44
CEC Log message: >> 01:44:00
CEC Log message: >> TV (0) -> Recorder 1 (1): user control pressed (44)
CEC Log message: SetCurrentButton select (0) D:0ms cur:555600a8aab0
CEC Log message: key pressed: select (0) current(ff) duration(0)
CEC Log message: Changed key select (0) D:0ms cur:ff
CEC Log message: key pressed: select (0, 0)
Got event 2 with data (0, 0)
CEC Log message: CheckKeypressTimeout T:472.994
CEC Log message: Key select: idle (duration:0) (0) timeout:1000ms (rel:5000,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:473.994
CEC Log message: Key select: idle (duration:0) (0) timeout:1000ms (rel:4000,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:474.994
CEC Log message: Key select: idle (duration:0) (0) timeout:1000ms (rel:3000,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:475.994
CEC Log message: Key select: idle (duration:0) (0) timeout:1000ms (rel:2000,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:476.994
CEC Log message: Key select: idle (duration:0) (0) timeout:1000ms (rel:1000,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:477.994
CEC Log message: Key unknown: released (duration:5000) (ff) timeout:1000ms (rel:0,rep:0,prs:0,rel:0)
Got event 2 with data (0, 5000)
CEC Log message: CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE - rx_status=01 len=2 addr=01 opcode=45
CEC Log message: >> 01:45
CEC Log message: >> TV (0) -> Recorder 1 (1): user control release (45)

As you can see, my code only gets two non-log events: first a key down, and 5000ms (or whatever timeout I configure) later, the fake key up. There are some other events logged in-between, but that doesn't seem to prevent the fake key up from triggering.

Btw, this is happening using libcec from master. In 7.1.1 the problem isn't there because that version wasn't generating the fake key up event (maybe due to a bug that got fixed?). In 7.1.1, after the 500 ms timeout there was simply no key up ever sent. This is the same long-press on 7.1.1 (the timeout was 500ms in this sample, but notice there's no Got event 2 when that triggers):

CEC Log message: CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE - rx_status=01 len=3 addr=01 opcode=44
CEC Log message: >> 01:44:00
CEC Log message: >> TV (0) -> Recorder 1 (1): user control pressed (44)
CEC Log message: SetCurrentButton select (0) D:0ms cur:7fff36b3de80
CEC Log message: key pressed: select (0) current(ff) duration(0)
CEC Log message: Changed key select (0) D:0ms cur:ff
CEC Log message: key pressed: select (0, 0)
Got event 2 with data (0, 0)
CEC Log message: CheckKeypressTimeout T:45611.429
CEC Log message: Key select: idle (duration:0) (0) timeout:500ms (rel:500,rep:0,prs:1,rel:0)
CEC Log message: CheckKeypressTimeout T:45611.929
CEC Log message: Key unknown: idle (duration:500) (ff) timeout:1000ms (rel:0,rep:0,prs:0,rel:0)
CEC Log message: CLinuxCECAdapterCommunication::Process - ioctl CEC_RECEIVE - rx_status=01 len=2 addr=01 opcode=45
CEC Log message: >> 01:45
CEC Log message: >> TV (0) -> Recorder 1 (1): user control release (45)

@opdenkamp

Copy link
Copy Markdown
Contributor

Thanks for the detailed traffic logs — they made the root cause clear. Rather than raise the global default (CEC_BUTTON_TIMEOUT is overloaded: it's also the default iButtonReleaseDelayMs and a couple of fallbacks, and bumping it just moves the cliff without fixing the class of problem), I've landed a targeted fix on master:

  • a660c29 — libCEC now learns whether the device sends its own user control release. Once it has seen one, and it isn't auto-repeating, the synthesized release is stretched from 500ms to a generous stuck-key backstop (CEC_BUTTON_RELEASE_BACKSTOP_MS, 5s) so the real release wins and long-presses aren't cut short. Devices that never release keep the old 500ms behaviour, and repeat-mode clients (Kodi) are untouched since a real release already clears the held state there.
  • b7689bb — a related cleanup: the held-button state is now cleared when a client is unregistered, so a key held across a reconnect can't emit a phantom release.

This should cover your YouTube TV case on the Pi (default non-repeat mode, a TV that releases but doesn't repeat select/back): after the first release libCEC observes, holds up to ~5s register as a long-press. One caveat — the very first hold of a session, before any release has been seen, is still cut at 500ms; in practice you'll have pressed something else first, so the flag is already set.

Could you build master and confirm it behaves for you? If it does, I'll close this in favour of that approach.

@albertvaka

Copy link
Copy Markdown
Contributor Author

Oh, I didn't know that this define was used for more stuff. Your solution looks good and I just tested it and works well. Closing this now :)

@albertvaka albertvaka closed this Jul 23, 2026
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 this pull request may close these issues.

2 participants