Grab keys only when active window is changed

pull/1/head
Takashi Kokubun 8 years ago
parent 36d41a3c99
commit fc993cee6e

@ -3,21 +3,33 @@ module Xkremap
# @param [Xkremap::Config] config
# @param [Xkremap::Display] display
def initialize(config, display)
@config = config
@display = display
XlibWrapper.grab_keys(@display)
@key_remap_builder = KeyRemapBuilder.new(config, display)
@key_grab_manager = KeyGrabManager.new(display)
remap_keys
end
def handle_key_press(keycode, state)
handler = @key_remap_builder.prebuilt[keycode][state]
handler && handler.call
puts 'Event: key_press'
end
def handle_property_notify
puts 'Event: property_notify'
if @key_remap_builder.active_window_changed?
remap_keys
end
end
def handle_mapping_notify
puts 'Event: mapping_notify'
remap_keys
end
private
def remap_keys
@key_remap_builder.build
@key_grab_manager.grab_keys
puts 'remap keys!'
end
end
end

@ -0,0 +1,13 @@
module Xkremap
class KeyGrabManager
# @param [Xkremap::Display] display
def initialize(display)
@display = display
end
def grab_keys
XlibWrapper.ungrab_keys(@display)
XlibWrapper.grab_key(@display, 0x0062, 1<<2) # C-b
end
end
end

@ -0,0 +1,33 @@
module Xkremap
class KeyRemapBuilder
# @attribute [Hash] prebuilt
# [Fixnum] keycode -> [Fixnum] state -> [Proc] handler
attr_reader :prebuilt
# @param [Xkremap::Config] config
# @param [Xkremap::Display] display
def initialize(config, display)
@config = config
@display = display
@prebuilt = Hash.new { |h, k| h[k] = {} }
@current_window = fetch_active_window
end
def build
puts 'rebuilt!'
end
def active_window_changed?
next_window = fetch_active_window
@current_window != next_window
ensure
@current_window = next_window
end
private
def fetch_active_window
XlibWrapper.fetch_active_window(@display)
end
end
end

@ -5,14 +5,41 @@
extern Display* extract_x_display(mrb_state *mrb, mrb_value display_obj);
mrb_value
mrb_xw_grab_keys(mrb_state *mrb, mrb_value self)
mrb_xw_fetch_active_window(mrb_state *mrb, mrb_value self)
{
mrb_value display_obj;
mrb_get_args(mrb, "o", &display_obj);
mrb_int keycode, state;
mrb_get_args(mrb, "o", &display_obj, &keycode, &state);
Window window;
int focus_state;
Display *display = extract_x_display(mrb, display_obj);
XGetInputFocus(display, &window, &focus_state);
return mrb_fixnum_value(window);
}
mrb_value
mrb_xw_grab_key(mrb_state *mrb, mrb_value self)
{
mrb_value display_obj;
mrb_int keycode, state;
mrb_get_args(mrb, "oii", &display_obj, &keycode, &state);
Display *display = extract_x_display(mrb, display_obj);
XGrabKey(display, XKeysymToKeycode(display, keycode), state, XDefaultRootWindow(display), True, GrabModeAsync, GrabModeAsync);
Window root = XDefaultRootWindow(display);
XGrabKey(display, XKeysymToKeycode(display, XK_b), ControlMask, root, True, GrabModeAsync, GrabModeAsync);
return mrb_nil_value();
}
mrb_value
mrb_xw_ungrab_keys(mrb_state *mrb, mrb_value self)
{
mrb_value display_obj;
mrb_get_args(mrb, "o", &display_obj);
Display *display = extract_x_display(mrb, display_obj);
XUngrabKey(display, AnyKey, AnyModifier, XDefaultRootWindow(display));
return mrb_nil_value();
}
@ -21,5 +48,7 @@ void
mrb_xkremap_xlib_wrapper_init(mrb_state *mrb, struct RClass *mXkremap)
{
struct RClass *cXlibWrapper = mrb_define_class_under(mrb, mXkremap, "XlibWrapper", mrb->object_class);
mrb_define_class_method(mrb, cXlibWrapper, "grab_keys", mrb_xw_grab_keys, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, cXlibWrapper, "fetch_active_window", mrb_xw_fetch_active_window, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, cXlibWrapper, "grab_key", mrb_xw_grab_key, MRB_ARGS_REQ(3));
mrb_define_class_method(mrb, cXlibWrapper, "ungrab_keys", mrb_xw_ungrab_keys, MRB_ARGS_REQ(1));
}

Loading…
Cancel
Save