haskellfunctional-programmingxmonadio-monadxmobar

How can I change XMobar's Kbd monitor plugin such that clicking on it loops throught the layouts?


The Kbd monitor plugin can be installed in the xmobar status bar like this,

Run $ Kbd [("it", "IT"), ("ru(phonetic)", "RU")]

and then switch keyboard via setxkbmap, the monitor will reflect the change.

So far so good.

Now, assume that

even if this means writing MyOwnKbd plugin.

Also assume that another requirement is that I don't want the logic of rotation to be encoded in an external script.


Since I don't want to bind a key to switching between keyboards¹, I was thinking about allowing the switch via clicking on the monitor itself.

I know I can just wrap the text of the monitor in <action=`the command`> and </action> to make it clickable, but I have no clue what the command should be.

I know that I could write a shell script that detects the state of the keyboard and sets the other one, but I want to use the very list above, [("it", "IT"), ("ru(phonetic)", "RU")] as the source of what keyboard layouts clicking the monitor should loop through, so the question becomes: can I feed the click-on-monitor event back to the business logic of the monitor?

Or, if that's not possible, what other alternatives do I have?


(¹) E.g. I could have done

setxkbmap -layout it,ru -variant ,phonetic -option 'grp:caps_toggle'

once and for all, and Caps Lock would allow to switch between those two layouts, and the plugin, as is, would reflect which layout is in use. But I don't want to map any key to the layout switching action.

Well, it's not that I don't want that solution, but I'm curious to know what another solution would be.


(I've deleted a previous question because the specific scenario that led me to formulate it was actually complicating the matter. I'll un-delete it if the answer to this question will be insufficient for that.)


Solution

  • In reality, the best solution is simply to hardcode the actions at the point of creation of Kbd:

    Run $ Kbd [("it", "<action=`setxkbmap -layout ru -variant phonetic` button=1>it</action>"),
               ("ru(phonetic)", "<action=`setxkbmap -layout it` button=1>ru</action>")]
    

    Old answer

    Eventually I came up with a solution myself, which was merged with the PR #696.

    When I wrote

    I know I can just wrap the text of the monitor in <action=`the command`> and </action> to make it clickable, but I have no clue what the command should be.

    I was making the mistake of thinking that I have to know the command that does the right thing whatever the current layout, but that's incorrect, as I can just compute a different command for each layout, which will simply switch to the next one.

    To give a concrete example, if I install the plugin like this,

    Run $ Kbd [("it", "IT"), ("ru(phonetic)", "RU"), ("us", "US")]
    

    the text I want to print when each of the 3 layouts is selected is as follows:

    This allow switching layouts in the order IT->RU->US. In the code I've contributed to xmobar, I've also wrapped those in actions to navigate the opposite direction with button=3.