qt keyPress/keyRelease notify work differently on Vista and Linux - linux

I found that the keyPress event is never fired until the key is actually released on Linux . This behavior is different on vista. Here is a piece of code from my application.
The difference happens when I do the following sequence:
1) CTRL key down,
2) hold it for a while
3) release it.
On Linux, nothing is printed out till the release.i.e. you'll not see anything till 3), then you'see "notify::KeyPressed" and "notify::KeyReleased".
On Vista, after 1), you'll see "notify::KeyPressed", then in 2), you can detect that the CTRL is down with QApplication::keyboardModifier().testFlag(Qt::ControlModifier). then after 3), you'll see "notify::KeyReleased".
I think what happens on vista is what I expected. How can I fix the problem on Linux and why it happens this way?
Thanks for your help!
MyApplication::QApplication
{
bool notify(Object * receiver, QEvent * event) {
try{
if (event->type() == QEvent::KeyPress) {
std::cout<<"notify::KeyPressed"<<endl;
}
if (event->type() == QEvent::KeyRelease) {
std::cout<<"notify::KeyReleased"<<endl;
}
return QApplication::notify( receiver, event );
}
catch ( ... ) {
std::cerr << "Unknown Exception caught: " << ends;
}
return false;
}
}

Finally found the problem. I'm using a virtual machine running on a blade. When you connect to the blade, the client tool, has an option: "Send First Key", by default, it is disabled, so when connected to the virtual machine, when you pressed CTRL, (remember the first key is disabled), you do not get the "keyPress" event! After I enabled that, it starts to work as expected!

Related

Hololens Perception Simulation sample test crashes device

The sample code for perception simulation crashes my device. The device do respond to voice commands but there is not response to hand gestures neither no visuals. I have to use WDR to reset it everytime
Link to the documentation
https://learn.microsoft.com/en-us/windows/mixed-reality/perception-simulation
Here is the source code.
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
try
{
RestSimulationStreamSink sink = await RestSimulationStreamSink.Create(
// use the IP address for your device/emulator
new Uri("http://127.0.0.1:10080"),
// no credentials are needed for the emulator
new System.Net.NetworkCredential("snarain", "snarain"),
// normal priorty
true,
// cancel token
new System.Threading.CancellationToken());
IPerceptionSimulationManager manager = PerceptionSimulationManager.CreatePerceptionSimulationManager(sink);
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
// If main exits, the process exits.
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
After a week of troubleshooting, I noticed the control mode switches to simulation that suspends all sensors to detect human gestures which makes the device unresponsive.
Switching it back to Default resolves this problem.
Solved !!

Handle message in MFC

I have created a simple program about CDialog and Timer in MFC.
The problem I have encountered, I think it is very normal but i cannot explain how MFC handle message in one or many threads.
The mainly source code of program:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
SetTimer(1, 10000, NULL);
return TRUE;
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BTN_START, OnBtnStartClicked)
END_MESSAGE_MAP()
void CMyDlg::OnBtnStartClicked()
{
DisplayMessage(1);
}
void CMyDlg::OnTimer(UINT nIDTimer)
{
if (nIDTimer == 1)
{
KillTimer(1);
DisplayMessage(2);
SetTimer(1, 10000, NULL);
}
}
void CMyDlg::DisplayMessage(INT nID)
{
if (nID == 1)
{
AfxMessageBox(_T("Button Clicked"));
}
else if (nID == 2)
{
AfxMessageBox(_T("Timer timeout"));
}
else
{
}
}
I debug program with following steps:
Set break points in two functions: OnBtnStartClicked() and OnTimer() and run in debug mode.
Click on Start button, the pointer of Visual Studio stops in OnBtnStartClicked(). Open Threads window, I see that the code is executed in "Main Thread".
Press F5 to continue. A message box is displayed. And I do nothing next.
In the next few seconds, the pointer of VS stops in OnTimer(). I also see in the Thread window and see that the code is also executed in "Main Thread".
Press F5 to continue. The second message box is display.
That makes me confused is: in Step 3, because I do nothing next, the "Main Thread" is temporary paused; but in Step 4, the "Main Thread" is continuously executed.
Please help me explain that make me confused!
Windows messaging is an event based system. Your program sits in a loop, checking the message queue and responding to events.
This means that when your program looks like it's waiting for you to click the OK button on the message box, it's still listening for and responding to events. One of those events would be the BN_CLICKED for the OK button, but another is a timer message.
If the program ever really pauses, your program will become unresponsive.

How to make Windows 8 tablet open the on-screen-keyboard when an input field gets focus?

I am developing an app for a Windows 8.1 tablet (using Java & eclipse RCP).
I would like Windows to automatically open the OSK when a text field receives focus and to close it again when the focus is lost. This works for some of the built-in windows functions such as search (swipe in from the right side of the screen and the search field appears)
I have tried to open OSK programmatically but it does not work as expected. The OSK is started but in a window which removes the focus from the input field and, therefore, the characters typed to not reach the input.
The OSK is started as follows
cmd /c c:WINDOWS/system32/osk.exe
Perhaps there is another way to start it so that the input field does not loose focus.
UPDATE
I managed to open the keyboard programmatically using
Runtime.getRuntime().exec(path + "tabtip.exe")
but only after I ran the app as Administrator. Why can I run tabtip from the command line but not start it from my app?
namespace Windows.ApplicationModel.Search.SearchPane has a property called ShowOnKeyboardInput.
However, this is used for searching via Search charm.
This is my solution which seems to work ok. I had hoped that Windows 8 might be able to do this automatically but I couldn't find a way.
text.addFocusListener(new FocusListener()
{
#Override
public void focusLost(FocusEvent arg0)
{
LogUtil.logInfo("Closing OSK");
try
{
if(Settings.getBoolean(Settings.OSK_USETABTIP)) {
Runtime.getRuntime().exec("cmd /c taskkill /IM tabtip.exe");
} else {
Runtime.getRuntime().exec("cmd /c taskkill /IM osk.exe");
}
}
catch (IOException e)
{
LogUtil.logError(e.toString());
}
}
#Override
public void focusGained(FocusEvent arg0)
{
try
{
String sysroot = System.getenv("SystemRoot");
if(Settings.getBoolean(Settings.OSK_USETABTIP)) {
LogUtil.logInfo("Opening TabTip");
ProcessBuilder pb = new ProcessBuilder("C:/pathtotabtip/tabtip.exe");
pb.start();
} else {
LogUtil.logInfo("Opening OSK");
ProcessBuilder pb = new ProcessBuilder(sysroot + "/system32/osk.exe");
pb.start();
}
}
catch (Exception e)
{
LogUtil.logError(e.toString());
}
}
});
NOTE
taskkill tabtip.exe only works when run as Administrator on Windows 8. Starting via cmd does not need these privileges. Why ?!? :-(

RegisterEventHotKey CMD+TAB in Mountain Lion

According to this post:
ShortcutRecorder record CMD+Tab
calling setCanCaptureGlobalHotKeys:YES on the ShortCutRecorder control should allow you to capture CMD+TAB. However, it doesn't seem to work. I created this small app myself to see whats going on:
OSStatus myHotKeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData)
{
NSLog(#"YEAY WE DID A GLOBAL HOTKEY");
return noErr;
}
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
EventHotKeyRef myHotKeyRef;
EventHotKeyID myHotKeyID;
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventHotKeyPressed;
myHotKeyID.signature = 'mhk1';
myHotKeyID.id = 1;
InstallApplicationEventHandler(&myHotKeyHandler, 1, &eventType, NULL, NULL);
OSStatus status = RegisterEventHotKey(kVK_Tab,
cmdKey,
myHotKeyID,
GetApplicationEventTarget(),
0,
&myHotKeyRef);
NSLog(#"status:%d", status);
}
#end
If I use cmdKey + optionKey, then it does work.
Is there another way to capture CMD+TAB in my own application on Mountain Lion? CMD+OPTION+TAB is not good enough for me.
Things have changed a bit since that question was asked in 2010! ⌘⇥ is detected by Dock.app with an Event Tap, and that event no longer makes it back to the application.
You can still hook ⌘⇥, but you need to beat Dock to it with an Event Tap yourself. Here's some example code, courtesy osxbook.com:
// alterkeys.c
// http://osxbook.com
//
// Complile using the following command line:
// gcc -Wall -o alterkeys alterkeys.c -framework ApplicationServices
//
// You need superuser privileges to create the event tap, unless accessibility
// is enabled. To do so, select the "Enable access for assistive devices"
// checkbox in the Universal Access system preference pane.
#include <ApplicationServices/ApplicationServices.h>
// This callback will be invoked every time there is a keystroke.
//
CGEventRef
myCGEventCallback(CGEventTapProxy proxy, CGEventType type,
CGEventRef event, void *refcon)
{
// Paranoid sanity check.
if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp))
return event;
// The incoming keycode.
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(
event, kCGKeyboardEventKeycode);
// Swap 'a' (keycode=0) and 'z' (keycode=6).
if (keycode == (CGKeyCode)0)
keycode = (CGKeyCode)6;
else if (keycode == (CGKeyCode)6)
keycode = (CGKeyCode)0;
// Set the modified keycode field in the event.
CGEventSetIntegerValueField(
event, kCGKeyboardEventKeycode, (int64_t)keycode);
// We must return the event for it to be useful.
return event;
}
int
main(void)
{
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;
// Create an event tap. We are interested in key presses.
eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
eventMask, myCGEventCallback, NULL);
if (!eventTap) {
fprintf(stderr, "failed to create event tap\n");
exit(1);
}
// Create a run loop source.
runLoopSource = CFMachPortCreateRunLoopSource(
kCFAllocatorDefault, eventTap, 0);
// Add to the current run loop.
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
kCFRunLoopCommonModes);
// Enable the event tap.
CGEventTapEnable(eventTap, true);
// Set it all running.
CFRunLoopRun();
// In a real program, one would have arranged for cleaning up.
exit(0);
}
The downside to this is that you cannot sandbox or ship an application that uses ⌘⇥ on the App Store. Not only should it be obvious why Event Taps are not allowed in those environments (they give you the ability to terminate—and even mutate—events), but the functionality Dock provides on ⌘⇥ is pretty darn useful and can't be remapped to a different keyboard shortcut, so even Witch and Switch avoid it using it by default.

Windows Phone 7 Audio Recording Problem

I'm hoping someone can help me with this. I have found the examples for recording audio using XNA in a Silverlight application. And it works, however, only the first time in. I have all the recording functionality on a seperate WP7 Page and with successive visits to the page it doesn't work. The best I can tell is the microphone.start is getting called but the micophone.status remains stopped. What is weird is the BufferReady keeps getting called and the code within that function is all running but without the microphone really starting nothing is really happening. When you exit the app and come back in again the first time visit to the page and everything works fine, but a revisit to the page and it doesn't.
void microphone_BufferReady(object sender, EventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
microphone.GetData(buffer);
stream.Write(buffer, 0, buffer.Length);
TimeSpan tsTemp = timer.Elapsed;
TextBlockSeconds.Text = tsTemp.Hours.ToString().PadLeft(2, '0') + ":" + tsTemp.Minutes.ToString().PadLeft(2, '0') + ":" + tsTemp.Seconds.ToString().PadLeft(2, '0');
if(timer.Elapsed.Seconds >5)
DoStop();
});
}
private void ButtonRecord_Click(object sender, RoutedEventArgs e)
{
DisableRecordButton();
timer = new Stopwatch();
timer.Start();
stream = new MemoryStream();
TextBlockSeconds.Text = "00:00:00";
TextBlockStatus.Text = "Recording: ";
microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
microphone.BufferReady += new EventHandler<EventArgs>(microphone_BufferReady);
microphone.Start();
}
private void DoStop()
{
if (timer.IsRunning)
timer.Stop();
if (microphone.State == MicrophoneState.Started)
{
microphone.Stop();
TextBlockStatus.Text = "Stopped: Ready to save";
}
else
{
TextBlockStatus.Text = "Ready: ";
}
TextBlockSeconds.Text = string.Empty;
EnableRecordButton();
}
Update...
I found the problem but no solution. I was calling the microphone.stop via code on a timer (so I could limit the recorded audio to 5 seconds). Exact same code to execute when a manual stop button would be clicked. When clicking the manual stop button everything worked fine, could re-visit the page and all would be fine. When the stop was called in code from the timer, next visit to the page would not work. So I implemented it with only a manual stop button but really would have been nice to do it automatically (and to know what the real issue was).
actually when you are navigating away from the page you can add
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
this.MicroPhone.BufferReady -= this.Microphone_BufferReady;
}
and when you are returning to page add
this.MicroPhone.BufferReady += this.Microphone_BufferReady;
You can add this statement either in a page loaded event or an OnNavigatedTo event
Added string name = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() to make sure that it was on the same thread (and it was).
But finally worked this out, the problem is the microphone.stop doesn't stop the microphone from continuing to fire the buffer ready event (like I was expecting). And it would seem the way the page is cached this causes some weird problems with that event still firing. So I added the code
microphone.BufferReady -= new EventHandler<EventArgs>(microphone_BufferReady);
to my code for stopping, and it all works now.
I can't see from your code how you're stopping the timer/microphone if you navigate away from the page and don't manually stop it.
If that's not it, are you ensuring that all your microphone operations are being executed on the same thread? (Just a thought.)

Resources