Recent

Author Topic: macOS how to get window position?  (Read 4208 times)

Key-Real

  • Full Member
  • ***
  • Posts: 185
macOS how to get window position?
« on: March 14, 2022, 12:19:22 pm »
How to get a window position?

NSWindow.frame.origin returns me correct X but strange Y
« Last Edit: March 14, 2022, 12:40:27 pm by Key-Real »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS how to get window position?
« Reply #1 on: March 14, 2022, 02:11:32 pm »
This works for me:

Code: Pascal  [Select][+][-]
  1. NSLog(NSSTR(FloatToStr(window.frame.origin.x)));
  2. NSLog(NSSTR(FloatToStr(window.frame.origin.y)));

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: macOS how to get window position?
« Reply #2 on: March 14, 2022, 02:23:57 pm »
not at my side

here my evidence


www.sistavip.com/pub/screen2.zip

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS how to get window position?
« Reply #3 on: March 14, 2022, 10:53:43 pm »
Code: Pascal  [Select][+][-]
  1. program badger;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch objectivec1}
  5.  
  6. uses
  7. CocoaAll, Sysutils;
  8.  
  9. type
  10.   { TMyDelegate }
  11.   TMyDelegate = objcclass(NSObject)
  12.   public
  13.     procedure BadgeButtonClick(sender :  id); message 'BadgeButtonClick:';
  14.     procedure UnBadgeButtonClick(sender :  id); message 'UnBadgeButtonClick:';
  15.   end;
  16.  
  17. var
  18.    appName    : NSString;
  19.    window     : NSWindow;
  20.    myBadgeButton   : NSButton;
  21.    myUnBadgeButton : NSButton;
  22.    myDelegate : TMyDelegate;
  23.  
  24. procedure TMyDelegate.BadgeButtonClick(sender :  id);
  25. begin
  26.    NSApp.dockTile.setBadgeLabel(NSStr('12'));
  27.    NSLog(NSSTR(FloatToStr(window.frame.origin.x)));
  28.    NSLog(NSSTR(FloatToStr(window.frame.origin.y)));
  29. end;
  30.  
  31. procedure TMyDelegate.UnBadgeButtonClick(sender :  id);
  32. begin
  33.    NSApp.dockTile.setBadgeLabel(Nil);
  34. end;
  35.  
  36. begin
  37.    // app and window creation
  38.    NSApp := NSApplication.sharedApplication;
  39.    NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);
  40.    appName := NSStr('Badger');
  41.    window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),
  42.                 NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,
  43.                 NSBackingStoreBuffered, False);
  44.    myDelegate := TMyDelegate.alloc.init;
  45.  
  46.    // badge button
  47.    myBadgeButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 100, 100, 50));
  48.    window.contentView.addSubview(myBadgeButton);
  49.    myBadgeButton.setTitle(NSSTR('Badge'));
  50.    myBadgeButton.setButtonType(NSMomentaryLightButton);
  51.    myBadgeButton.setBezelStyle(NSRoundedBezelStyle);
  52.  
  53.    // unbadge button
  54.    myUnBadgeButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 60, 100, 50));
  55.    window.contentView.addSubview(myUnBadgeButton);
  56.    myUnBadgeButton.setTitle(NSSTR('UnBadge'));
  57.    myUnBadgeButton.setButtonType(NSMomentaryLightButton);
  58.    myUnBadgeButton.setBezelStyle(NSRoundedBezelStyle);
  59.  
  60.    // badge button event handler
  61.    myBadgeButton.setTarget(myDelegate);
  62.    myBadgeButton.setAction(ObjCSelector(myDelegate.BadgeButtonClick));
  63.  
  64.    // unbadge button event handler
  65.    myUnBadgeButton.setTarget(myDelegate);
  66.    myUnBadgeButton.setAction(ObjCSelector(myDelegate.UnBadgeButtonClick));
  67.  
  68.    // Window showing and app running
  69.    window.center;
  70.    window.setTitle(appName);
  71.    window.makeKeyAndOrderFront(Nil);
  72.    NSApp.activateIgnoringOtherApps(True);
  73.    NSApp.run;
  74. end.

Start the executable from a Terminal. Move the window around the screen and the window's x, y coordinates are correctly logged to the Terminal when pressing the badge button.

Hint: Next time post your compilable code and then someone can try to replicate what you describe. It also helps to mention which version of FPC you're using.

I'm curious: why you are avoiding the LCL which would make life easier and also make your code generally cross-platform?

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: macOS how to get window position?
« Reply #4 on: March 17, 2022, 06:16:51 pm »
I lunched your prog but it tells me
x=0
y=647
but I have the window at 0,0

See attached picture

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS how to get window position?
« Reply #5 on: March 17, 2022, 11:06:22 pm »

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: macOS how to get window position?
« Reply #6 on: April 03, 2022, 03:04:14 pm »
Code: Pascal  [Select][+][-]
  1. procedure getGFXwindowPos(var x,y:longint);
  2. begin
  3.   x:=round(window.frame.origin.x);
  4.   y:=round(NSScreen.mainScreen.Frame.size.height-window.frame.origin.y);
  5. end;
  6.  

y is not correct :(

is NSScreen.mainScreen.Frame.size.height not the height of the whole screen?

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS how to get window position?
« Reply #7 on: April 30, 2022, 03:59:47 am »
This works for me (small adjustment to my program above):

Code: Pascal  [Select][+][-]
  1. var
  2.    appName    : NSString;
  3.    window     : NSWindow;
  4.    myBadgeButton   : NSButton;
  5.    myUnBadgeButton : NSButton;
  6.    myDelegate : TMyDelegate;
  7.    myScreen : NSRect;   // addition
  8.  
  9. procedure TMyDelegate.BadgeButtonClick(sender :  id);
  10. begin
  11.    NSApp.dockTile.setBadgeLabel(NSStr('12'));
  12.    myScreen := NSscreen.MainScreen.Frame;          // addition
  13.    NSLog(NSSTR(FloatToStr(myScreen.size.width)));  // addition
  14.    NSLog(NSSTR(FloatToStr(myScreen.size.height))); // addition
  15. end;

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: macOS how to get window position?
« Reply #8 on: April 30, 2022, 06:53:29 am »
Er, forgive my ignorance of things Apple, but does this discussion mean that the usual 'top' and 'left' properties of a form do not give (or set) the top left of the form wrt the screen ?

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: macOS how to get window position?
« Reply #9 on: April 30, 2022, 09:39:40 am »
The OP is not using the LCL, but pure Cocoa as you can see from my example program above.

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: macOS how to get window position?
« Reply #10 on: April 30, 2022, 12:51:06 pm »
Ah, I should have read the whole thread !
Thanks.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Key-Real

  • Full Member
  • ***
  • Posts: 185
Re: macOS how to get window position?
« Reply #11 on: September 27, 2022, 08:21:48 pm »
This
Code: Pascal  [Select][+][-]
  1. var
  2.    appName    : NSString;
  3.    window     : NSWindow;
  4.    myBadgeButton   : NSButton;
  5.    myUnBadgeButton : NSButton;
  6.    myDelegate : TMyDelegate;
  7.    myScreen : NSRect;   // addition
  8.  
  9. procedure TMyDelegate.BadgeButtonClick(sender :  id);
  10. begin
  11.    NSApp.dockTile.setBadgeLabel(NSStr('12'));
  12.    myScreen := NSscreen.MainScreen.Frame;          // addition
  13.    NSLog(NSSTR(FloatToStr(myScreen.size.width)));  // addition
  14.    NSLog(NSSTR(FloatToStr(myScreen.size.height))); // addition
  15. end;
  16.  

gives me the Desktop Resolution. At my side it returns X=1440 Y=900



This:
Code: Pascal  [Select][+][-]
  1. procedure getGFXwindowPos(var x, y:longint);
  2. begin
  3.   x:=round(window.frame.origin.x);
  4.   y:=round(window.frame.origin.y);
  5. end;
  6.  

returns me correct X but not adequate Y. Sould be 100,100 because I set it with:
Code: Pascal  [Select][+][-]
  1. procedure setGFXwindowPos(x, y:longint);
  2. var
  3.   point:NSPoint;
  4. begin
  5.     point.x:=x;
  6.     point.y:=NSscreen.mainScreen.visibleFrame.size.height - y;
  7.     window.setFrameTopLeftPoint(point);
  8.     Cocoa_PollEvents;
  9. end;
  10.  

If I set the window to 0,0 the getGFXwindowPos return X=0 Y=339





what is wrong?

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user

 

TinyPortal © 2005-2018