Window Shake (macOS)

Hi… I’m trying to create a window that asks the user for a password to log in to the app - I want it to look like the built in MacOS dialog to unlock, for example, items in system preferences - whereby the window shakes if the user entered the wrong password - does anyone know of a declare that can do this? tia

1 Like

NSWindowMBS has a method with animation:

• method setFrame(frameRect as NSRectMBS, display as boolean, animated as boolean)

You may need to use a timer to move it three times each direction.

1 Like

Hi Christian, I was kinda hoping that someone knew of an Apple appkit call that could be made so its more native.

NSWindow has a few interesting methods like this one:

  • (void)_shake;

You can try it. No idea what it does!

Are you able to supply an example Christian…?

Seems to work here:

Sub Action() Handles Action
  Declare Sub shake Lib "Cocoa" Selector "_shake" (windowRef As Integer)
  shake(Self.Handle)
End Sub
3 Likes

Truly. you are a legend! Thank you so much.

3 Likes
sub shake extends w as window
Const shakewidth=6
const shakedel = .062
dim startingleft as Integer = w.Left
dim lastupdate As integer

for s as Integer = 0 to 3
  w.left = startingleft - shakewidth/2
  app.DoEvents
  DelayMBS shakedel
  w.left =startingleft + shakewidth/2
  app.DoEvents
  DelayMBS shakedel
Next

w.left = startingleft

Let the doevents flames begin!

5 Likes

I would be cautious on this one as it appears to be private API (Apple use only), which means your app may be rejected from the  App Store or Apple’s Notarization service.

2 Likes

Meanwhile the other suggestion uses app destabilizing DoEvents and requires third party plugins. So choose your poison?

There might be something in Thom’s AnimationKit (open source) …

but it is also fairly easy to do it yourself without plugins, declares, or doEvents (and I send you a pm for a demo project).

2 Likes

Well, if you make selector from text, you may pass through their checks.
At least the selector will not show up in the scans of the application file.

1 Like

I use this in one of my on the AppStore. Up to now… no problems. fingers crossed.

1 Like

I use Julia’s approach but I use a Timer to control the movements. Works nice.

1 Like

You can easily use timers instead of DelayMBS and doevents, I just pulled this out of a module that’s worked for me over the years :slight_smile:

2 Likes

How can this be done?

hah, why are the most interesting “hacker subjects” hidden under such a topic. I thought “Window Shake” is of no interest to me, now it has the potential to become my favourite thread :slight_smile:

The difference would be that with MBS the shake method does not return until the shaking is done… With a Timer that would not be the case, but given the short duration probably not an issue.

I threw together an example using a timer and a Window extension method in a module:

Private Class ShakeTimer
Inherits Timer
	#tag Event
		Sub Action()
		  Const ShakeDelta as Integer =12
		  Const Shakes as Integer = 2
		  
		  Select Case W.Left - StartingPosition
		  Case 0
		    W.Left = StartingPosition - ShakeDelta
		  Case -ShakeDelta
		    W.Left = StartingPosition + ShakeDelta
		    Rep = Rep + 1
		  Else
		    W.Left = StartingPosition - ShakeDelta
		  End Select
		  
		  If Rep >= Shakes Then
		    W.Left = StartingPosition
		    Me.Mode = Timer.ModeOff
		    Myself = Nil
		    W = Nil
		  End if
		End Sub
	#tag EndEvent

	#tag Method, Flags = &h0
		Sub Constructor(W as Window)
		  me.Period = 75
		  me.Mode = Timer.ModeMultiple
		  me.W = W
		  me.Myself = me
		  StartingPosition = W.Left
		End Sub
	#tag EndMethod

	#tag Property, Flags = &h21
		Private Myself As Shaketimer
	#tag EndProperty

	#tag Property, Flags = &h21
		Private Rep As Integer
	#tag EndProperty

	#tag Property, Flags = &h21
		Private StartingPosition As Integer
	#tag EndProperty

	#tag Property, Flags = &h21
		Private W As Window
	#tag EndProperty

And then the extension method is just:

Public Sub Shake(Extends W as Window)
  Dim T as new ShakeTimer(W)
  
End Sub

I create a circular reference in the timer on purpose that gets broken when the shaking is done. That way one does not need to keep a reference to it during the shake but still not have a leak.

7 Likes

I just tried this in a Windows 7 VM on my Mac… Besides shaking sideways, the window also moves up! Seems like an Xojo bug… On a Windows 10 VM it works as expected…

BTW is window shaking a thing on Windows?

Fixed that by also saving Window.Top and setting that as well as Window.Left with each move… though I should not have to.

-Karen

2 Likes