Merge pull request #1679 from psychon/keyboard-layout-changes

Asynchronously update the keyboard state
This commit is contained in:
Emmanuel Lepage Vallée 2017-03-29 13:59:34 -04:00 committed by GitHub
commit b81b2149f6
5 changed files with 65 additions and 11 deletions

View File

@ -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();

View File

@ -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 */

View File

@ -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
View File

@ -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,

1
xkb.h
View File

@ -26,6 +26,7 @@
#include <lua.h> #include <lua.h>
void event_handle_xkb_notify(xcb_generic_event_t* event); void event_handle_xkb_notify(xcb_generic_event_t* event);
void xkb_refresh(void);
void xkb_init(void); void xkb_init(void);
void xkb_free(void); void xkb_free(void);