Can you manually send a keyboard input to a client in AwesomeWM while a keygrabber is running? - awesome-wm

I am trying to write an api for awesome in such a way that the user could create widgets which behave exactly like regular clients. They can be "focused", can receive keyboard and mouse input, etc. And currently, I'm having trouble in making widgets and clients act the same in regards to keyboard input.
Ideally, in order to make them behave the same, I would be able to write something like:
local client_lib = require("") -- a library to work with real clients
local function send_key_input(thing, key)
if client_lib.is_client(thing) then
-- on clients maybe we have to do something special to "input" a key
client_lib.manually_send_key_input(thing, key)
else -- we have a widget that acts as a client
-- on regular widgets, we can just emit a "KeyPressed" signal and the
-- widget will handle the rest
thing:emit_signal("KeyPressed", key)
end
end
local client_manager_data = {
currently_focused_client_or_widget = nil,
}
root.keys.connect_signal("KeyPressed", function(key, modifiers, event)
if client_manager_data.currently_focused_client_or_widget == nil then
return
end
send_key_input(client_manager_data.currently_focused_client_or_widget, {
key = key,
modifiers = modifiers,
event = event,
})
end)
The problem with this is that root.keys does not emit a signal when a key is pressed.
I thought I would maybe solve this by running a global keygrabber.run, store all my keybindings in the keygrabber instead of root.keys, and emit a signal myself whenever a key is pressed. The problem with this is that if a keygrabber is running, the real focused clients don't receive keyboard input anymore and I'm not sure if I can manually "Send" a keyboard input signal to a client.
So my question is: can I somehow send keyboard input manually to a client? and if not, how would I be able to solve this problem of making real clients and widget-clients behave the same from a keyboard input perspective?

Related

How can I detect what room a user disconnected from?

I have an application that I need to pass the room the current user has just disconnected from to the server. The user can be in multiple rooms via multiple tabs.
I can detect that the user has left this way but it does not seem to be able to have data passed with it:
#socketio.on('disconnect')
def on_disconnect():
print(session['id'])
print("user left " )
In my client end I have tried this:
socket.on('disconnect', function () {
socket.emit('user_disconnect', {"channel": "{{symbol}}"});
});
This emit never goes through to the server though. I am guessing the window closes or changes before this can get called? How can I pass data to the server on the disconnect event?
I believe I have figured out a solution.
Utilizing request.sid, I can store the room name in a list along with this sid on the server-side join event.
#socketio.on('join')
def on_join(data):
active_rooms.append(json.dumps({'room':data['channel'],'socket_id':str(request.sid)}))
When the disconnect event is triggered I can view this same sid and use it as a lookup in the list. The sid appears to be unique for each socket connection so multiple tabs will result in a new sid.

How to make an action connection for multiple buttons in xcode10?

I am wondering how do we make an action connection for multiple buttons in Xcode10. Just ONE CODE for ALL buttons.NOT SEPARATE.
For example, we have 7 music key buttons, and we want to make one action connection for all 7 of them, and then continue to code to make the code know which key is being exactly pressed. As the code that I posted in this question, how do we make " #IBAction func notePressed(_ sender: UIButton)" this line? Not by typing, by clicking and dragging.
Another example is, we have "true" and "false", two buttons. We want to make just one action connection for these two buttons in ViewController.swift.
I know how to make one action connection for a single button, but when it comes to multiple buttons, I do not know how to do. I use xcode10
I have tried to hold the command and select all the buttons at the same time, and then hold the control key and try to drag all the buttons from the mainStoryBoard to my swift code, but it seems that I only created an action connection for on button in this way.
#IBAction func notePressed(_ sender: UIButton)
{
let selectedNote : String = soundArray[sender.tag - 1]
playSound(inputNote : selectedNote)
}
If you find the connected actions part in the First Responder part in the storyboard, you are able to connect it one by one as the screenshot.

Qt pass data between multiple forms

I am new to Qt and understands the concept of signal and slots. However I am not able to implement it.
My objective is:
Form1 has a button Config. So when I click Config it should open another form Form2( without closing Form1) and send a string strData to Form2.
In Form2 I set some value in the string strData. Then I click Ok button in Form2, Form2 should close and return back the string to Form1.
When the call returns back to Form1, it should continue from where it emitted the signal to invoke Form2.
Any help is highly appreciated.
You can't do this using signals/slots; the signal is emitted, and all of the connected slots are executed, and then the code continues from where the signal is emitted and eventually returns to the event loop. That's when your second form is actually shown and the user can respond to it, but by then, your code is long past where the signal was emitted.
What I believe you're looking for is the QDialog::exec method; use it in place of the signal. The basic pattern of the code is:
// This is the response to click on Config...
Form2Dialog form2;
form2.setSomeStringValue (some_value);
if (form2.exec() == QDialog::Accepted)
{
QString some_new_value = form2.newValue();
}
The Form2Dialog is a subclass of QDialog where you've added your own setSomeStringValue and newValue methods. (What you actually name these is up to you.)
The important thing is that the exec method blocks and doesn't return until the user selects OK or Cancel on the dialog, or closes it using the "close" button in the title bar (if there is one).

QInputMethod : programatically end the input method session

I have a QWidget ( lets call it parentWidget ) on which I have enabled the input method by setting the attribute : Qt::WA_InputMethodEnabled.
My interest is to pop up a Line dialog ( lets call it inputMethodEditor ) which should further handle all the input of the text.
Now I have read that the inputMethod works like a session, means it has states like startedToCompose, composing, completing. While the input method is in startedToCompose or composing state it sends the string under composition in preEditString through inputMethodEvent and once the session completes it sends the final composed string in commitString().
My intent is to finish this session started on parentWidget as soon as the inputMethodEditor dialog is popped up.
So, the question is, whether there is a way to close this session programmatically.?
After exploring a while, I could figure it out, I don't know how I overlooked it earlier.
So the trick is to invoke QInputMethod::reset function.
Something like this:
QApplication* application = static_cast<QApplication *>(QApplication::instance());
application->inputMethod()->reset();

Flash: How to dispatch a click event at the top of a loaded .swf?

So I'm trying to build a tool that will allow me and other users to all open the same .swf, and then I as the Admin user am able to interact with mine while they all see my mouse movements and button clicks etc on theirs.
I'm using BlazeDS to manage this and I'm getting data sent back and forth etc - no difficulties there. The issue I'm running into is this:
In an "Admin" instance, I click a button. I capture that X and Y, then tell Blaze to tell my clients to dispatch a Click event at that X and Y. On my client side, I get that data and dispatch a Click event at that X and Y - but the click is actually caught at the stage level. The click on my client side takes place UNDER all of my buttons and other content - so the whole thing fails.
Does this make sense? Is there a way to tell it to start the click event at the top?
If you are unable to architect the loaded swf's to use a better architecture you could try something a little more hackish to get buttons working.
Have a look at the methods getObjectsUnderPoint and areInaccessibleObjectsUnderPoint of the DisplayObjectContainer. Combined with hasEventListener you should be able to emulate what you want.
Here is some untested pseudo-code:
function detectClick(pt:Point):void
{
var objsUnderPoint:Array = containerStage.getObjectsUnderPoint(pt);
var clickable:Array = [];
for each(dispObj:DisplayObject in objsUnderPoint)
{
if(dispObj.hasEventListener(MouseEvent.CLICK))
{
clickable.push(dispObj);
}
}
if(clickable.length)
{
// sort on depth here
// that might be tricky since you'll be looking at grandchildren
// and not just children but it is doable.
var topMostClickable:DisplayObject = ???
topMostClickable.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));
}
}
areInaccessibleObjectsUnderPoint is important if you think their might be security restrictions (e.g. cross-domain issues) so you can debug if things go wrong.
Also note that you may want to (or need to) fill in more details of the MouseEvent (like the proper target, localX, localyY etc.)
Sounds like you need to set focus to the top most component of the x and y positions before dispatching the click event.
That said, I wonder what the use case is for something like this; as opposed to using a screen sharing tool such as Connect.
This seems like a poor way to implement what you are trying to do. If you "click" in the admin tool you are probably actually triggering some event. Why not trigger that event instead of sending the mouse click?
I'd just keep a map of actions and then when something happens in the Admin interface send the key to the action.
e.g.
In the admin:
myButton.addEventListener(MouseEvent.CLICK, handleClickButton);
function handleClickButton(event:MouseEvent):void
{
doSomeAction();
sendTriggerToClient(MyActions.SOME_TRIGGER);
}
In the client:
var actionMap:Object = {};
actionMap[MyActions.SOME_TRIGGER] = doSomeAction;
function receiveTriggerFromAdmin(trigger:String):void
{
var responseFunc:Function = actionMap[trigger];
responseFunc();
}
I hope that pseudo-code makes sense. Just abstract what happens as a result of a click into a separate function (doSomeAction) and then have the admin send a message before calling that function. In the client wait for any trigger that comes through and map it to the same function.

Resources