Live Update Window Positions on Move

Heyho,

i want to do just one simple thing…

if i drag a window (Desktop (Mac)) the window moves oh suprise but the Event “Moved” will just fire after the window is moved to the final position (Like liveResizing).

i want to know during the “drag” the current Position of the Window… maybe someone have a idea how to get the values…

greetings

AppKit on OS X doesn’t support this. NSWindowDelegate only has these two moving-related “events”:

[code]- windowWillMove:

  • windowDidMove:[/code]

So you will need to use a timer.

Which will not work, since the timer will not fire during the mouse down.

Posts on Stackoverflow show that even in Objective C this needs some acrobatic code.

I added now manualy the Delegate and the Methods for

NSSelectorFromString(“windowWillMove:”)
NSSelectorFromString(“windowDidMove:”)

its the same… WillMove just fire on starting moving and didmove fires after moving…

Beetween there is nothing in NSWindowDelegate…

greetings

I tried a while ago to come up with a Moving event, and never found a way. I did try a timer, but the window left and top does not change during the move.

OK. I was a bit too pessimistic. It appears during the move, System.MouseX and Y still work fine. So getting the coordinates of the click in the window bar and then getting the mouse coordinates gives a way to get the left and top of the window during the move with a timer :slight_smile:

Project.

What I did is a very quick job. It works, but could be refined. Creating a subclass around the timer with a “Moving” event definition would probably be better.

Hey Michel, I came up with the same thing :slight_smile:

But instead of having a Timer always running I put a Canvas over the title bar to detect MouseDown and start the Timer, then the Timer can turn itself off when it sees the mouse is up.

Usually anything in the titlebar is clipped out but this code moves the canvas from the ‘content view’ to the ‘theme frame’ (**This is a no-no by Xojo. To be proper you’ll need to create and add an NSView in pure code).

There’s also a slight issue in the Window coordinate is not always in the same relation to the mouse, for example, drag up into the menubar and the Window stops flush. You could limit the calculated value but on a multiscreen setup this may get complicated.

Canvas1: Placed over title bar and locked left+right
Timer1: Mode Off, Period 10
Label1: placed somewhere in Window

//Window Properties
startMouseX As Integer
startMouseY As Integer
startWindLeft As Integer
startWindTop As Integer

//Canvas1 Event
Function MouseDown(X As Integer, Y As Integer) As Boolean
  
  startMouseX = System.MouseX
  startMouseY = System.MouseY
  startWindLeft = self.Left
  startWindTop = self.Top
  
  Timer1.Mode = Timer.ModeMultiple
  
End Function

//Timer1 Event
Sub Action()

  if not System.MouseDown then
    me.Mode = Timer.ModeOff
    return
  end
    
  dim x As integer = startWindLeft + System.MouseX - startMouseX
  dim y As integer = startWindTop  + System.MouseY - startMouseY
  
  Label1.Text = Str(x) + ", " + Str(y) 

End Sub

//Window Event
Sub Open()
  moveControlsToTitleRegion(Array(Canvas1))
End Sub

//Window Method
Private Sub moveControlsToTitleRegion(items() As RectControl)
  declare function contentView lib "Cocoa" selector "contentView" (id As integer) As Ptr
  declare function superView lib "Cocoa" selector "superview" (id As Ptr) As Ptr
  declare function subviews lib "Cocoa" selector "subviews" (id As Ptr) As Ptr
  declare function objAtIdx lib "Cocoa" selector "objectAtIndex:" (id As Ptr, idx As UInt32) As Ptr
  declare sub      addSubView lib "Cocoa" selector "addSubview:positioned:relativeTo:" _
       (id As Ptr, aView As integer, order As integer, rel As Ptr)
  
  dim cv As Ptr = contentView(self.Handle)
  
  dim themeFrame As Ptr = superView(cv)
  
  dim firstSubView As Ptr = objAtIdx(subViews(themeFrame), 0)
  
  for i As integer = 0 to items.Ubound
    addSubView(themeFrame, items(i).Handle, 0, firstSubView)
  next
End Sub

I like simplicity.

This new project contains a “MovingWindow” class. Once into the project, simply make any window Super “MovingWindow”, and it gets a “Moving” event, Left as Integer, Top as Integer.

MovingEvent.xojo_binary_project

I do have an issue when the window bumps against the menu bar and the mouse cursor slides into it. Then the reported Top is off.

It is possible to fix that with AvailableTop, but it would be an issue with multi screen setups. Fixing this would require checking on which screen the window is on… For the time being, and since my system does not have several screens, I could not test, so I’ll stop here.

Just added a check for the current screen based on the position of left and top within the current screen. Now the event is not triggered while the cursor slides over the menu bar while moving the window. Same link.

Howdy,

thanks all for the reply… i resolved my problem with just a simple thing:

declare sub addChild lib "Cocoa" selector "addChildWindow:ordered:" (id As integer, child As integer, ordering As integer) addChild(self.Handle, myWindow.Handle, 1)

[quote=201648:@Christian Bader]Howdy,

thanks all for the reply… i resolved my problem with just a simple thing:

declare sub addChild lib "Cocoa" selector "addChildWindow:ordered:" (id As integer, child As integer, ordering As integer) addChild(self.Handle, myWindow.Handle, 1)[/quote]

Sorry, but I don’t get it.

So this opens a new window which position is fixed relative to the parent window.

How is it supposed to get you the coordinates of the window while moving it ?

Unless your thread should have read ‘How to move two windows together’ ?

Youre right, maybe the Thread-Title wasnt the best at all. For me it was basic to move the second window within the first window if i will know the coordinates during the move :slight_smile:

i will mark your answer is my answer for fairness and correctness for the threadtitle :slight_smile: Anyway, thanks for help.