Awesome: Crash when using a custom keyboard layout

Created on 21 Sep 2016  Â·  11Comments  Â·  Source: awesomeWM/awesome

Output of awesome --version:

awesome  (The Fox)
 • Compiled against Lua 5.3.3 (running with Lua 5.3)
 • D-Bus support: ✔

How to reproduce the issue:

I am using a custom keyboard layout (a variant of Dvorak with accents; for the record, in my system awesome.xkb_get_group_names() returns pc+dvorak_alt2+inet(evdev)).

Actual result:

Whenever I restart Awesome with an error in my ~/.config/awesome/rc.lua, which should have caused the default config to load, instead I get a fatal error: X terminates and I'm back to the console. Piping awesome to a log file, I found that I got the following Lua error:

Failed to get list of keyboard groups

Triggered at awful/widget/keyboardlayout.lua:

local function update_layout(self)
    self._layout = {};
    local layouts = keyboardlayout.get_groups_from_group_names(awesome.xkb_get_group_names())
    if layouts == nil or layouts[1] == nil then
        error("Failed to get list of keyboard groups")
        return;
    end
    if #layouts == 1 then
        layouts[1].group_idx = 0
    end
    for _, v in ipairs(layouts) do
        local layout_name = self.layout_name(v)
        -- Please note that numbers of groups reported by xkb_get_group_names
        -- is greater by one than the real group number.
        self._layout[v.group_idx - 1] = layout_name
    end
    update_status(self)
end

Interestingly, loading Awesome with the default config works, but restarting always shuts down X.

Expected result:

I simply commented out the error("Failed to get list of keyboard groups") line and everything works as expected: Awesome doesn't terminate and my keyboard works the way I configured it; it seems to me that not finding a standard keyboard layout should not be a fatal error.

I can provide more info if desired. Thank you!

bug

Most helpful comment

I'd suggest

diff --git a/lib/awful/widget/keyboardlayout.lua b/lib/awful/widget/keyboardlayout.lua
index b6e8ce0..ab0c56a 100644
--- a/lib/awful/widget/keyboardlayout.lua
+++ b/lib/awful/widget/keyboardlayout.lua
@@ -11,6 +11,7 @@ local textbox = require("wibox.widget.textbox")
 local button = require("awful.button")
 local util = require("awful.util")
 local widget_base = require("wibox.widget.base")
+local gdebug = require("gears.debug")

 --- Keyboard Layout widget.
 -- awful.widget.keyboardlayout
@@ -234,8 +235,8 @@ local function update_layout(self)
     self._layout = {};
     local layouts = keyboardlayout.get_groups_from_group_names(awesome.xkb_get_group_names())
     if layouts == nil or layouts[1] == nil then
-        error("Failed to get list of keyboard groups")
-        return;
+        gdebug.print_error("Failed to get list of keyboard groups")
+        return
     end
     if #layouts == 1 then
         layouts[1].group_idx = 0

All 11 comments

Can you poke into get_groups_from_group_names and print things there, please?
You can use require("gears").debug.dump(data, "desc") for that.
Of course also the return value is interesting (layouts): is it nil or is layouts[1] nil?

Oh, and trying it with awesome from Git (if you easily can) would be nice, too.

I'd like to try to reproduce this. However, of course I do not have dvorak_alt2. You do provide a link to it in your report. However, what exactly do I do with the files I have there?

@psychon thanks! But I'll get the information that @blueyed asked for as soon as I'm at the computer again, I hope that should be enough to diagnose the problem without making you unconfigure your keyboard :)

Oh, I just remembered that keyboardlayout is covered by unit tests, so the following patch can be used to reproduce the problem (kinda):

diff --git a/spec/awful/keyboardlayout_spec.lua b/spec/awful/keyboardlayout_spec.lua
index e2a5c96..f7d396e 100644
--- a/spec/awful/keyboardlayout_spec.lua
+++ b/spec/awful/keyboardlayout_spec.lua
@@ -14,6 +14,8 @@ describe("awful.widget.keyboardlayout get_groups_from_group_names", function()
         -- possible worst cases
         [""] = {
         },
+        ["pc+dvorak_alt2+inet(evdev)"] = {
+        },
         ["empty"] = {
         },
         ["empty(basic)"] = {

So this returns an empty table.

Looking at what get_groups_from_group_names does, it splits the string into parts delimited by "+". For each of these parts it tries to figure out a country. Well, none of it is.

When I do e.g. setxkbmap dvorak, awesome gets pc+us(dvorak)+inet(evdev) and can parse the us part of this. So your dvorak_alt2-layout just has a name that this code does not expect.

So I guess the issue here boils down to "the keyboardlayout widget expects a specific format of the 'XKB group names thing'; however, this expectation is wrong and should be lifted". I suggest: Instead of erroring out, the code prints a warning (via gears.debug) and produces an empty widget.

I think @psychon's assessment is spot on. In any case, here's the answers to the clarifications that were requested:

Can you poke into get_groups_from_group_names and print things there, please?
You can use require("gears").debug.dump(data, "desc") for that.

I get three tokens, "pc", "dvorak2_alt" and "inet(evdev)".

Of course also the return value is interesting (layouts): is it nil or is layouts[1] nil?

The return value is an empty table.

Oh, and trying it with awesome from Git (if you easily can) would be nice, too.

This was running 25f2b034 — I don't think this part of the code change since, but I can try updating if you find it necessary!

I agree that changing that error() into a warning is the best course of action (especially since it's non-fatal and the desktop runs fine when it fails to detect the keyboard layout). Thank you both for the prompt responses! :)

I'd suggest

diff --git a/lib/awful/widget/keyboardlayout.lua b/lib/awful/widget/keyboardlayout.lua
index b6e8ce0..ab0c56a 100644
--- a/lib/awful/widget/keyboardlayout.lua
+++ b/lib/awful/widget/keyboardlayout.lua
@@ -11,6 +11,7 @@ local textbox = require("wibox.widget.textbox")
 local button = require("awful.button")
 local util = require("awful.util")
 local widget_base = require("wibox.widget.base")
+local gdebug = require("gears.debug")

 --- Keyboard Layout widget.
 -- awful.widget.keyboardlayout
@@ -234,8 +235,8 @@ local function update_layout(self)
     self._layout = {};
     local layouts = keyboardlayout.get_groups_from_group_names(awesome.xkb_get_group_names())
     if layouts == nil or layouts[1] == nil then
-        error("Failed to get list of keyboard groups")
-        return;
+        gdebug.print_error("Failed to get list of keyboard groups")
+        return
     end
     if #layouts == 1 then
         layouts[1].group_idx = 0

Looks like this could be merged. @hishamhm you +1-ed this, so it works for you?

@Elv13 yes, it does!

Great, I will create a PR in @psychon's name.

@psychon
The test (from https://github.com/awesomeWM/awesome/issues/1108#issuecomment-248904455) did not fail: https://github.com/awesomeWM/awesome/pull/1152#issuecomment-252362421

Sorry if I wasn't clear.

No, this test should not fail. It shows that this keyboard layout description will be parsed into an empty table (no language-specific entries found). The following code then raises an error claiming that something was wrong:

    if layouts == nil or layouts[1] == nil then
        error("Failed to get list of keyboard groups")

The idea of this test was more "via this one (at least I) can understand what is actually happening".

Was this page helpful?
0 / 5 - 0 ratings

Related issues

psychon picture psychon  Â·  6Comments

deb75 picture deb75  Â·  4Comments

ghost picture ghost  Â·  4Comments

batmanm0b1E picture batmanm0b1E  Â·  6Comments

SethBarberee picture SethBarberee  Â·  3Comments