Window resize events

Mac OSX specific forum
WilliamL
Addict
Addict
Posts: 1215
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Window resize events

Post by WilliamL »

...it seems that I brought this up once before but I can't find the post.

When I resize a window I get a lot of #PB_Event_SizeWindow events. This is not usually a problem but I had a case where the data being re-loaded to the gadgets was large and having many #PB_Event_SizeWindow events was slowing things down with the repeated re-loads. Is there a way to get just one #PB_Event_SizeWindow event when the window is resized?

Code: Select all

#wndid=1 : #gadget1=1
Procedure UpdateGadgetInfo()
    ;ClearGadgetItems(#gadget1) ; taken out to show the repeated loading
    AddGadgetItem(#gadget1,-1,"Added line")
EndProcedure

If OpenWindow(#wndid, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
    ListViewGadget(#gadget1,10,10,175,240)
    UpdateGadgetInfo()
EndIf

Repeat
    Event = WaitWindowEvent()
    Select event
    Case #PB_Event_CloseWindow
        End
    Case #PB_Event_SizeWindow
        Debug "Window resized"
        ResizeGadget(#gadget1,#PB_Ignore,#PB_Ignore,WindowWidth(#wndid)-20,WindowHeight(#wndid)-20)
        UpdateGadgetInfo()
    EndSelect
ForEver
MacBook Pro-M1 (2021), Sonoma 14.3.1 (CLT 15.3), PB 6.10b7 M1
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Window resize events

Post by mk-soft »

At macOS and the events of PB are very strange.

After hours of searching finally found.

NSWindowDidEndLiveResizeNotification

Base of Wilbert - Link: viewtopic.php?p=393576#p393576

Code: Select all

;-TOP

; *** import the required functions ***

ImportC ""
  sel_registerName(str.p-ascii)
  class_addMethod(class, selector, imp, types.p-ascii)
EndImport

; *** required variables ***

Global notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")
Global appDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
Global delegateClass = CocoaMessage(0, appDelegate, "class")

Define selector

; ---

#wndid=1 : #gadget1=1

Procedure UpdateGadgetInfo()
  Static cnt
  cnt + 1
  AddGadgetItem(#gadget1,-1,"Added line " + cnt)
EndProcedure

; *** Window0 resize callback ***

ProcedureC Window0_Resize(obj, sel, notification)
  ResizeGadget(#gadget1, 10, 10, WindowWidth(#wndid) - 20, WindowHeight(#wndid) - 20)
EndProcedure

ProcedureC Window0_ResizeDone(obj, sel, notification)
  UpdateGadgetInfo()
EndProcedure

; ----

If OpenWindow(#wndid, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  ListViewGadget(#gadget1,10,10,175,240)
  UpdateGadgetInfo()
  
  selector = sel_registerName("Window0_Resize:")
  class_addMethod(delegateClass, selector, @Window0_Resize(), "v@:@")
  CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selector, "name:$", @"NSWindowDidResizeNotification", "object:", WindowID(#wndid))
  
  selector = sel_registerName("Window0_ResizeDone:")
  class_addMethod(delegateClass, selector, @Window0_ResizeDone(), "v@:@")
  CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selector, "name:$", @"NSWindowDidEndLiveResizeNotification", "object:", WindowID(#wndid))
  
EndIf

Repeat
  Event = WaitWindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_SizeWindow
      ;
  EndSelect
ForEver

CocoaMessage(0, notificationCenter, "removeObserver:", appDelegate, "name:$", @"NSWindowDidResizeNotification", "object:", #nil)
CocoaMessage(0, notificationCenter, "removeObserver:", appDelegate, "name:$", @"NSWindowDidEndLiveResizeNotification", "object:", #nil)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
WilliamL
Addict
Addict
Posts: 1215
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Window resize events

Post by WilliamL »

mk-soft,

I saw wilberts example also and I've been studying both of them. I see what you have done and it works fine. I wonder if it works this way on Windows?

I tried using a flag to set the first time thru the event but I couldn't figure out how to know when the drag was done. Your second method (?) was the key (Window0_ResizeDone() ).

I don't know how you (both) figure this stuff out :!:

Thanks again.
MacBook Pro-M1 (2021), Sonoma 14.3.1 (CLT 15.3), PB 6.10b7 M1
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Window resize events

Post by Shardik »

I have found out something really weird: WilliamL's first example is running like a charm when setting #wndid=0 instead of #wndid=1 or any other number or when using #PB_Any...:oops:

I have observed this on MacOS 10.13.6 'High Sierra' and MacOS 10.14.6 'Mojave' with PB 5.46 x86 and x64 and PB 5.72 x86 and x64. #wndid=0 doesn't defer from other IDs in PB 5.31 x86 and x64, i.e. in PB 5.31 #PB_Event_SizeWindow produces several events also with #wndid=0.
Last edited by Shardik on Sat Jul 25, 2020 7:18 pm, edited 1 time in total.
Wolfram
Enthusiast
Enthusiast
Posts: 567
Joined: Thu May 30, 2013 4:39 pm

Re: Window resize events

Post by Wolfram »

May be this helps you.
But depends on how slow you update procedure is you need a trigger if you left the mouse button.

Code: Select all

#wndid=1 : #gadget1=1
Procedure UpdateGadgetInfo()
    ;ClearGadgetItems(#gadget1) ; taken out to show the repeated loading
    AddGadgetItem(#gadget1,-1,"Added line")
EndProcedure

Procedure rsCallback()
          Debug "Window resized"
        ResizeGadget(#gadget1,#PB_Ignore,#PB_Ignore,WindowWidth(#wndid)-20,WindowHeight(#wndid)-20)
        UpdateGadgetInfo()
EndProcedure


If OpenWindow(#wndid, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
    ListViewGadget(#gadget1,10,10,175,240)
    UpdateGadgetInfo()
    
    BindEvent(#PB_Event_SizeWindow, @rsCallback(), #wndid)
    
EndIf



Repeat
  Event = WaitWindowEvent()
    Select event
    Case #PB_Event_CloseWindow
        End
;     Case #PB_Event_SizeWindow
;         Debug "Window resized"
;         ResizeGadget(#gadget1,#PB_Ignore,#PB_Ignore,WindowWidth(#wndid)-20,WindowHeight(#wndid)-20)
;         UpdateGadgetInfo()
    EndSelect
  ForEver
  
macOS Catalina 10.15.7
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Window resize events

Post by mk-soft »

May be this helps you.
But depends on how slow you update procedure is you need a trigger if you left the mouse button.
I've tested that too.
Unfortunately I did not save the code with currentEvent.

But every time after a Resize Event there is also NSLeftMouseUp.

Somehow there must be a bug in the event management of PB.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Window resize events

Post by Shardik »

@mk-soft,

your example is too complicated. You don't need two callbacks. One callback for NSWindowDidEndLiveResizeNotification would be sufficient.
mk-soft wrote:After hours of searching finally found.
I had posted this cross-platform solution already in 2014 in the German forum... :wink:

I have taken my old cross-platform example from 2014, stripped off the Linux and Windows parts and adapted it to WilliamL's example:

Code: Select all

EnableExplicit

#WinID = 0

#PB_Event_WindowResizeComplete = #PB_Event_FirstCustomValue

ProcedureC WindowCallback(Object.I, Selector.I, Notification.I)
  ResizeGadget(0, 10, 10, WindowWidth(#WinID) - 20,
    WindowHeight(#WinID) - 20)
  PostEvent(#PB_Event_WindowResizeComplete, #WinID, 0)
EndProcedure

Procedure UpdateGadgetInfo()
  Static LineCount.I
  LineCount + 1
  AddGadgetItem(0, -1, "Added line " + LineCount)
EndProcedure

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define Selector.I = sel_registerName_("WindowResizeDidEnd:")

If OpenWindow(#WinID, 100, 200, 195, 260, "Resizing test",
  #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  ListViewGadget(0, 10, 10, 175, 240)

  class_addMethod_(DelegateClass, Selector, @WindowCallback(), "v@:@")
  CocoaMessage(0, NotificationCenter,
    "addObserver:", AppDelegate,
    "selector:", Selector,
    "name:$", @"NSWindowDidEndLiveResizeNotification",
    "object:", WindowID(#WinID))

  UpdateGadgetInfo()
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_WindowResizeComplete
        UpdateGadgetInfo()
    EndSelect
  ForEver
EndIf

CocoaMessage(0, NotificationCenter, "removeObserver:", AppDelegate,
  "name:$", @"NSWindowDidEndLiveResizeNotification",
  "object:", WindowID(#WinID))
I have just posted this bug report in the forum "Bugs - Mac OSX"
Last edited by Shardik on Sun Jul 26, 2020 6:51 pm, edited 2 times in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Window resize events

Post by mk-soft »

Damn it.

I didn't look in the German forums.

But it's a bug in the PB ?!
If the Window ID is zero, there is only one event like in Windows.
With Linux every event arrives in the MainScope ?!

Code: Select all

;-TOP

Enumeration Windows 0 ; Set here to 1 
  #Main
EndEnumeration

Enumeration Gadgets 1
  #Gadget
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

Procedure DoEventSizeWindow()
  Static cnt
  cnt + 1
  Debug "BindEvent SizeWindow Count " + cnt
  ResizeGadget(#Gadget, 5, 5, WindowWidth(#Main) - 10, WindowHeight(#Main) - 10)
EndProcedure

BindEvent(#PB_Event_SizeWindow, @DoEventSizeWindow(), #Main)

Procedure Main()
  Protected cnt
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 600, 400, "Window" , #MainStyle)
    ListViewGadget(#Gadget, 5, 5, 590, 390)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_SizeWindow
          If EventWindow() = #Main
            cnt + 1
            Debug "MainScope SizeWindow Count " + cnt
            AddGadgetItem(#Gadget,-1,"MainScope Added line " + cnt)
          EndIf
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Window resize events

Post by Shardik »

@mk-soft,

I have tested your last example on all 3 operating systems running on real hardware:
  • Linux Mint 19.3 'Tricia' x64 with Cinnamon and PB 5.72 x64:
    Each window resize event generates multiple messages.
    For each BindEvent message 1 MainScope message is displayed.
    BindEvent count and MainScope count are synchronized.
  • MacOS 10.14.6 'Mojave' and PB 5.72 x64:
    • #Window=0
      Each window resize event generates 1 message.
      Multiple BindEvent messages are displayed for 1 MainScope message.
    • #Window<>0
      Each window resize event generates multiple messages.
      Multiple BindEvent and multiple MainScope messages are displayed.
  • Windows 10 x64 v1909 with PB 5.72 x86:
    Each window resize event generates 1 message.
    Multiple BindEvent messages are displayed for 1 MainScope message.
By the way, you should add #PB_Window_SizeGadget to your constant #MainStyle because otherwise the window resizing won't work on Windows!
mk-soft wrote:But it's a bug in the PB ?!
It's clearly a bug in PB for MacOS and it's a total mess for cross-platform programming when trying to catch window resize events!
WilliamL
Addict
Addict
Posts: 1215
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Window resize events

Post by WilliamL »

Maybe this thread should be moved to 'Bugs - Mac OSX'...
MacBook Pro-M1 (2021), Sonoma 14.3.1 (CLT 15.3), PB 6.10b7 M1
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Window resize events

Post by collectordave »

I maybe looking at this a little simply.

On my mac I just throw the events I do not want away.

I have added the sizewindowhandler() from the help

Code: Select all

#wndid=23 : #gadget1=1
Procedure UpdateGadgetInfo()
    ClearGadgetItems(#gadget1) ; taken out to show the repeated loading
    AddGadgetItem(#gadget1,-1,"Added line")
EndProcedure

 Procedure SizeWindowHandler()
   
    Debug "Size event on window #" + EventWindow()
    ResizeGadget(#gadget1,#PB_Ignore,#PB_Ignore,WindowWidth(#wndid)-20,WindowHeight(#wndid)-20)
    
  EndProcedure



If OpenWindow(#wndid, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
    ListViewGadget(#gadget1,10,10,175,240)
    UpdateGadgetInfo()
EndIf



  BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())

Repeat
    Event = WaitWindowEvent()
    Select event
    Case #PB_Event_CloseWindow
        End
      Case #PB_Event_SizeWindow
        Debug "Main Loop Resize"
        UpdateGadgetInfo()
        While WindowEvent():Wend
    EndSelect
ForEver
I get multiple calls to the size handler and just one to the main loop resize bit?

PB 5.72 on mac book pro high sierra

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Post Reply