How to turn off keyboard sounds in Cocoa application? - c++

I have a problem with my OpenGL Cocoa application - every time a keyUp / KeyDown event is fired, a system sound is being played... How can I disable this logic for my application?
I have a bad feeling that for some strange reason my application may treat a key press as an error and play system alert sound... Please help!

add to your NSView/NSWindow subclass
- (void)keyDown:(NSEvent *)theEvent {
and make exception on up and down keys, but for other [super keyDown:theEvent];
i think it's may sense

For me, the following has turned out to be the optimal solution:
override func awakeFromNib() {
// Do your setup here.
NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
if keyDownPressed(with: $0) {
return nil
}
return $0
}
}
func keyDownPressed(with event: NSEvent) -> Bool {
print("caught a key down: \(event.keyCode)")
if event.keyCode == 125 {
//your code for arrow down here
return true
}
if event.keyCode == 126 {
//your code for arrow up here
return true
}
return false
}

Create a Cocoa Class, subclassing it from NSView
Set it as the class for your View instead of standard greyed-out NSView in storyboard
Add the following to your subclass implementation:
#implementation YourCustomNSView
- (BOOL)acceptsFirstResponder {
return YES;
}
- (void)keyDown:(NSEvent *)theEvent {
NSLog (#"keypress %#", theEvent);
// [super keyDown:theEvent]; // this line triggers system beep error, there's no beep without it
}
#end

Swift 5.6 solution
It's caused because of unhandled keydown events in your responder chain.
Make sure some NSView subclass in your responder chain overrides this and returns true.
override performKeyEquivalent(with event: NSEvent) -> Bool {}

Related

HERE SDK Orientation change too late

I am using HERE-Android-SDK to build a simple navigation solution with offline maps.
In order to automatically center and rotate the map (depending on location and orientation of the user) I am using the PositioningManager class from the HERE-SDK. It seems that the orientation update is some seconds too late when an active navigation is running.
I am using the following code snippets to do so.
val positioningManager = PositioningManager.getInstance()
positioningManager.addListener(WeakReference(positionListener))
positioningManager.start(PositioningManager.LocationMethod.GPS)
var positionListener = object : PositioningManager.OnPositionChangedListener {
override fun onPositionFixChanged(
p0: PositioningManager.LocationMethod?,
p1: PositioningManager.LocationStatus?
) {
// do nothing here
}
override fun onPositionUpdated(
method: PositioningManager.LocationMethod?,
position: GeoPosition?,
isMapMatched: Boolean
) {
if (position == null) return
// update map center and orientation
}
}
override fun onPause() {
positioningManager.stop()
}
override fun onResume() {
positioningManager.start(PositioningManager.LocationMethod.GPS)
}
Is there anything I can do to avoid the too late orientation update?
Thanks for all of your help in advance!

SwiftUI Drag&Drop: Accessing the dragged item in validateDrop

G'day everyone,
I'm trying to interrogate the dragged object during the validate phase of drag and drop in SwiftUI, but haven't been able to make it work. Here's my validateDrop method:
func validateDrop(info: DropInfo) -> Bool {
print("Drop Validating")
print ("Dropping into slot where \(rosterPlayer!.givenName!) \(rosterPlayer!.surname!) is")
guard info.hasItemsConforming(to: [PlayerShirtUTT.uti.identifier]) else {
return false
}
let itemProviders = info.itemProviders(for: [PlayerShirtUTT.uti.identifier])
guard let itemProvider = itemProviders.first
else {
return false
}
print ("Lets check")
itemProvider.loadObject(ofClass: Player.self) { player, _ in
let player = player as? Player
// Do the player checks here
print ("Player check code")
}
return true
}
Exactly the same code in my performDrop method works fine... can anyone point me in the right direction here please?
If anyone else is looking for an answer to this, the answer is you can't.
Documentation reference:
https://developer.apple.com/documentation/uikit/drag_and_drop/making_a_view_into_a_drop_destination
The content of the dragged item is only available asynchronously after the drop is concluded (i.e. only in perdormDrop() ).
So, now I'm looking at ways to use the UTT as a distinguishing identifier for the same base data.

Is there an event that fires from a C++ program when a control is about to lose focus?

I am trying to fix a validation bug in a MFC CEdit control. Currently, validation is performed in an OnChange event handler. But this does not work because it validates data before the user is finished entering it.
So, instead, I am trying to validate inside an OnKillFocus event handler. If validation fails, then I use GotoDlgCtrl() to return focus to the edit box that contained the invalid data. And when I call GotoDlgCtrl(), the kill focus event fires again, and I'm in an infinite loop.
So, I'd like to handle an event that fires just before the control loses focus, so that if I determine that the data is invalid, I can stop focus from leaving and instead get the user to enter correct data.
I know I've seen a Validating event someplace, but that was probably in the .Net world. But it offers the functionality I'm looking for.
Right-click the dialog resource and invoke Class Wizard:
Next, go to the Virtual Functions tab, locate PreTranslateMessage and add it:
Then, you can do something like this:
BOOL CTestDlgDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_CHAR)
{
CWnd *pControl = GetDlgItem(IDC_EDIT1);
if (pControl->GetSafeHwnd() == pMsg->hwnd)
{
if (pMsg->wParam == _TINT('!'))
{
AfxMessageBox(_T("Not allowed ! character"));
return TRUE;
}
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
Normally the control is a member variable of type CEdit so you could compare against m_edit.GetSafeHwnd() instead.
Results:
Update
I realise you stated:
But this does not work because it validates data before the user is finished entering it.
You could use WM_KEYUP instead:
BOOL CTestDlgDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYUP)
{
CWnd *pControl = GetDlgItem(IDC_EDIT1);
if (pControl->GetSafeHwnd() == pMsg->hwnd)
{
CString str;
GetDlgItemText(IDC_EDIT1, str);
if (str.Find(_T("!")) >= 0)
{
AfxMessageBox(_T("Not allowed ! character"));
return TRUE;
}
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
That is give you a chance to validate after the display has been updated.
An alternative it to customize your DoDataExchange handler. In there you can validate as required. Then in your code you simple test the return value of UpdataData(TRUE) for FALSE.

Swift 3 - how to move sprite node when a bool is true?

Ok, I am working in Swift 3 playgrounds and need to move a sprite node to a certain point ONLY when the user's mouse is down, stopping when it's released. So far I have:
override func mouseDown(with event: NSEvent) {
mouseIsDown = true
}
override func mouseDragged(with event: NSEvent) {
}
override func mouseUp(with event: NSEvent) {
mouseIsDown = false
}
func moveGuy() {
let action = SKAction.move(to: CGPoint(x: size.width / 2,y: 200), duration: 2)
action.timingMode = .easeInEaseOut
guy.run(action)
}
//UPDATE
override func update(_ currentTime: CFTimeInterval) {
if(mouseIsDown)
{
moveGuy()
}
}
This works somewhat, the problem is only after I release the mouse (mouseIsDown is false) does the SKAction actually run (smoothly). I think this is because it is being called again and again.
Normally I would use a moveBy action in little increments, but I need my node to move to a specific point.
How can I make my node move on its way to a point only when the mouse is down?
When you call
guy.run(action)
sprite-kit will run the action on the guy until completion. You're correct, moveGuy() is being called again and again (every time the frame is update, i.e. every ~33ms assuming 30fps).
Try placing moveGuy() in mouseDown(). As soon as you click, the guy will move smoothly to his destination, but he won't stop if you stop clicking. You need to somehow stop the action. What you can do is replace
guy.run(action)
with
guy.run(action, withKey: "moveGuy")
This will associate a key with your action, that you can look up later on in mouseUp():
guy.removeAction(forKey: "moveGuy")
After this, your node will move to a point only when your mouse is down. But as you've pointed out, the node's movement is still irregular if you re-click. Try changing .easeInEaseOut to .linear. The movement will then be consistent, albeit abrupt when starting/stopping.
I highly recommend the reading documentation on SKActions to gain a better understanding of how to use them.

Quit application call twice the closeevent

I have wrote an application in Qt/c++ on OSX. When quitting the app, I'm catching the closeevent to display dialog box
void MainUI::closeEvent (QCloseEvent *event)
{
if( DeviceUnplugged == false) {
ExitDialog = new DialogExit;
ExitDialog->exec();
if(ExitDialog->result() == QDialog::Accepted) {
m_device.CloseDevice();
event->accept();
}
else {
event->ignore();
}
}
}
The dialog box is correctly displayed when closing using the red cross or using the menu "quit".
but when I'm closing the app using the right click on the icon in the dock, the dialog box appears twice the close event is called twice.
Any idea why ?
Yes, I think it is normal for Mac, at least I had this in my Qt application, too (only on Mac).
I used the following workaround:
void MainUI::closeEvent (QCloseEvent *event)
{
if (m_closing)
{
event->accept();
return;
}
if( DeviceUnplugged == false) {
ExitDialog = new DialogExit;
ExitDialog->exec();
if(ExitDialog->result() == QDialog::Accepted) {
m_device.CloseDevice();
m_closing = true;
event->accept();
}
else {
event->ignore();
}
}
}
By default, boolean variable m_closing should be initialized by false of course in your class. This way second time nothing will be done (processing will be skipped). This worked for me.
Looks like this is a QT bug:
See: https://bugreports.qt.io/browse/QTBUG-43344
Also had this problem when using qt-5.6_4 ,
In my case it happened when using CMD+Q but didn't happen when using the red x button.
Used a similar patch.
I avoided accept or ignore since this is a bug and I don't think we should "talk to it" :-)
Instead I simply return when called more then once.
static int numCalled = 0;
if (numCalled++ >= 1)
return;