@All Created a small hack (thanks Petrol for idea) which patch Intuition's functions via SetMethod() to allow transparently run of the Filer binary pointing to the given partition on Workbench's Desktop instead of original Workbench windows. Things like "Open Workbench" in Filer, or "wbrun" from shell / asyncwb work as before and open for you original WB window.
There is how it looks like currently:
Check this out, suggestion, and bug report are welcome of course:
Hitting "ctrl+c", will clean the patches up and exit.
If you like, you can run it from User-Startup as well, just by adding (as example):
RUN >NIL >NIL: work:wb2filer/wb2filer system:utilitites/filer/filer
Edited by kas1e on 2023/11/24 6:45:23 Edited by kas1e on 2023/11/24 6:46:48 Edited by kas1e on 2023/11/25 10:10:24 Edited by kas1e on 2023/11/25 10:10:50 Reason: version update Edited by kas1e on 2023/11/27 8:22:53 Reason: version update Edited by kas1e on 2023/11/30 9:02:46 Reason: version update Edited by kas1e on 2023/12/1 13:14:29 Reason: version update Edited by kas1e on 2023/12/1 13:14:54 Edited by kas1e on 2023/12/7 11:22:42 Reason: version/video update Edited by kas1e on 2023/12/7 11:23:11 Reason: revsion/video/text updated Edited by kas1e on 2023/12/14 3:41:26 Reason: version update Edited by kas1e on 2023/12/17 10:40:01 Reason: version update Edited by kas1e on 2023/12/17 10:41:39 Reason: updating Edited by kas1e on 2023/12/17 10:41:54
I will test it, but it looks as great tool. AmigaOS workbench windows browsing and operations are too obsolete and unpleasant to use. MorphOS Ambient has this solved far better. And automatic filer opening is nice idea.
AmigaOS3: Amiga 1200 AmigaOS4: Micro A1-C, AmigaOne XE, Pegasos II, Sam440ep, Sam440ep-flex, AmigaOne X1000 MorphOS: Efika 5200b, Pegasos I, Pegasos II, Powerbook, Mac Mini, iMac, Powermac Quad
which may be faster than calling it three times. You may want to check return value to make sure command is constructed correctly.
Also in main() you can drop the "notdone" variable as you "break;" out from the loop so it will never be checked and it can just be an endless loop with while (1).
I'd also move "filer_binary = argv[1];" to after argc is checked although it does not matter as it's not used before.
@all Have few more ideas, but not sure if they worth of it or not:
1). create a commoditie. Not sure if there needs for, and if, not sure if plain binary need to keep, or ditch in favor of commoditie ?
2). currently, all workbench drawer calls are patched, i.e., not only when you hit on the "root" ones, but also if you will for example do "wbrun xx0:drawer". The same when you will try to "open in wb folder" from filer. Maybe it worth to hack only ones which on desktop ? Like, parse the path, and if it contains "/", it means more than root volume, so don't hack it, and only hack it when it has only ":" at the end. Is it worth at all ? At least for me, a bit suck when i tried to "open in workbench folder" from filer, and it opens instead another filer :)
@kas1e understood but it means I have to manually run every time. Commodity means could load on system startup but be able to stop if decided once running.
-- few logical fixes: replaced 3 calls of asprintf() by one, ditch unused vars, shift parsing of argv (thanks Balaton) -- now hijack only root (WBICON) volumes, so you still can continue to open pure WB folders from Filer or via "wbrun" tool as before
The thing which i dislike and also want to deal with is this "blink" of the title bar when you dbl-click on icon...
As long as you're hacking anyway, you could always patch DisplayBeep() to ignore calls from the Workbench task. Of course, then you stop Workbench from flashing the screen for any reason.
A more elegant fix would be to have a global flag that is shared by both the OpenWindowTagList() patch and the DisplayBeep() patch. If the flag is clear, as it normally would be, the DisplayBeep() patch allows Workbench to flash the screen. When the OpenWindowTagList() patch opens Filer and passes NULL back to Workbench, it also sets the flag. When the DisplayBeep() patch sees the flag is set it blocks Workbench from flashing the screen that one time, and then clears the flag. That way, only the next Workbench call to DisplayBeep() after a new Filer window is opened is blocked. All other DisplayBeep() calls from Workbench are allowed, as well as calls from any other program.
Multi-tasking might mess with this scheme, but that shouldn't be a problem with Workbench, as it typically only does something in response to user actions, so it's effectively single-threaded. If it gets it wrong on rare occasion, hey, it's only a hack!
It's imho too small/easy hack which anyone who have 68k can make if need it, but just in case: i put source to archive, so all what the one doing this need to do to for 68k version of it, is to replace SetMethod() by SetFuntion() and i do not know if OS3.x have WhichWorkbenchObject() support with all this types/paths, etc, so maybe need to change something for this part too to make it works on os3.x.
@All New version:
-- hijack Intuition->DisplayBeep() as well, to disable wb-bar blinks after Filer's run and original OpenWindowTagList() returning NULL (thanks msteed for idea) -- updated readme to be in sync
In other words, you have no needs to disable prefs:sound alerts now, and can keep it working.
@kas1e How about the ability to have either traditional style wb windows by default but if qualifier is held down then filer opens, or vice versa? Or maybe if capslock is on then use filer etc?
You have in main uint32 sigmask = 0 and then the only usage is IExec->Wait(sigmask|SIGBREAKF_CTRL_C) so it seems to be constant 0 and I think you could just drop it and just do IExec->Wait(SIGBREAKF_CTRL_C) with same effect. You can also drop signals variable as you don't actually use it more than once and could just write:
and move the IDOS->Printf("patching cleaned\n"); from this if to after deinit() That's more consistent with init() and then you have just a single line in your main loop that's really simple and clear. Actually if IExec->Wait(SIGBREAKF_CTRL_C) only ever returns when mask is set you don't even need the & SIGBREAKF_CTRL_C in the if, I don't know what IExec->Wait() could return here.
Only struct Task *Caller is static the others are global. Since this is just a single file it does not matter anyway so you could either drop static from Caller or declare all of them static for consistency. Or just make Caller local to Patched_OpenWindowTagList() as it's not used from anywhere else so no need for it to be global. Maybe that's why it's static? You can also drop the inits to 0 from all of these as globals and static globals are init to 0 but it can be kept for more explicit code.
The value of Caller and ready_string are not checked before usage so if there's an error it could crash on trying to dereference NULL pointer or use a string that's not complete.
Move setting disable_flash_beep just before you call the command, after asprintf and checking ready_string to minimise the possibiliy something else also calls DisplayBeep before your command and clears the flag. This may also happen sometimes anyway I think but that was already said by the original poster of this idea. So just setting it right before calling the command is the best you can do to minimise that.
Finally you can write WBOBJA_FullPathSize,sizeof(fullpath) The sizeof operator also works for constant size arrays then you can't accidentally change it at one place and forget the other so it's usually recommended to have such constants at one place or declare a macro when needed at more than one place.
Looking at it more I've also found possible actual bug. In Patched_DisplayBeep() return is missing before Original_DisplayBeep() in the else. Compiling with -Wall should warn for function not returning something and catch that.
...minimise the possibiliy something else also calls DisplayBeep before your command and clears the flag. This may also happen sometimes anyway I think but that was already said by the original poster of this idea.
I was actually thinking that the DisplayBeep() patch would check to see if it was being called by Workbench by calling FindTask(NULL) and checking the task name, just like the OpenWindowTagList() patch does. Only if the disable_flash_beep flag is set AND the caller is Workbench does the call get blocked and the flag get cleared.
That way, the only way it can go wrong is if Workbench calls OpenWindowTagList() a second time before it calls DisplayBeep() the first time. Depending on how Workbench is structured internally, that ranges from highly unlikely to impossible.
@kas1e
While playing with the program I noticed some issues that may be bugs or may be features .
1. If you click on an icon and then select 'Open' from the Workbench menu you get a Workbench window, not a Filer.
2. I figured a good torture test of the DisplayBeep() patch would be to shift-click a number of icons, then shift-double-click the last one, to open all the icons at the same time. DisplayBeep() worked fine, but all of the Filers that opened were for the last icon, the one I double-clicked.
@balaton Thanks ! Fixed/changed almost everything, except that with asnprintf i only add check that it's not <0 , because i can't check for "full string" , as paths differs, and maybe someone willing to run not just filer, but some other binary instead (like AmiDisk or so:) ).
@msteed I think Balaton mean to shift setting of the value just before calling of command, to avoid in-the-middle multitasking issues as much as possible. And i set this value inside of OpenWindowTagList() as this one already check on the Workbenh task, on the ICON type, and so on.
Quote:
1. If you click on an icon and then select 'Open' from the Workbench menu you get a Workbench window, not a Filer.
Yeah, that seems to happen because when you click on icon, and then hit RMB, and choose "open" the mouse cursor is out of the icon, so, checks inside patched function fail => run as before.. Probably we need somehow to change the code to be not just WhichWorkbenchObject() as it now, but somehow tell the function (if possible) that "if highlighted, and does not matter where clicked"). If possible of course ..
Quote:
2. I figured a good torture test of the DisplayBeep() patch would be to shift-click a number of icons, then shift-double-click the last one, to open all the icons at the same time. DisplayBeep() worked fine, but all of the Filers that opened were for the last icon, the one I double-clicked.
Mmm.. right.. Issue there, that to take a path to which icon belong to, i use that WhichWorkbenchObject() again, which works for the icon you clicked on seems so (at least by default).
So we need to find a ways how to tell WhichWorkbenchObject() to take path just when icon highlighted and not when mouse cursor over it or clicked at. This will fix both issues for us then. Have any idea maybe ?:)
@All
New version:
Quote:
-- build with -Wall and -O3, later of which made binary be smaller on 1kb -- made a changes/fixes following Balaton's coding style suggestions (kudos for help!): -- made struct Task to be local to Patched_OpenWindowTagList() -- cleaned and simplify ctrl+c loop by get rid of unuzed vars and shifting printf out of ctrl+c check-loop -- minimize multitasking risks of calling DisplayBeep() out of our hack -- added error checking for Task creatiog and asnprinf() result -- use sizeof(..) with WBOBJA_FullPathSize to avoid future's potential issues when code grow -- fixed missing return in Patched_DisplayBeep()