Merge pull request #1679 from psychon/keyboard-layout-changes
Asynchronously update the keyboard state
This commit is contained in:
commit
b81b2149f6
4
event.h
4
event.h
|
@ -42,9 +42,13 @@ void client_destroy_later(void);
|
||||||
/* objects/screen.c */
|
/* objects/screen.c */
|
||||||
void screen_refresh(void);
|
void screen_refresh(void);
|
||||||
|
|
||||||
|
/* xkb.c */
|
||||||
|
void xkb_refresh(void);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
awesome_refresh(void)
|
awesome_refresh(void)
|
||||||
{
|
{
|
||||||
|
xkb_refresh();
|
||||||
screen_refresh();
|
screen_refresh();
|
||||||
luaA_emit_refresh();
|
luaA_emit_refresh();
|
||||||
drawin_refresh();
|
drawin_refresh();
|
||||||
|
|
|
@ -186,6 +186,12 @@ typedef struct
|
||||||
struct xkb_context *xkb_ctx;
|
struct xkb_context *xkb_ctx;
|
||||||
/* xkb state of dead keys on keyboard */
|
/* xkb state of dead keys on keyboard */
|
||||||
struct xkb_state *xkb_state;
|
struct xkb_state *xkb_state;
|
||||||
|
/* Do we have a pending reload? */
|
||||||
|
bool xkb_reload_keymap;
|
||||||
|
/* Do we have a pending map change? */
|
||||||
|
bool xkb_map_changed;
|
||||||
|
/* Do we have a pending group change? */
|
||||||
|
bool xkb_group_changed;
|
||||||
/** The preferred size of client icons for this screen */
|
/** The preferred size of client icons for this screen */
|
||||||
uint32_t preferred_icon_size;
|
uint32_t preferred_icon_size;
|
||||||
/** Cached wallpaper information */
|
/** Cached wallpaper information */
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
-- Test for bug #1494: Using xmodmap freezes awesome since it re-queries the
|
||||||
|
-- keyboard layout many, many times. (xmodmap applies each change on its own)
|
||||||
|
|
||||||
|
local runner = require("_runner")
|
||||||
|
local spawn = require("awful.spawn")
|
||||||
|
local GLib = require("lgi").GLib
|
||||||
|
|
||||||
|
local done
|
||||||
|
local timer = GLib.Timer()
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
function(count)
|
||||||
|
if count == 1 then
|
||||||
|
-- POSIX allows us to use awk
|
||||||
|
local cmd = "awk 'BEGIN { for(i=1; i<=1000;i++) print \"keycode 107 = parenleft\" }' | xmodmap -"
|
||||||
|
spawn.easy_async({"sh", "-c", cmd}, function()
|
||||||
|
awesome.sync()
|
||||||
|
done = true
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
if done then
|
||||||
|
-- Apply some limit on how long awesome may need to process 'things'
|
||||||
|
return timer:elapsed() < 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
runner.run_steps(steps)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
36
xkb.c
36
xkb.c
|
@ -297,13 +297,29 @@ xkb_reload_keymap(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xkb_refresh(void)
|
||||||
|
{
|
||||||
|
lua_State *L = globalconf_get_lua_State();
|
||||||
|
|
||||||
|
if (globalconf.xkb_reload_keymap)
|
||||||
|
xkb_reload_keymap();
|
||||||
|
if (globalconf.xkb_map_changed)
|
||||||
|
signal_object_emit(L, &global_signals, "xkb::map_changed", 0);
|
||||||
|
if (globalconf.xkb_group_changed)
|
||||||
|
signal_object_emit(L, &global_signals, "xkb::group_changed", 0);
|
||||||
|
|
||||||
|
globalconf.xkb_reload_keymap = false;
|
||||||
|
globalconf.xkb_map_changed = false;
|
||||||
|
globalconf.xkb_group_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
/** The xkb notify event handler.
|
/** The xkb notify event handler.
|
||||||
* \param event The event.
|
* \param event The event.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
event_handle_xkb_notify(xcb_generic_event_t* event)
|
event_handle_xkb_notify(xcb_generic_event_t* event)
|
||||||
{
|
{
|
||||||
lua_State *L = globalconf_get_lua_State();
|
|
||||||
assert(globalconf.have_xkb);
|
assert(globalconf.have_xkb);
|
||||||
|
|
||||||
/* The pad0 field of xcb_generic_event_t contains the event sub-type,
|
/* The pad0 field of xcb_generic_event_t contains the event sub-type,
|
||||||
|
@ -315,18 +331,16 @@ event_handle_xkb_notify(xcb_generic_event_t* event)
|
||||||
{
|
{
|
||||||
xcb_xkb_new_keyboard_notify_event_t *new_keyboard_event = (void*)event;
|
xcb_xkb_new_keyboard_notify_event_t *new_keyboard_event = (void*)event;
|
||||||
|
|
||||||
xkb_reload_keymap();
|
globalconf.xkb_reload_keymap = true;
|
||||||
|
|
||||||
if (new_keyboard_event->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
|
if (new_keyboard_event->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
|
||||||
{
|
globalconf.xkb_map_changed = true;
|
||||||
signal_object_emit(L, &global_signals, "xkb::map_changed", 0);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_XKB_MAP_NOTIFY:
|
case XCB_XKB_MAP_NOTIFY:
|
||||||
{
|
{
|
||||||
xkb_reload_keymap();
|
globalconf.xkb_reload_keymap = true;
|
||||||
signal_object_emit(L, &global_signals, "xkb::map_changed", 0);
|
globalconf.xkb_map_changed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_XKB_STATE_NOTIFY:
|
case XCB_XKB_STATE_NOTIFY:
|
||||||
|
@ -342,10 +356,7 @@ event_handle_xkb_notify(xcb_generic_event_t* event)
|
||||||
state_notify_event->lockedGroup);
|
state_notify_event->lockedGroup);
|
||||||
|
|
||||||
if (state_notify_event->changed & XCB_XKB_STATE_PART_GROUP_STATE)
|
if (state_notify_event->changed & XCB_XKB_STATE_PART_GROUP_STATE)
|
||||||
{
|
globalconf.xkb_group_changed = true;
|
||||||
lua_pushinteger(L, state_notify_event->group);
|
|
||||||
signal_object_emit(L, &global_signals, "xkb::group_changed", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +369,9 @@ event_handle_xkb_notify(xcb_generic_event_t* event)
|
||||||
void
|
void
|
||||||
xkb_init(void)
|
xkb_init(void)
|
||||||
{
|
{
|
||||||
|
globalconf.xkb_reload_keymap = false;
|
||||||
|
globalconf.xkb_map_changed = false;
|
||||||
|
globalconf.xkb_group_changed = false;
|
||||||
|
|
||||||
int success_xkb = xkb_x11_setup_xkb_extension(globalconf.connection,
|
int success_xkb = xkb_x11_setup_xkb_extension(globalconf.connection,
|
||||||
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
||||||
|
|
Loading…
Reference in New Issue