I am trying to dispatch (inject) a GTK keyboard event to some window, in specific the window with a webkit webview inside of it. Problem that I have is with special keys like Backspace, Up, Down etc. For some reason they are not injected properly, meaning that corresponding functionality is not triggered. For other keys it works perfectly. I tried to focus the keyboard on the window and put the window on the top of the window z-index stack, but it doesn't help.
GdkEvent* const event = gdk_event_new(GDK_KEY_PRESS);
event->key.window = self->window->window;
event->key.send_event = TRUE;
event->key.time = GDK_CURRENT_TIME;
event->key.state = 0; event->key.keyval = key_value;
event->key.hardware_keycode = 0;
event->key.length = 0; event->key.string = 0;
event->key.group = 0;
//key_value is the code for the key.
This is the C to Python binding part where I just pass a keycode (key_value) to the function. I do the similar thing for key release event (GDK_KEY_RELEASE). In Python part I call those two functions (press and then release) and it works for normal keys like for a, s, d, etc. However, it doesn't work for BackSpace, Enter, Delete etc.
I solved the problem by using the KeyMap object that I get with gtk.gdk.keymap_get_default(). KeyMap has method get_entries_for_keyval(keycode) to which you need to pass just the value of keycode. It returns a triple: hardware_code, group and level. So when I passed the hardware_code and group everything started to work, except arrow keys.
Related
Trying to learn to write applications with Gtk2Hs I'm getting difficulties bridging the gap between the event driven Gtk2HS and the persistent state of my model. So to simplify, lets say that I have this simple application
module Main where
import Graphics.UI.Gtk
import Control.Monad.State
main = do
initGUI
window <- windowNew
button <- buttonNew
set button [buttonLabel := "Press me"]
containerAdd window button
-- Events
onDestroy window mainQuit
onClicked button (putStrLn ---PUT MEANINGFUL CODE HERE---)
widgetShowAll window
mainGUI
and the state of my application is how many times the button has been pressed. Seeing other posts like this they rely on MVars or IORefs which do not seem satisfactory to me, because in the future maybe I will want to refactor the code so the state lives on its own context.
I think that the solution should use the State monad using a step function like:
State $ \s -> ((),s+1)
but I'm not sure about the implications, how to do that in the above code or even if that monad is the right solution to my problem.
There's basically two approaches:
Use a pointer of some kind. This is your IORef or MVar approach. You can hide this behind a MonadState-like interface if you like:
newtype GtkT s m a = GtkT { unGtkT :: ReaderT (IORef s) m a } deriving (Functor, Applicative, Monad, MonadIO)
runGtkT = runReaderT . unGtkT
instance MonadIO m => MonadState s (GtkT s m) where
get = GtkT (ask >>= liftIO . readIORef)
put s = GtkT (ask >>= liftIO . flip writeIORef s)
Pull an "inversion of control" style trick. Write a callback that prints a number, then replaces itself with a new callback that prints a higher number.
If you try to use State or StateT directly, you're gonna have a bad time.
I was wondering if you could receive keyboard input just like Java, C+, etc. Or if there isn't is there external libraries?
Here's some info on the 2D, Maze-Game:
You use the arrow keys to navigate through the maze. You use the UP and DOWN arrow keys to select the objects in the menu, for example:
--> New Game
Load Game
Options
And so on... I appreciate any help. Good day.
Lua on its own does not provide any libraries that aren't part of ANSI C, which is part of the extensive portability of the language.
As such, you miss out on things like keyboard input and graphics, but also operations that might be considered "simple," like listing the files in a directory.
Most likely, there's a library for what you need, and if there isn't, then keep in mind that Lua is one of the friendliest languages to write C-side libraries for.
LOVE is a good framework that couples quite a few extensions to Lua (including a rather abstracted interface to SDL) with a distribution method, more or less. If you're developing games with Lua, this is a good place to start.
EDIT: If you're on Windows with LuaJIT and you're okay with global key hooks, then I developed a library recently (May 2015) that solves that problem: https://github.com/LPGhatguy/global-keys
There are libraries like curses that may help; here is one tutorial one reading arrow keys with curses in Lua. There is also luaposix library, which includes curses.
I have answer if you use linux this code will work. just try my code on other platform see if it work(if you curious). It doesn't echo the arrow key and doesn't wait until you press enter.
Modify some my code if this cause some problem.
This might be very useful for your 2D maze project
function getch_unix() --This return key pressed instantly without waiting until user press enter key
os.execute("stty -echo raw")
os.execute("stty cbreak </dev/tty >/dev/tty 2>&1")
local key = io.read(3) --must read three letter for getArrowKey to work
os.execute("stty -cbreak </dev/tty >/dev/tty 2>&1");
return(key);
end
function getArrowKey()
function split(str)
local tmp = {}
for let in string.gmatch(str, ".") do
table.insert(tmp, let)
end
return tmp
end
--[[
A is up arrow
B is down arrow
D is left arrow
C is right arrow
]]
local key = split(getch_unix())
if string.lower(key[3]) == "a" then
return "up"
elseif string.lower(key[3]) == "b" then
return "down"
elseif string.lower(key[3]) == "d" then
return "left"
elseif string.lower(key[3]) == "c" then
return "right"
else
error("Invalid arrow key!")
end
end
I get this way when i exprimenting with getch_unix() function that i found on internet searching to get a pressed key without echoing at all and not waiting for you press enter button.
EDIT:
Im also found https://github.com/max1220/lua-getch it has several useful features for your use case more info at the git if my code still not fit with your use case it also shorthen your code
I'm running an update() method n times per second to "update" the keyboard input from the user so I can read it later in the logic part of the program. So I find two ways of implementing this in the SDL Docs and I'm not sure which one should I use.
1; Loop for all events using SDL_PollEvent searching for key down/up events and saving the key states in a map so I can check for each key state in the logic of the program.
Note: Alternatively, I can also use SDL_PeepEvents instead of SDL_PollEvent to take only the event types that matter; so, it would not "thrown away" the events on the queue.
std::map<int, bool> keyboard; // Saves the state(true=pressed; false=released) of each SDL_Key.
void update()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = true;
break;
}
}
}
2; Taking a snapshot from the keyboard each frame so I can read it easily.
Uint8* keyboard;
void update()
{
SDL_PumpEvents();
keyboard = SDL_GetKeyState(NULL);
}
With any of above implementations I can read keyboard just like this:
if (key_map[SDLK_Return]) printf("Return has been pressed.");
Also, is there another way to do so?
I prefer to do a variation of 1, where I fill three arrays, indicating not only the current state, but also which keys just went down and which keys just went up. This allows me to easily check for those events in code (without comparing to the previous snapshot), but, most importantly, it won't miss events that last less than a frame. For example, if your game is running at 10 fps due to a slow machine, the user might press and release an important key between two calls of your update routine, and then your system will never register it. This is extremely frustrating.
SDL also sends key events when the key is held down, which allow you to have multiple key down events for each key up. I find this particularly useful when implementing keyboard scrolling through a list of items, e.g. a keyboard-controlled menu.
You should use solution 2.
Why? As SDL_GetKeyState() docs point out, before using it you are expected to call SDL_PumpEvents() to update the state array.
When you are calling SDL_PollEvent(), it implicitly calls SDL_PumpEvents(). So, it basically updates the array for SDL_GetKeyState() anyway. By parsing these events manually, you just create a second array (well, actually a much slower map) holding the same information which SDL already collected for you.
So, I would dare say that first solution means doing the same thing twice. And if you ever decide to support things such as repeated keystrokes (SDL_EnableKeyRepeat()), you'll be reimplementing even a larger part of SDL.
I realize this question is quite old, but my answer could benefit someone. Personally, I use two arrays with SDL_GetKeyState. I store one array holding the current frame's keyboard state, and one array holding that last frame's keyboard state. (With some memcpy commands, it's really easy to update them.) Along with those two arrays, I have a map that converts strings like "A" to the SDL scancode values, but that is optional.
Then, when you need to check if something is released or pressed, you can combine the two arrays to check. (I made this a function.) For example, if you know that the key is pressed this frame, but wasn't pressed last frame, it was clearly just pressed this frame. if (currentFrame["A"] == true && lastFrame["A"] == false) {/*just pressed*/}
You would then do the opposite for the released. I find that method super easy to implement and use.
I have an AutoHotkey script in which the left-mouse-button is mapped to a function. Part of the function includes simulating a left-button click offset from the actual cursor position. Not surprisingly, this ends up becoming a bit of an infinite loop.
Likewise, there is a handler that traps a key-press and performs some math before passing the key-press on through.
Is there a way perform a click without triggering the click-handler? Similarly, is there a way to send a key-press without triggering the key-press-handler?
Trap() {
MouseGetPos, x,y
;Perform some math with x and y
Click %x% %y% left ;oops, this causes Trap to get called again
}
LButton:: Trap
From the AutoHotkey manual:
$ - This is usually only necessary if the script uses the Send command to send the keys that comprise the hotkey itself, which might otherwise cause it to trigger itself.
That does the trick:
$LButton:: Trap
I actually do not see the looping behaviour you describe, so I wonder if there is some other factor at play.
If that really is the problem, then you can use a boolean flag to prevent recursive execution:
isTrapping := false
Trap() {
global isTrapping
if isTrapping = true
return
isTrapping := true
MouseGetPos x, y
; do some maths with x & y
Click %x%, %y%
isTrapping := false
}
LButton::Trap()
I've installed a keyboard hook:
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
Basically I want to take the user's keyboard taps, eat the input, and post my own input instead.
So if he taps "g" I might want to post "foo" to the textfield.
I'm writing to the textfield with CGEventPost and CGEventSetUnicodeString as found here:
http://www.mail-archive.com/cocoa-dev#lists.apple.com/msg23343.html
The problem is that each of my programmatically entered characters is hitting the keyboard hook. So I can't return NULL in the keyboard hook to block the user input... that blocks all the program's input as well!
I differentiated them on the Windows side in C# with the 'injected' flag, see my question a year ago here: How do I use low-level 8 bit flags as conditionals?
Looking for something similar in Objective-C.
Take a look at the comments in CGEventSource.h. It's a little bit easier to put the information together than using the Event Services Reference. The long, but more correct, way around looks like creating an event source (which is subject to memory management rules; you need to CFRelease it if you're done using it before program termination):
myEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
This will create your own private event source with a unique ID; you then indicate that events you create came from there:
CGEventRef myKeyboardEvent = CGEventCreateKeyboardEvent(myEventSource,
keyCode, true);
When an event comes in, check to see if it's from yourself:
if( (CGEventGetType(newEvent) == kCGEventKeyDown) &&
(CGEventGetIntegerValueField(newEvent, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource) ) {
There's also a user data field for the source that lets you pass around an arbitrary 64 bits, should you need to.
The quick and dirty way would be to try picking an event field that isn't likely to be a meaningful value for a keyboard event, like kCGMouseEventPressure and turn it into a signature:
CGEventSetIntegerValueField(myKeyboardEvent,
kCGMouseEventPressure,
0xFEEDFACE);
// The field is an int_64 so you could make the sig longer