PB_Gadget_SetOpenFinderFiles() is broken
PB_Gadget_SetOpenFinderFiles() is broken
If I try my programs on macOS 11 (Big Sur) the PB_Gadget_SetOpenFinderFiles() function works not as on older OS versions.
Normally I can start my program by double click on a file or drop a file on the program and the programs loads the file after it is started.
On macOS 11 and later the program starts, but dose't load the file.
If the program is already started and I double click on a file it is loaded.
Normally I can start my program by double click on a file or drop a file on the program and the programs loads the file after it is started.
On macOS 11 and later the program starts, but dose't load the file.
If the program is already started and I double click on a file it is loaded.
macOS Catalina 10.15.7
Re: PB_Gadget_SetOpenFinderFiles() is broken
I had a look at this in the Purebasic IDE, where it also works.
There are some rules to be observed and entries still have to be made in the info.plist.
Example:
info.plist
There are some rules to be observed and entries still have to be made in the info.plist.
Example:
Code: Select all
;-TOP
#ProgramTitle = "Main Window - Drop Files"
#ProgramVersion = "v1.01.2"
ImportC ""
PB_Gadget_SetOpenFinderFiles(*Callback)
EndImport
Enumeration Windows
#Main
EndEnumeration
Enumeration MenuBar
#MainMenu
EndEnumeration
Enumeration MenuItems
#MainMenuAbout
#MainMenuExit
EndEnumeration
Enumeration Gadgets
#MainList
EndEnumeration
Enumeration StatusBar
#MainStatusBar
EndEnumeration
; ----
Enumeration CustomEvent #PB_Event_FirstCustomValue
#MyEvent_OpenFiles
EndEnumeration
Global NewList OpenFilesCommandLine.s()
ProcedureC OpenDocument(*FilesUTF8)
Protected Files$, File$, k
; Files are separated by a tab
;
Files$ = PeekS(*FilesUTF8, -1, #PB_UTF8)
Repeat
File$ = StringField(Files$, k+1, #TAB$) ; index is 1 based
If File$ <> ""
If FileSize(File$) >= 0 ; no directories here...
Debug "passed file: "+File$
; Use the queue, as loading a document from this callback crash the IDE (probably because we do GUI operations in startup callback
; It will be loaded in the main loop
LastElement(OpenFilesCommandLine())
AddElement(OpenFilesCommandLine()) ; will cause this file to be loaded when the IDE is ready for it
OpenFilesCommandLine() = File$
EndIf
k+1
EndIf
Until File$ = ""
PostEvent(#MyEvent_OpenFiles)
EndProcedure
; ----
Procedure GetCommandLineFiles()
Protected cnt, index, file.s
cnt = CountProgramParameters()
For index = 0 To cnt - 1
file = ProgramParameter(index)
If file <> ""
AddElement(OpenFilesCommandLine())
OpenFilesCommandLine() = file
EndIf
Next
EndProcedure
; ----
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
; Resize gadgets
ResizeGadget(#MainList, 0, 0, dx, dy)
EndProcedure
Procedure Main()
Protected dx, dy
; Set before first OpenWindow
PB_Gadget_SetOpenFinderFiles(@OpenDocument())
#MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
; Menu
CreateMenu(#MainMenu, WindowID(#Main))
MenuTitle("&File")
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
MenuItem(#PB_Menu_About, "")
CompilerElse
MenuItem(#MainMenuAbout, "About")
CompilerEndIf
; Menu File Items
CompilerIf Not #PB_Compiler_OS = #PB_OS_MacOS
MenuBar()
MenuItem(#MainMenuExit, "E&xit")
CompilerEndIf
; StatusBar
CreateStatusBar(#MainStatusBar, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
ListViewGadget(#MainList, 0, 0, dx, dy)
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
;GetCommandLineFiles()
ForEach OpenFilesCommandLine()
AddGadgetItem(#MainList, -1, OpenFilesCommandLine())
Next
ClearList(OpenFilesCommandLine())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
CompilerEndIf
Case #MainMenuExit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
Case #MainMenuAbout
MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #MainList
Select EventType()
Case #PB_EventType_Change
;
EndSelect
EndSelect
Case #MyEvent_OpenFiles
ForEach OpenFilesCommandLine()
AddGadgetItem(#MainList, -1, OpenFilesCommandLine())
Next
ClearList(OpenFilesCommandLine())
EndSelect
ForEver
EndIf
EndProcedure : Main()
info.plist
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pb</string>
<string>pbi</string>
<string>pbp</string>
</array>
<key>CFBundleTypeName</key>
<string>MyDropFiles</string>
<key>CFBundleTypeIconFile</key>
<string>FileIcon.icns</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>DropFiles</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>PURE</string>
<key>CFBundleVersion</key>
<string>0.1</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
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
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: PB_Gadget_SetOpenFinderFiles() is broken
mk-soft,
I really appreciate you're looking into this. It is very interesting to see the IDE example.
I've given some of my experience in this thread viewtopic.php?t=79365
The code you posted is essentially the same as Fred's original code. The ProcedureC OpenDocument(*FilesUTF8) callback is not triggered when the file is double clicked in my programs. If the program is running, dragging the file triggers the callback.
I've looked at your examples (both code and plist) and what I am using and I can't find any significant differences. The code worked for years.. now it doesn't so I don''t think it is a case of doing it wrong.
Your code obviously works in the IDE. It's a mystery to me.
I really appreciate you're looking into this. It is very interesting to see the IDE example.
I've given some of my experience in this thread viewtopic.php?t=79365
The code you posted is essentially the same as Fred's original code. The ProcedureC OpenDocument(*FilesUTF8) callback is not triggered when the file is double clicked in my programs. If the program is running, dragging the file triggers the callback.
I've looked at your examples (both code and plist) and what I am using and I can't find any significant differences. The code worked for years.. now it doesn't so I don''t think it is a case of doing it wrong.
Your code obviously works in the IDE. It's a mystery to me.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: PB_Gadget_SetOpenFinderFiles() is broken
This works (based on mk-soft help)
Code: Select all
ImportC ""
PB_Gadget_SetOpenFinderFiles(*Callback)
EndImport
Enumeration CustomEvent #PB_Event_FirstCustomValue
#MyEvent_OpenFiles
EndEnumeration
Global NewList OpenFilesCommandLine.s()
ProcedureC OpenDocument(*FilesUTF8)
Protected Files$, File$, k
; Files are separated by a tab
Files$ = PeekS(*FilesUTF8, -1, #PB_UTF8)
Repeat
File$ = StringField(Files$, k+1, #TAB$) ; index is 1 based
If File$ <> ""
If FileSize(File$) >= 0 ; no directories here...
LastElement(OpenFilesCommandLine())
AddElement(OpenFilesCommandLine())
OpenFilesCommandLine() = File$
EndIf
k+1
EndIf
Until File$ = ""
PostEvent(#MyEvent_OpenFiles)
EndProcedure
; Set before first OpenWindow
PB_Gadget_SetOpenFinderFiles(@OpenDocument())
; Example:
If OpenWindow(0, 0, 0, 820, 620, "OpenFinderFiles", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
EditorGadget(0, 10, 10, 800, 600)
Repeat
Select WaitWindowEvent()
Case #MyEvent_OpenFiles
ForEach OpenFilesCommandLine()
AddGadgetItem(0, -1, OpenFilesCommandLine())
Next
ClearList(OpenFilesCommandLine()) ; Remember to clear the queue
Case #PB_Event_CloseWindow
end
EndSelect
Until EventMenu() = #PB_Menu_Quit
EndIf
Last edited by Piero on Wed Aug 16, 2023 4:13 am, edited 1 time in total.
Re: PB_Gadget_SetOpenFinderFiles() is broken
But it won't work without adjusting the info.plist.
Edit and add this to info.plist inside <dict>
Edit and add this to info.plist inside <dict>
Code: Select all
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pb</string>
<string>pbi</string>
<string>pbp</string>
</array>
<key>CFBundleTypeName</key>
<string>FinderFiles</string>
<key>CFBundleTypeIconFile</key>
<string>FileIcon.icns</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
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
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: PB_Gadget_SetOpenFinderFiles() is broken
Ok, I've spent a few hours on this...
I put Fred's original code before any Procedures but it still didn't work.
It appears that the call is made before my procedures to load the menus and preferences. I tried all ways of getting these procedures done before the OpenFiles call but with marginal success. But, in the end, I gave up.
I modified my program using a PostEvent(). These were some of the lines I added and they are from Piero's and mk-soft examples. (see their examples)
[These are not complete instructions of how to add the info.]
I would guess that the PostEvent method is the way to go and that is what I will use from now on.
I put Fred's original code before any Procedures but it still didn't work.
It appears that the call is made before my procedures to load the menus and preferences. I tried all ways of getting these procedures done before the OpenFiles call but with marginal success. But, in the end, I gave up.
I modified my program using a PostEvent(). These were some of the lines I added and they are from Piero's and mk-soft examples. (see their examples)
Code: Select all
Enumeration CustomEvent #PB_Event_FirstCustomValue
#MyEvent_OpenFiles
EndEnumeration
PostEvent(#MyEvent_OpenFiles)
Case #MyEvent_OpenFiles
LoadFile(filename$)
I would guess that the PostEvent method is the way to go and that is what I will use from now on.
Last edited by WilliamL on Tue Aug 15, 2023 5:32 pm, edited 1 time in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: PB_Gadget_SetOpenFinderFiles() is broken
It seems to me that the problem was solved with this:
Code: Select all
; Use the queue, as loading a document from this callback crash the IDE
; (probably because we do GUI operations in startup callback)
; It will be loaded in the main loop
LastElement(OpenFilesCommandLine())
AddElement(OpenFilesCommandLine()) ; will cause this file to be loaded when the IDE is ready for it
OpenFilesCommandLine() = File$
Last edited by Piero on Wed Aug 16, 2023 4:19 am, edited 1 time in total.
Re: PB_Gadget_SetOpenFinderFiles() is broken
mk-soft & Piero,
We agree that the loading should be done in the event loop.
Thank you. I wouldn't have been able to fix it without your help.
PS Using a NewList and disposing of it was perfect for this use.
We agree that the loading should be done in the event loop.

Thank you. I wouldn't have been able to fix it without your help.
PS Using a NewList and disposing of it was perfect for this use.
Last edited by WilliamL on Wed Aug 16, 2023 5:39 pm, edited 2 times in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: PB_Gadget_SetOpenFinderFiles() is broken
You are very welcome!WilliamL wrote: Mon Aug 14, 2023 10:55 pmThank you. I wouldn't have been able to fix it out without your help.
Thanks mk-soft! I will need openfinderfiles soon...

PS:
Let's all remember that you can change the app that will open your file via Get Info in Finder ("Change all" to set the default app that will open that kind of files)
Re: PB_Gadget_SetOpenFinderFiles() is broken
The code to load files double-clicked works great! What I can't figure out is if I just run the app how do I (for instance) go to a load routine? Since I have to go through the event loop once to see the #MyEvent_OpenFiles event I can't just go to the Load routine when I first run the program.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: PB_Gadget_SetOpenFinderFiles() is broken
Huh? Do you mean load previously-opened-but-never-closed files like on the PB IDE? (mk-soft's IDE code can help you)WilliamL wrote: Tue Sep 05, 2023 11:15 pm The code to load files double-clicked works great! What I can't figure out is if I just run the app how do I (for instance) go to a load routine? Since I have to go through the event loop once to see the #MyEvent_OpenFiles event I can't just go to the Load routine when I first run the program.
Otherwise, mk-soft will probably suggest you to open threads and clean the pool