Experimentally add press and release DSL

pull/1/head
Takashi Kokubun 8 years ago
parent a37f2924a2
commit 0b9600d1ea

@ -1,15 +1,19 @@
module Xkremap
class Config
Key = Struct.new(:keysym, :modifier)
Remap = Struct.new(:from_key, :to_keys)
Remap = Struct.new(:from_key, :to_keys)
class Window < Struct.new(:class_only, :class_not)
def class_only
super ? Array(super) : []
class Key < Struct.new(:keysym, :modifier, :action)
def initialize(*)
super
self.action ||= :input
end
end
def class_not
super ? Array(super) : []
class Window < Struct.new(:class_only, :class_not)
def initialize(*)
super
self.class_only = self.class_only ? Array(self.class_only) : []
self.class_not = self.class_not ? Array(self.class_not) : []
end
end

@ -19,10 +19,28 @@ module Xkremap
ConfigDSL.new(@config, win).instance_exec(&block)
end
def press(str)
key = compile_exp(str)
key.action = :press
key
end
def release(str)
key = compile_exp(str)
key.action = :release
key
end
private
def compile_exp(str)
KeyExpression.compile(str)
def compile_exp(exp)
if exp.is_a?(Config::Key)
exp
elsif exp.is_a?(String)
KeyExpression.compile(exp)
else
raise "unexpected expression: #{exp.inspect}"
end
end
end
end

@ -36,21 +36,7 @@ module Xkremap
end
def to_keysym(keyexp)
X11.const_get(x11_const_name(keyexp))
end
def x11_const_name(keyexp)
if keyexp.length == 1
"XK_#{keyexp.downcase}"
else
"XK_#{capitalize(keyexp)}"
end
end
def capitalize(str)
result = str.downcase
result[0] = str[0].upcase
result
X11.const_get("XK_#{keyexp}")
end
end
end

@ -20,11 +20,23 @@ module Xkremap
from = remap.from_key
tos = remap.to_keys
result[to_keycode(from.keysym)][from.modifier] = Proc.new do
tos.each do |to|
XlibWrapper.input_key(@display, to.keysym, to.modifier)
actions = remap.to_keys.map do |to|
case to.action
when :input
Proc.new { XlibWrapper.input_key(@display, to.keysym, to.modifier) }
when :press
Proc.new { XlibWrapper.press_key(@display, to.keysym, to.modifier) }
when :release
Proc.new { XlibWrapper.release_key(@display, to.keysym, to.modifier) }
end
end
result[to_keycode(from.keysym)][from.modifier] =
if actions.length == 1
actions.first
else
Proc.new { actions.each { |action| action.call } }
end
end
end

@ -68,6 +68,50 @@ create_key_event(Display *display, Window window, KeySym keysym, unsigned int mo
};
}
void
send_press_event(Display *display, Window window, KeySym keysym, unsigned int modifiers)
{
XKeyEvent event = create_key_event(display, window, keysym, modifiers, KeyPress);
XSendEvent(display, window, True, KeyPressMask, (XEvent *)&event);
}
void
send_release_event(Display *display, Window window, KeySym keysym, unsigned int modifiers)
{
XKeyEvent event = create_key_event(display, window, keysym, modifiers, KeyRelease);
XSendEvent(display, window, True, KeyReleaseMask, (XEvent *)&event);
}
mrb_value
mrb_xw_press_key(mrb_state *mrb, mrb_value self)
{
mrb_value display_obj;
mrb_int keysym, modifiers;
mrb_get_args(mrb, "oii", &display_obj, &keysym, &modifiers);
Display *display = extract_x_display(mrb, display_obj);
Window window = get_focused_window(display);
send_press_event(display, window, keysym, modifiers);
return mrb_nil_value();
}
mrb_value
mrb_xw_release_key(mrb_state *mrb, mrb_value self)
{
mrb_value display_obj;
mrb_int keysym, modifiers;
mrb_get_args(mrb, "oii", &display_obj, &keysym, &modifiers);
Display *display = extract_x_display(mrb, display_obj);
Window window = get_focused_window(display);
send_release_event(display, window, keysym, modifiers);
return mrb_nil_value();
}
mrb_value
mrb_xw_input_key(mrb_state *mrb, mrb_value self)
{
@ -78,11 +122,9 @@ mrb_xw_input_key(mrb_state *mrb, mrb_value self)
Display *display = extract_x_display(mrb, display_obj);
Window window = get_focused_window(display);
XKeyEvent event = create_key_event(display, window, keysym, modifiers, KeyPress);
XSendEvent(display, window, True, KeyPressMask, (XEvent *)&event);
send_press_event(display, window, keysym, modifiers);
send_release_event(display, window, keysym, modifiers);
event = create_key_event(display, window, keysym, modifiers, KeyRelease);
XSendEvent(display, window, True, KeyReleaseMask, (XEvent *)&event);
return mrb_nil_value();
}
@ -138,6 +180,8 @@ 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, "input_key", mrb_xw_input_key, MRB_ARGS_REQ(3));
mrb_define_class_method(mrb, cXlibWrapper, "press_key", mrb_xw_press_key, MRB_ARGS_REQ(3));
mrb_define_class_method(mrb, cXlibWrapper, "release_key", mrb_xw_release_key, MRB_ARGS_REQ(3));
mrb_define_class_method(mrb, cXlibWrapper, "keysym_to_keycode", mrb_xw_keysym_to_keycode, MRB_ARGS_REQ(2));
mrb_define_class_method(mrb, cXlibWrapper, "fetch_active_window", mrb_xw_fetch_active_window, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, cXlibWrapper, "fetch_window_class", mrb_xw_fetch_window_class, MRB_ARGS_REQ(2));

Loading…
Cancel
Save