Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bug where the keyboard layout was changed when generating a key event #113

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions xcape.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ typedef struct _XCape_t
KeyMap_t *map;
Key_t *generated;
struct timeval timeout;
unsigned char intended_group;
unsigned char previous_group;
} XCape_t;

/************************************************************************
Expand Down Expand Up @@ -100,6 +102,7 @@ int main (int argc, char **argv)

XRecordRange *rec_range = XRecordAllocRange();
XRecordClientSpec client_spec = XRecordAllClients;
XkbStateRec state;

self->foreground = False;
self->debug = False;
Expand Down Expand Up @@ -161,6 +164,9 @@ int main (int argc, char **argv)
self->data_conn = XOpenDisplay (NULL);
self->ctrl_conn = XOpenDisplay (NULL);

XkbGetState (self->data_conn, XkbUseCoreKbd, &state);
self->intended_group = state.group;

if (!self->data_conn || !self->ctrl_conn)
{
fprintf (stderr, "Unable to connect to X11 display. Is $DISPLAY set?\n");
Expand Down Expand Up @@ -354,6 +360,11 @@ void intercept (XPointer user_data, XRecordInterceptData *data)
XCape_t *self = (XCape_t*)user_data;
static Bool mouse_pressed = False;
KeyMap_t *km;
XkbStateRec state;
unsigned char current_group;

XkbGetState (self->ctrl_conn, XkbUseCoreKbd, &state);
current_group = state.group;

XLockDisplay (self->ctrl_conn);

Expand Down Expand Up @@ -413,6 +424,18 @@ void intercept (XPointer user_data, XRecordInterceptData *data)
}
}

if (self->previous_group != current_group)
Copy link
Owner

Choose a reason for hiding this comment

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

Looks like previous_group is read before written to?

Copy link
Author

Choose a reason for hiding this comment

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

previous_group is now initialized to -1. The first time intercept() is called the condition in this "if" will definitely be true. Since the bug did occur only after intercept() was already called for the key press event, this case will work exactly as before. If switching to another keyboard change was set to a single key (for example grp:lalt_toggle), the initialization of previous_group to intended_group might have caused problems since the keyboard group is changed before intercept() is called.

Copy link
Author

Choose a reason for hiding this comment

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

While writing the comment my first commit started to make more and more sense. It will also handle both cases correctly and it seems to be a more reasonable solution.

{
self->intended_group = current_group;

if (self->debug)
fprintf (stdout, "Changed group to %d\n", current_group);
}

XkbLockGroup (self->ctrl_conn, XkbUseCoreKbd, self->intended_group);
XkbGetState (self->ctrl_conn, XkbUseCoreKbd, &state);
self->previous_group = state.group;

exit:
XUnlockDisplay (self->ctrl_conn);
XRecordFreeData (data);
Expand Down