Blocking/Locking a background window
Blocking/Locking a background window
How I block a window with another popup window on Mac OS? If I disable the background window (DisableWindow) and I click on this disabled background window, the background window gets active and the popup looses the focus. It is even possible to activate gadgets in this disabled window (SetActiveGadget). So I can scroll through a list (with trackpad), switch the active gadgets by TAB and press buttons with SPACE inside a disabled window!! It seems only some mouse interaction are blocked. This is not the behaviour I see on Windows. With Windows the disabled window is untouchable. It is impossible to activate a disabled window and it is impossible to activate and trigger gadgets inside a disabled window. Is DisableWindow() the wrong way to lock a window?
Re: Blocking/Locking a background window
Could you use a modal window?
Code: Select all
Macro RunModal(_window_)
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"runModalForWindow:",WindowID(_window_))
EndMacro
Macro AbortModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"abortModal")
EndMacro
Macro StopModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"stopModal")
EndMacro
Procedure OnButton_0()
HideWindow(1,#False) ; without this line, hidden windows are always displayed automatically, and always centered
RunModal( 1 )
EndProcedure
Procedure OnButton_1()
AbortModal() ; StopModal()
SetActiveWindow(0)
HideWindow(1,#True)
EndProcedure
If OpenWindow(0,0,0,800,600, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,150,25,"Open Modal Window")
BindGadgetEvent(0,@OnButton_0())
ListViewGadget(2,10,45,300,300)
For i = 1 To 200 : AddGadgetItem(2,-1,"Item "+i) : Next
OpenWindow(1,200,300,300,200,"Tool",#PB_Window_Tool|#PB_Window_Invisible,WindowID(0))
ButtonGadget(1,10,10,150,25,"Close Modal Window")
BindGadgetEvent(1,@OnButton_1())
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Re: Blocking/Locking a background window
You could probably also use sheets; that's what I do.
Sheets can be any size, even bigger as the main window.
On how to implement sheets: Use a window as a sheet for another window
Sheets can be any size, even bigger as the main window.
On how to implement sheets: Use a window as a sheet for another window
I am to provide the public with beneficial shocks.
Alfred Hitshock
Re: Blocking/Locking a background window
Hi Danilo,
nice example. Is it possible to add a Keyboard shortcut to the Modal Window?
For example to have copy and past.
Thanks
Wolfram
nice example. Is it possible to add a Keyboard shortcut to the Modal Window?
For example to have copy and past.
Thanks
Wolfram
macOS Catalina 10.15.7
Re: Blocking/Locking a background window
Another RunModal() method is required for this, so we can use PB's WaitWindowEvent() to run all of the internal event processing:Wolfram wrote:Is it possible to add a Keyboard shortcut to the Modal Window?
Code: Select all
Enumeration Commands 1000
#Command_Copy
#Command_Paste
EndEnumeration
;Macro RunModal(_window_)
; CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"runModalForWindow:",WindowID(_window_))
;EndMacro
Procedure RunModal(_window_)
#NSModalResponseContinue = -1002
; begin a modal session
Protected session = CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"beginModalSessionForWindow:",WindowID(_window_))
; loop while modal session is still running
While CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"runModalSession:",session) = #NSModalResponseContinue
WaitWindowEvent() ; PB's event processing
Wend
; end modal session
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"endModalSession:",session)
EndProcedure
Macro AbortModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"abortModal")
EndMacro
Macro StopModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"stopModal")
EndMacro
Procedure OnCopy()
Debug "Copy!"
EndProcedure
Procedure OnPaste()
Debug "Paste!"
EndProcedure
Procedure OnButton_0()
;HideWindow(1,#False) ; without this line, hidden windows are always displayed automatically, and always centered
RunModal( 1 )
EndProcedure
Procedure OnButton_1()
AbortModal() ; StopModal()
SetActiveWindow(0)
HideWindow(1,#True)
EndProcedure
If OpenWindow(0,0,0,800,600, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,150,25,"Open Modal Window")
BindGadgetEvent(0,@OnButton_0())
ListViewGadget(2,10,45,300,300)
For i = 1 To 200 : AddGadgetItem(2,-1,"Item "+i) : Next
OpenWindow(1,200,300,300,200,"Tool",#PB_Window_Tool|#PB_Window_Invisible,WindowID(0))
ButtonGadget(1,10,10,150,25,"Close Modal Window")
BindGadgetEvent(1,@OnButton_1())
AddKeyboardShortcut(1,#PB_Key_1, #Command_Copy)
AddKeyboardShortcut(1,#PB_Key_2, #Command_Paste)
BindEvent(#PB_Event_Menu, @OnCopy() , 1, #Command_Copy)
BindEvent(#PB_Event_Menu, @OnPaste(), 1, #Command_Paste)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Re: Blocking/Locking a background window
Why are Windows which are open by the Modal Window (like this MessageRequester) not in center?
Code: Select all
Enumeration Commands 1000
#Command_Copy
#Command_Paste
EndEnumeration
Procedure RunModal(_window_)
#NSModalResponseContinue = -1002
; begin a modal session
Protected session = CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"beginModalSessionForWindow:",WindowID(_window_))
; loop while modal session is still running
While CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"runModalSession:",session) = #NSModalResponseContinue
WaitWindowEvent() ; PB's event processing
Wend
; end modal session
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"endModalSession:",session)
EndProcedure
Macro AbortModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"abortModal")
EndMacro
Macro StopModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"stopModal")
EndMacro
Procedure OnCopy()
Debug "Copy!"
MessageRequester("ERROR!", "I'm not centered")
EndProcedure
Procedure OnPaste()
Debug "Paste!"
EndProcedure
Procedure OnButton_0()
;HideWindow(1,#False) ; without this line, hidden windows are always displayed automatically, and always centered
RunModal( 1 )
EndProcedure
Procedure OnButton_1()
AbortModal() ; StopModal()
SetActiveWindow(0)
HideWindow(1,#True)
EndProcedure
If OpenWindow(0,0,0,800,600, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,150,25,"Open Modal Window")
BindGadgetEvent(0,@OnButton_0())
ListViewGadget(2,10,45,300,300)
For i = 1 To 200 : AddGadgetItem(2,-1,"Item "+i) : Next
OpenWindow(1,200,300,300,200,"Tool",#PB_Window_Tool|#PB_Window_Invisible,WindowID(0))
ButtonGadget(1,10,10,150,25,"Close Modal Window")
BindGadgetEvent(1,@OnButton_1())
AddKeyboardShortcut(1,#PB_Key_1, #Command_Copy)
AddKeyboardShortcut(1,#PB_Key_2, #Command_Paste)
BindEvent(#PB_Event_Menu, @OnCopy() , 1, #Command_Copy)
BindEvent(#PB_Event_Menu, @OnPaste(), 1, #Command_Paste)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
macOS Catalina 10.15.7
Re: Blocking/Locking a background window
Looks like default behavior of NSAlert dialogs. If the alert (a modal dialog) is opened when another modal window is active, it isWolfram wrote:Why are Windows which are open by the Modal Window (like this MessageRequester) not in center?
positioned relative to the modal window (which makes sense somehow).
If you don't want that behavior, you can change it by centering and displaying the alert before running it in modal mode:
Code: Select all
Enumeration Commands 1000
#Command_Copy
#Command_Paste
EndEnumeration
Procedure RunModal(_window_)
#NSModalResponseContinue = -1002
; begin a modal session
Protected session = CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"beginModalSessionForWindow:",WindowID(_window_))
; loop while modal session is still running
While CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"runModalSession:",session) = #NSModalResponseContinue
WaitWindowEvent() ; PB's event processing
Wend
; end modal session
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"endModalSession:",session)
EndProcedure
Macro AbortModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"abortModal")
EndMacro
Macro StopModal()
CocoaMessage(0,CocoaMessage(0,0,"NSApplication sharedApplication"),"stopModal")
EndMacro
Procedure OnCopy()
Debug "Copy!"
;MessageRequester("ERROR!", "I'm not centered")
alert = CocoaMessage(0,CocoaMessage(0,0,"NSAlert alloc"),"init")
CocoaMessage(0,alert,"setMessageText:$",@"Message text.")
CocoaMessage(0,alert,"setInformativeText:$",@"Informative text.")
CocoaMessage(0,alert,"addButtonWithTitle:$",@"OK")
;CocoaMessage(0,alert,"addButtonWithTitle:$",@"Cancel")
;CocoaMessage(0,alert,"addButtonWithTitle:$",@"Abort")
CocoaMessage(0,alert,"layout")
; START FIX
alertWindow = CocoaMessage(0,alert,"window")
If alertWindow
CocoaMessage(0,alertWindow,"center") ; center the window
CocoaMessage(0,alertWindow,"makeKeyAndOrderFront:",0) ; display the window (without this line, it is displayed relative to the modal window)
EndIf
; END FIX
CocoaMessage(0,alert,"runModal")
CocoaMessage(0,alert,"release")
EndProcedure
Procedure OnPaste()
Debug "Paste!"
EndProcedure
Procedure OnButton_0()
;HideWindow(1,#False) ; without this line, hidden windows are always displayed automatically, and always centered
RunModal( 1 )
EndProcedure
Procedure OnButton_1()
AbortModal() ; StopModal()
SetActiveWindow(0)
HideWindow(1,#True)
EndProcedure
If OpenWindow(0,0,0,800,600, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0,10,10,150,25,"Open Modal Window")
BindGadgetEvent(0,@OnButton_0())
ListViewGadget(2,10,45,300,300)
For i = 1 To 200 : AddGadgetItem(2,-1,"Item "+i) : Next
AddKeyboardShortcut(0,#PB_Key_1, #Command_Copy)
AddKeyboardShortcut(0,#PB_Key_2, #Command_Paste)
BindEvent(#PB_Event_Menu, @OnCopy() , 0, #Command_Copy)
BindEvent(#PB_Event_Menu, @OnPaste(), 0, #Command_Paste)
OpenWindow(1,200,300,900,600,"Tool",#PB_Window_Tool|#PB_Window_Invisible,WindowID(0))
ButtonGadget(1,10,10,150,25,"Close Modal Window")
BindGadgetEvent(1,@OnButton_1())
AddKeyboardShortcut(1,#PB_Key_1, #Command_Copy)
AddKeyboardShortcut(1,#PB_Key_2, #Command_Paste)
BindEvent(#PB_Event_Menu, @OnCopy() , 1, #Command_Copy)
BindEvent(#PB_Event_Menu, @OnPaste(), 1, #Command_Paste)
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Re: Blocking/Locking a background window
DisableWindow() on Mac OS X is very, very slow! If you have a ListIconGadget with > 10000 Items, then DisableWindow() needs more than a second to disable the window. With Windows DisableWindow() works immediately....
Re: Blocking/Locking a background window
Examples above won't compile in recent PB... Did it ever work?
WindowEvent() and WaitWindowEvent() can not be called from a 'binded' event callback.
or any WaitWindowEvent in callback...
Can be solved in the above by not using BindEvent on the first button, but not always possible.
WindowEvent() and WaitWindowEvent() can not be called from a 'binded' event callback.
or any WaitWindowEvent in callback...
Can be solved in the above by not using BindEvent on the first button, but not always possible.