diff --git a/mrblib/xkremap/event_handler.rb b/mrblib/xkremap/event_handler.rb index fc379ac..223da07 100644 --- a/mrblib/xkremap/event_handler.rb +++ b/mrblib/xkremap/event_handler.rb @@ -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 diff --git a/mrblib/xkremap/key_grab_manager.rb b/mrblib/xkremap/key_grab_manager.rb new file mode 100644 index 0000000..5d67e3c --- /dev/null +++ b/mrblib/xkremap/key_grab_manager.rb @@ -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 diff --git a/mrblib/xkremap/key_remap_builder.rb b/mrblib/xkremap/key_remap_builder.rb new file mode 100644 index 0000000..3e11456 --- /dev/null +++ b/mrblib/xkremap/key_remap_builder.rb @@ -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 diff --git a/src/xlib_wrapper.c b/src/xlib_wrapper.c index 7004160..b56bdfc 100644 --- a/src/xlib_wrapper.c +++ b/src/xlib_wrapper.c @@ -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)); }