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

Implemented keybinder_set_avoid_cooking_shift_accelerators to fix Shift problems #10

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 14 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@

keybinder v0.3.1
----------------

* Use ``XkbFreeKeyboard`` to fix memory leak
(by Dmitry Eremin-Solenikov)
* Fix deprecated directives in build system
(by Dmitry Eremin-Solenikov)


keybinder and keybinder-3.0 v0.3.0
-----------------------------------

Not Released Yet
Released Sunday, 17 June 2012

* Patch Makefile.am to use ACLOCAL_AMFLAGS=-I m4 (by Luca Falavigna)
* Add two functions to fix gobject-introspection (gir) bindings:
Expand Down Expand Up @@ -35,6 +44,10 @@ Not Released Yet

+ These libraries will possibly have separate releases in the future
but their first release is simultaneous, it is now.

+ ``keybinder-3.0`` is distributed under X11 license, since the GPL
parts have been removed (python-keybinder and ax_lua).
The old branch ``keybinder`` is still GPL!


keybinder v0.2.2
Expand Down
1 change: 0 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ libkeybinder
============

:Author: Ulrik Sverdrup <[email protected]>
:Homepage: http://kaizer.se/wiki/keybinder/

**keybinder** is a library for registering global keyboard shortcuts.
Keybinder works with GTK-based applications using the X Window System.
Expand Down
14 changes: 7 additions & 7 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT(keybinder, 0.2.2,
AC_INIT(keybinder, 0.3.1,
[])
AC_CONFIG_SRCDIR(libkeybinder/bind.c)
AC_CONFIG_MACRO_DIR([m4])
Expand All @@ -11,9 +11,9 @@ AM_INIT_AUTOMAKE([-Wno-portability])
# If interfaces are added/changed/removed: increment current, reset revision
# If library changed but is backwards-compatible: increment age
# If library changed backwards-incompatibly: reset age
m4_define([keybinder_lt_current], [0])
m4_define([keybinder_lt_revision], [1])
m4_define([keybinder_lt_age], [0])
m4_define([keybinder_lt_current], [1])
m4_define([keybinder_lt_revision], [0])
m4_define([keybinder_lt_age], [1])
LT_CURRENT=keybinder_lt_current
LT_REVISION=keybinder_lt_revision
LT_AGE=keybinder_lt_age
Expand Down Expand Up @@ -155,9 +155,9 @@ if test "x$enable_python" != "xno"; then
dnl ****************************************************************************
dnl * PyGTK Codegen and defs files
dnl ****************************************************************************
AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
if test "x$PYGTK_CODEGEN" = xno; then
AC_MSG_ERROR(could not find pygtk-codegen-2.0 script)
AC_PATH_PROG(PYGOBJECT_CODEGEN, pygobject-codegen-2.0, no)
if test "x$PYGOBJECT_CODEGEN" = xno; then
AC_MSG_ERROR(could not find pygobject-codegen-2.0 script)
fi

AC_MSG_CHECKING(for pygtk defs)
Expand Down
2 changes: 1 addition & 1 deletion libkeybinder/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
INCLUDES = $(GTK_CFLAGS)
AM_CPPFLAGS = $(GTK_CFLAGS)

AM_CFLAGS = -Wall

Expand Down
45 changes: 37 additions & 8 deletions libkeybinder/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct Binding {
static GSList *bindings = NULL;
static guint32 last_event_time = 0;
static gboolean processing_event = FALSE;
static gboolean avoid_cooking_shift_accelerators = TRUE;

/* Return the modifier mask that needs to be pressed to produce key in the
* given group (keyboard layout) and level ("shift level").
Expand Down Expand Up @@ -243,7 +244,7 @@ grab_ungrab (GdkWindow *rootwin,

}
g_free(keys);
XkbFreeClientMap(xmap, 0, TRUE);
XkbFreeKeyboard(xmap, 0, TRUE);

return success;
}
Expand Down Expand Up @@ -345,7 +346,7 @@ filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
XEvent *xevent = (XEvent *) gdk_xevent;
GdkKeymap *keymap = gdk_keymap_get_default();
guint keyval;
GdkModifierType consumed, modifiers;
GdkModifierType consumed, modifiers, shiftMask = 0;
guint mod_mask = gtk_accelerator_get_default_mod_mask();
GSList *iter;

Expand All @@ -360,6 +361,15 @@ filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
xevent->xkey.keycode,
xevent->xkey.state));

if( avoid_cooking_shift_accelerators )
{
//gdk_keymap_translate_keyboard_state will always report that
//GDK_SHIFT_MASK got consumed (because it converts lower case to uppercase).
//We need to remove shift modifier, and insert it after the translation.
shiftMask = modifiers & GDK_SHIFT_MASK;
}
modifiers &= ~GDK_SHIFT_MASK;

gdk_keymap_translate_keyboard_state(
keymap,
xevent->xkey.keycode,
Expand All @@ -372,6 +382,8 @@ filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)

/* Map non-virtual to virtual modifiers */
modifiers &= ~consumed;
if( avoid_cooking_shift_accelerators )
modifiers |= shiftMask;
gdk_keymap_add_virtual_modifiers(keymap, &modifiers);
modifiers &= mod_mask;

Expand Down Expand Up @@ -464,6 +476,27 @@ keybinder_init ()
NULL);
}

/**
* keybinder_set_avoid_cooking_shift_accelerators:
* @avoid_cooking_shift: if %TRUE, the Shift modifier won't be cooked into accelerators
*
* "Cooked" accelerators use symbols produced by using modifiers such
* as shift or altgr, for example if "!" is produced by "Shift+1",
* thus binding Shift+1 may not work as expected.
* Enabling this workaround will make Shift+1 work, but it could cause
* issues on some keymaps where "!" is an actual key.
*
* The cooked accelerator keyvalue and modifiers are provided by the
* function gdk_keymap_translate_keyboard_state()
*
* Default: Enabled.
*/
void
keybinder_set_avoid_cooking_shift_accelerators (gboolean avoid_cooking_shift)
{
avoid_cooking_shift_accelerators = avoid_cooking_shift;
}

/**
* keybinder_bind: (skip)
* @keystring: an accelerator description (gtk_accelerator_parse() format)
Expand All @@ -487,7 +520,7 @@ keybinder_bind (const char *keystring,
}

/**
* keybinder_bind_full:
* keybinder_bind_full: (rename-to keybinder_bind)
* @keystring: an accelerator description (gtk_accelerator_parse() format)
* @handler: (scope notified): callback function
* @user_data: (closure) (allow-none): data to pass to @handler
Expand All @@ -496,8 +529,6 @@ keybinder_bind (const char *keystring,
* Grab a key combination globally and register a callback to be called each
* time the key combination is pressed.
*
* Rename to: keybinder_bind
*
* Since: 0.3.0
*
* Returns: %TRUE if the accelerator could be grabbed
Expand Down Expand Up @@ -565,13 +596,11 @@ keybinder_unbind (const char *keystring, KeybinderHandler handler)
}

/**
* keybinder_unbind_all:
* keybinder_unbind_all: (rename-to keybinder_unbind)
* @keystring: an accelerator description (gtk_accelerator_parse() format)
*
* Unregister all previously bound callbacks for this keystring.
*
* Rename to: keybinder_unbind
*
* Since: 0.3.0
*/
void keybinder_unbind_all (const char *keystring)
Expand Down
2 changes: 2 additions & 0 deletions libkeybinder/keybinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ typedef void (* KeybinderHandler) (const char *keystring, void *user_data);

void keybinder_init (void);

void keybinder_set_avoid_cooking_shift_accelerators (gboolean avoid_cooking_shift);

gboolean keybinder_bind (const char *keystring,
KeybinderHandler handler,
void *user_data);
Expand Down
2 changes: 1 addition & 1 deletion lua-keybinder/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
INCLUDES = $(LUA_INCLUDE) $(GTK_CFLAGS) -I../libkeybinder
AM_CPPFLAGS = $(LUA_INCLUDE) $(GTK_CFLAGS) -I../libkeybinder

AM_CFLAGS = -Wall

Expand Down
6 changes: 3 additions & 3 deletions python-keybinder/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
INCLUDES = $(PYTHON_INCLUDES) $(PYGTK_CFLAGS) -I../libkeybinder
AM_CPPFLAGS = $(PYTHON_INCLUDES) $(PYGTK_CFLAGS) -I$(top_srcdir)/libkeybinder

AM_CFLAGS = -Wall

_keybinderdir = $(pyexecdir)/keybinder
_keybinder_LTLIBRARIES = _keybinder.la
_keybinder_la_CPPFLAGS = $(X_CFLAGS) $(PYEXTRAFLAGS)
_keybinder_la_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) $(PYEXTRAFLAGS)
_keybinder_la_LDFLAGS = -module -avoid-version -export-symbols-regex init_keybinder $(X_LDFLAGS)
_keybinder_la_LIBADD = ../libkeybinder/libkeybinder.la $(PYGTK_LIBS)
_keybinder_la_SOURCES = _keybindermodule.c
Expand All @@ -23,7 +23,7 @@ _keybinder.c: _keybinder.defs _keybinder.override

.defs.c:
(cd $(srcdir) \
&& $(PYGTK_CODEGEN) \
&& $(PYGOBJECT_CODEGEN) \
--override $*.override \
--register $(PYGTK_DEFSDIR)/gtk-types.defs \
--register $(PYGTK_DEFSDIR)/gdk-types.defs \
Expand Down
17 changes: 17 additions & 0 deletions python-keybinder/_keybinder.defs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@
"Will raise KeyError if keystring is not bound.")
)

(define-function set_avoid_cooking_shift_accelerators
(c-name "keybinder_set_avoid_cooking_shift_accelerators")
(return-type "none")
(parameters
'("bool" "avoid_cooking_shift")
)
(docstring "set_avoid_cooking_shift_accelerators (avoid_cooking_shift)\n"
"'Cooked' accelerators use symbols produced by using modifiers such\n"
"as shift or altgr, for example if '!' is produced by 'Shift+1',\n"
"thus binding Shift+1 may not work as expected.\n"
"Enabling this workaround will make Shift+1 work, but it could cause\n"
"issues on some keymaps where '!' is an actual key.\n"
"Default: Enabled.\n"
"\n"
"Will raise KeyError if avoid_cooking_shift is not bool.")
)

(define-function get_current_event_time
(c-name "keybinder_get_current_event_time")
(return-type "guint32")
Expand Down
25 changes: 25 additions & 0 deletions python-keybinder/_keybinder.override
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,28 @@ _wrap_keybinder_unbind (PyGObject *self, PyObject *args, PyObject *kwargs)
PyErr_SetString(PyExc_KeyError, "bind: keystring is not bound");
return NULL;
}
%%
override keybinder_set_avoid_cooking_shift_accelerators kwargs
static PyObject*
_wrap_keybinder_set_avoid_cooking_shift_accelerators (PyGObject *self, PyObject *args, PyObject *kwargs)
{
guint len;
len = PyTuple_Size(args);
if (len != 1) {
PyErr_SetString(PyExc_TypeError, "set_avoid_cooking_shift_accelerators requires exactly 1 argument");
return NULL;
}

PyObject *pyBoolean = PyTuple_GetItem( args, 0 );
int boolArg = PyObject_IsTrue( pyBoolean );

if( boolArg < 0 )
{
PyErr_SetString(PyExc_TypeError, "set_avoid_cooking_shift_accelerators must use a Boolean argument");
return NULL;
}

keybinder_set_avoid_cooking_shift_accelerators( (gboolean)boolArg );

return Py_None;
}