Skip to content

Conversation

@wismill
Copy link
Member

@wismill wismill commented Dec 1, 2025

Fixes #932

TODO:

  • doc
  • changelog entry
  • mooar tests?
  • libxkbcommon-x11
  • libxkbregistry

@wismill wismill changed the title Add API to c Add API to check enumerations Dec 1, 2025
@wismill wismill added this to the 1.14.0 milestone Dec 1, 2025
@wismill wismill force-pushed the check-enums branch 6 times, most recently from 5ac7665 to 75521e5 Compare December 2, 2025 10:03
@wismill wismill force-pushed the check-enums branch 2 times, most recently from 5cabd27 to 2974759 Compare December 2, 2025 15:41
@whot
Copy link
Contributor

whot commented Dec 9, 2025

I'm somewhat wondering whether this can be a more generic feature test so we don't have to add new API in the future when we need more than enum checks. You could make this xkb_has_feature() and then your enums are just one of XKB_FEATURE_ENUM_FOO_BAR. In the future when specific behaviour (not API) needs to be checked we could add something like XKB_FEATURE_MANGLE_DEMANGLE. If you keep the namespace for enums and say you only add other features at 1000 that leaves you with a good space for adding enums.

More interestingly though: this would allow you to limit this patch to just the few enums that really matter - instead of writing a script that extracts all possible enums you just need a XKB_FEATURE_HAS_ENUM_FOOBAR for the one (few?) enums that were newly introduced. Because no-one will ever do feature checks for enums added a decade ago anyway.

Copy link
Member Author

@wismill wismill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat wondering whether this can be a more generic feature test so we don't have to add new API in the future when we need more than enum checks. You could make this xkb_has_feature() and then your enums are just one of XKB_FEATURE_ENUM_FOO_BAR. In the future when specific behaviour (not API) needs to be checked we could add something like XKB_FEATURE_MANGLE_DEMANGLE. If you keep the namespace for enums and say you only add other features at 1000 that leaves you with a good space for adding enums.

Great idea!

More interestingly though: this would allow you to limit this patch to just the few enums that really matter - instead of writing a script that extracts all possible enums you just need a XKB_FEATURE_HAS_ENUM_FOOBAR for the one (few?) enums that were newly introduced. Because no-one will ever do feature checks for enums added a decade ago anyway.

I disagree:

  • It introduces an unnecessary asymmetry. Let’s follow the principle of least astonishment.
  • The script that extract enum values is still necessary for the CI test.

Let me give it a thought.

- `xkb_has_feature()`: test feature availability. This is useful when
  the library is dynamically linked.
- `enum xkb_feature`: enumerate all the testable feature. Only
  enumerations are implemented for now.
Ensure we do not miss new enums/values.
@wismill
Copy link
Member Author

wismill commented Dec 9, 2025

Rebased and followed the suggestion of @whot to use a more generic xkb_has_feature().

@wismill wismill changed the title Add API to check enumerations Add API to test feature availability Dec 9, 2025
@wismill
Copy link
Member Author

wismill commented Dec 9, 2025

I do not think we need the same functionality in the X11 and registry libs for now.

@wismill wismill marked this pull request as ready for review December 9, 2025 17:57
@whot
Copy link
Contributor

whot commented Dec 10, 2025

It introduces an unnecessary asymmetry. Let’s follow the principle of least astonishment.

hehe, I think that's a translation victim but it made me smile :) (astonishment >> surprise)

My argument is mainly: instead of having an API surface of 20 enums we'd only have ... 1? 2?1 And 19/18 of those 20 will never be used because they pre-date this API anyway.

Footnotes

  1. that'll increase over time but it'll still be quite small

@wismill
Copy link
Member Author

wismill commented Dec 10, 2025

It introduces an unnecessary asymmetry. Let’s follow the principle of least astonishment.

hehe, I think that's a translation victim but it made me smile :) (astonishment >> surprise)

Both are equally correct, but “principle of least astonishment” is the original naming. For some reason I find that “astonishment” fits better for its pronunciation 😄.

My argument is mainly: instead of having an API surface of 20 enums we'd only have ... 1? 2?1 And 19/18 of those 20 will never be used because they pre-date this API anyway.

It is very pragmatic, but:

  • we still need some mechanism in the CI to ensure the function is always up to date, so focusing on 2enums does not seems to save much maintenance once automatized
  • users may prefer an API that can be applied consistently everywhere, even if somehow useless for old enums. Maybe @Caellian can comment about their Rust bindings.

@Caellian Caellian mentioned this pull request Dec 12, 2025
4 tasks
@Caellian
Copy link

Caellian commented Dec 12, 2025

Maybe @Caellian can comment about their Rust bindings.

It's usable, but introduces a layer of complexity and makes me encode the history of xkbcommon in conditionals. Example:

fn is_flag_supported(&self) -> bool {
  xkbcommon_sys::xkb_has_feature(xkbcommon_sys::XKB_FIRST_FLAG_CHECK + self as u32)
}

becomes:

fn is_flag_supported(&self) -> bool {
  if !xkbcommon_sys::xkb_has_feature(xkbcommon_sys::XKB_ENUM_CHECK) {
    return false;
  }
  match *self {
    Self::FirstFlag
    | Self::SecondFlag => true, // always supported
    Self::ThirdFlag if xkbcommon_sys::xkb_has_feature(xkbcommon_sys::XKB_THIRD_FLAG_CHECK) => true,
    Self::FourthFlag if xkbcommon_sys::xkb_has_feature(xkbcommon_sys::XKB_FOURTH_FLAG_CHECK) => true,
    _ => false,
  }
}

* I simplified xkb_has_feature for demo purposes

Bindings are just one user though - they shouldn't be the target of optimization.

Having a minimal list would mean that C & C++ users need to go through the changelog/headers to see e.g. which enum variants are guaranteed by enum presence and which were added later. So it adds usage complexity for them as well. This avoids frivolous checks, but the checks are cheap so it's not a huge deal.

Another thing you mentioned in #935 @whot is backporting, and exhaustiveness is necessary to avoid locking the library out of it. If someone were to backport this function to 1.7 (for Ubuntu to stay on 2 years old version), it would become useless.

  • If you remove something in 2.0, then you're forced to use additive (XKB_VALUE and XKB_VALUE_REMOVED) names, or versions could be confused.

Not sure if all of those things apply wrt your plans, I just listed all the reasons against I could come up with.

*
* @since 1.14.0
*/
enum xkb_feature {
Copy link

@Caellian Caellian Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move xkb_feature enum and xkb_has_feature function to a separate header file.

If functions are added to xkb_feature as a replacement for xkb_get_version, it will grow a lot and make the xkbcommon.h difficult to navigate (e.g. with case-insensitive string search in Vim, due to names matching).

In C++ land, I would wrap #import of that header in a separate namespace to make LSP more helpful.

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.

Add version query method (xkb_get_version)

3 participants