13 February 2024, 20:49 | #1 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
How to emulate a WB menu item pick?
At the moment I'm writing a tool for WB 3.1 which should refresh all icon images after a screen mode change. I've done that already successfully for all disk icons and left out icons, but now I still want to emulate a click in the WB menu onto the "Rescan All" item in order to get a complete update of all icons with wrong colors on the new screen.
Therefore I've written a few test programs trying to pick a WB menu item either by using IDCMP messages or alternatively by using the input.device. In my tests I'm trying to select the "About" requester from the Workbench menu, because this gives a quick and clear response to see whether it works or not. With IDCMP messages I couldn't find a working solution for the emulation of the right mouse buttons, not even with WFLG_RMBTRAP set. So, I tried to find a solution by using the input.device instead. And that really works correctly as long as MagicMenu is installed. The "About" requester appears. But without MagicMenu running, the Workbench only switches the WB menu title bar on and then nothing happens anymore. The selection of icons on the screen gets blocked, too. And you can only pass through the WB menu, but trying to execute any item won't work. There is one exception for the original WB menu too: In case that I once choose the "About" menu item manually before I try out my test program then, after that initial item selection, my test program always works and I do not even need the RMB emulation, just a selection of the item "MENU_VERSION" would be enough to get the requester. What am I doing wrong or how can I get my test program to work without using MagicMenu? I tried already to add some calls to OnMenu(), but that didn't help to fix the WB blocking. I also tried BeginIO(), but with the same problem. DoIO() is something what I didn't try yet. I have no experience with this message system, so I probably did something stupid, but what exactly is wrong or missing in my code? Code:
incdir "include:" include "exec/execbase.i" include "exec/initializers.i" include "dos/dos.i" include "dos/dosextens.i" include "devices/input.i" include "devices/inputevent.i" include "intuition/intuition.i" include "lvo/LVOs.i" main MOVEA.L (4).w,A6 ; execbase BTST.B #AFB_68020,AttnFlags+1(A6) BNE.S .cpuisok MOVEQ #RETURN_FAIL,D0 RTS DC.B "$VER: WBMenuInputTest 0.9",0 CNOP 0,2 .cpuisok MOVEA.L ThisTask(A6),A4 LEA pr_MsgPort(A4),A0 LEA RmbIOStdRequest\.mn_ReplyPort(PC),A1 MOVE.L A0,(A1) LEA MyIOStdRequest\.mn_ReplyPort(PC),A1 MOVE.L A0,(A1) LEA MupIOStdRequest\.mn_ReplyPort(PC),A1 MOVE.L A0,(A1) TST.L pr_CLI(A4) ; from CLI or WB ? BNE.S .opendevice JSR _LVOWaitPort(A6) ; wait for startup MOVE.L D0,-(SP) ; save WB message LEA pr_MsgPort(A4),A0 JSR _LVOGetMsg(A6) ; remove Msg from port PEA .replyWBmsg(PC) ; WB patch for RTS from CLI calls .opendevice MOVEQ #RETURN_ERROR,D2 LEA RmbIOStdRequest(PC),A2 LEA inputdevice(PC),A0 MOVEA.L A2,A1 MOVEQ #0,D0 ; unit 0 MOVEQ #0,D1 ; no flags JSR _LVOOpenDevice(A6) TST.B D0 BNE.S .openfailed MOVEA.L A2,A1 JSR _LVOSendIO(A6) ; right mouse button down MOVEA.L A2,A1 JSR _LVOWaitIO(A6) MOVEA.L A2,A1 JSR _LVOCloseDevice(A6) LEA MyIOStdRequest(PC),A2 LEA inputdevice(PC),A0 MOVEA.L A2,A1 MOVEQ #0,D0 ; unit 0 MOVEQ #0,D1 ; no flags JSR _LVOOpenDevice(A6) TST.B D0 BNE.S .openfailed MOVEA.L A2,A1 JSR _LVOSendIO(A6) ; pick WB menu "Version" MOVEA.L A2,A1 JSR _LVOWaitIO(A6) MOVEA.L A2,A1 JSR _LVOCloseDevice(A6) LEA MupIOStdRequest(PC),A2 LEA inputdevice(PC),A0 MOVEA.L A2,A1 MOVEQ #0,D0 ; unit 0 MOVEQ #0,D1 ; no flags JSR _LVOOpenDevice(A6) TST.B D0 BNE.S .openfailed MOVEA.L A2,A1 JSR _LVOSendIO(A6) ; right mouse button up MOVEA.L A2,A1 JSR _LVOWaitIO(A6) MOVEA.L A2,A1 JSR _LVOCloseDevice(A6) MOVEQ #RETURN_OK,D2 .openfailed MOVE.L D2,D0 RTS ; CLI ends here, on WB to .replyWBmsg .replyWBmsg JSR _LVOForbid(A6) MOVEA.L (SP)+,A1 JSR _LVOReplyMsg(A6) ; WB unloads seglist MOVE.L D2,D0 ; set the final RC RTS ; return from WB tool MENU_VERSION EQU (0 & $1F) | ((5 & $3F) << 5) | (($1F & $1F) << 11) RmbIOStdRequest .ln_Succ DC.L 0 .ln_Pred DC.L 0 .ln_Type DC.B NT_MESSAGE .ln_Pri DC.B 0 .ln_Name DC.L 0 .mn_ReplyPort DC.L 0 ; filled out at program start .mn_Length DC.W $30 ; size of IOStdRequest .io_Device DC.L 0 .io_Unit DC.L 0 .io_Command DC.W IND_WRITEEVENT .io_Flags DC.B 0 .io_Error DC.B 0 .io_Actual DC.L 0 .io_Length DC.L $12 ; size of InputEvent .io_Data DC.L RmbInputEvent .io_Offset DC.L 0 RmbInputEvent .ie_Next DC.L 0 .ie_Class DC.B IECLASS_RAWMOUSE .ie_SubClass DC.B IESUBCLASS_COMPATIBLE .ie_Code DC.W MENUDOWN ; emulate right mouse button down .ie_Qualifier DC.W 0 .ie_x DC.W 0 .ie_y DC.W 0 .ie_TimeStamp DC.L 0 MyIOStdRequest .ln_Succ DC.L 0 .ln_Pred DC.L 0 .ln_Type DC.B NT_MESSAGE .ln_Pri DC.B 0 .ln_Name DC.L 0 .mn_ReplyPort DC.L 0 ; filled out at program start .mn_Length DC.W $30 ; size of IOStdRequest .io_Device DC.L 0 .io_Unit DC.L 0 .io_Command DC.W IND_WRITEEVENT .io_Flags DC.B 0 .io_Error DC.B 0 .io_Actual DC.L 0 .io_Length DC.L $12 ; size of InputEvent .io_Data DC.L MyInputEvent .io_Offset DC.L 0 MyInputEvent .ie_Next DC.L 0 .ie_Class DC.B IECLASS_MENULIST .ie_SubClass DC.B IESUBCLASS_COMPATIBLE .ie_Code DC.W MENU_VERSION .ie_Qualifier DC.W MENUDOWN ; still right mouse button down .ie_x DC.W 0 .ie_y DC.W 0 .ie_TimeStamp DC.L 0 MupIOStdRequest .ln_Succ DC.L 0 .ln_Pred DC.L 0 .ln_Type DC.B NT_MESSAGE .ln_Pri DC.B 0 .ln_Name DC.L 0 .mn_ReplyPort DC.L 0 ; filled out at program start .mn_Length DC.W $30 ; size of IOStdRequest .io_Device DC.L 0 .io_Unit DC.L 0 .io_Command DC.W IND_WRITEEVENT .io_Flags DC.B 0 .io_Error DC.B 0 .io_Actual DC.L 0 .io_Length DC.L $12 ; size of InputEvent .io_Data DC.L MupInputEvent .io_Offset DC.L 0 MupInputEvent .ie_Next DC.L 0 .ie_Class DC.B IECLASS_RAWMOUSE .ie_SubClass DC.B IESUBCLASS_COMPATIBLE .ie_Code DC.W MENUUP ; emulate right mouse button up .ie_Qualifier DC.W 0 .ie_x DC.W 0 .ie_y DC.W 0 .ie_TimeStamp DC.L 0 inputdevice DC.B "input.device",0 Last edited by PeterK; 18 February 2024 at 14:56. |
14 February 2024, 10:21 | #2 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,649
|
Are you sure the workbench window has focus? Using input.device, whatever you do would affect the currently focused window, right!?
|
14 February 2024, 11:46 | #3 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Yes, that's right, I should indeed set the ACTIVE_WINDOW to Workbench before I use the menu. But I'm using the left out tool icon from the WB screen in my tests and once it worked with MagicMenu it even works that way without MagicMenu. There must be another problem being responsible for the blocking.
And no, WB 3.1 unfortunately has no Arexx port. |
14 February 2024, 15:31 | #4 |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 193
|
See PowerWB source code on Aminet. You can send Intuition Messages yourself (which you set up such that they come back to your own replyport you create, not back to Intuition). Possibly bonus: maybe annoy a little bit Thor by doing things like this ...
|
14 February 2024, 16:01 | #5 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Thanks for this hint, aros-sg!
I will have a look at the PowerWB source code ASAP. Yes, Thor probably knows best how to work with Intuition and how to get access to menus without blocking the system. He may like my attempt or not ..., I just need a working solution for WB 3.1 to rescan all icons in the open windows. And that code exists already and the user can simply execute it by selecting "Update All" in the WB menu. I even have the WB 3.1 C source for that "Rescan All", but why should I rewrite that if it can be launched by just picking the WB menu item? Last edited by PeterK; 14 February 2024 at 16:11. |
16 February 2024, 14:33 | #6 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,362
|
Quote:
Thus, if you send an inputevent intuition would normally generate, the event will probably end up in lower handlers, but that intuition recognizes it as one of its own and sorts it into the IDCMPs I doubt since it is none of the input even types intuition would usually react upon - it is one of the types intuition would rather create. This being said, why exactly do you think it is necessary to tell the workbench to refresh its icons if it doesn't do itself? Usually workbench knowns when the screen prefs change (or rather, IPrefs knows and forwards the information). |
|
16 February 2024, 15:35 | #7 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Thanks for your explanations, Thomas. I think I've to read them carefully a few more times later again to understand what really happens with my input events.
There are also some comments in the MagicMenu.guide, maybe from Olsen. The problem seems to be (from my point of view) that a right mouse button down event lets most of the system fall asleep and that can easily cause deadlocks. MagicMenu seems to take some (I don't know what?) precautions to avoid these deadlocks. I just wanted to know how they are doing that? I will try out another modification of my code today by first sending all 3 IORequests at once in a forbid state and then after the permit start waiting for the 3 replies. I hope that by doing it this way Intuition gets the final "RMB up" request before my tasks falls asleep and the system gets blocked. If that also has no success, I may try a different approach by walking directly through the WB window structure, and I hope there is some access to the menu items somewhere under menustrip, but I didn't check that yet (just an idea from last night). So, why do I want to refresh all the icons after a screenmode change? That's no problem under WB v44+, but the old WB 3.1 doesn't know anything about palette based icons and color mapping. It will never reload icons to remap their colors. WB v44+ is doing that by calling icon.library IconControlA() and sets the icons screen first to NULL in order to release all pens, and then remaps all icons that are stored with a GlobalScreen flag. But on WB 3.1 (my) icon.library stores no icons in its internal list, because 3.1 is still doing many things in workbench.library, like allocating memory for some DiskObject structures and freeing them later. There is no access to a list of all open WBObjects. As stated in my 1. post I've already written a program which can refresh all the disk icons and left out icons on WB, the only part that is still missing is the refresh of all icons in the open windows, because the ColorIcons are not remapped by the system. I'm glad that even WB 3.1 already has a menu function to do that. It calls the internal routine "Rescan All". Now, I just want to launch that somehow, so that the user can refresh really everything on the WB screen with only one click onto my tool. Maybe, after some user tests, I could integrate that later into icon.library, too. |
16 February 2024, 16:53 | #8 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,362
|
While I afraid that I understood only half of the first part, concerning the icon refresh - have you attempted just to change the date or touch one of the preferences files in ENV:sys? This should trigger IPrefs to pick up the change, reload the (actually unchanged) preferences, and force their installation into the workbench, which would then re-render the icons or even re-open the screen.
|
16 February 2024, 20:09 | #9 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
No, changing the date or overwriting a file in ENV:Sys like the screenmode.prefs will never reload any icons on WB 3.1, not even on WB v44+. On v44+ the Workbench task only remaps the icon palettes to the colors of the new screen and after a C2P icon.library creates new planar images for the ColorIcons.
The usual 4-color planar images on WB 3.1 will never need a remapping, because the first 4 pens are using the fixed system colors only, or 8 colors for MWB icons. Ok, the windows and icon images may get rearranged and redrawn after a screenmode change, but the icons are not reloaded, nor remapped. LayoutIconA() is another v44 function to do that for a new screen, used by DOpus5 for example. Unfortunately, my tests with sending all 3 IORequests at once in a Forbid state didn't work at all, the deadlock with Forbid was even worse. And I also couldn't find a solution with the WB window menustrip data, because there seems to be no reference for the associated commands in the menu items. But that needs more investigations, I won't give up that soon ... Btw, in my test program it's the menu pick (the 2. IORequest) which hangs. If I disable it, then RMB down and RMB up are executed without causing a deadlock. Maybe I have to supply the correct mouse position for the menu pick, too. That can be calculated from the MenuItem data, but I don't have much hope that it will fix anything. ...no, it did not! Update: Meanwhile, I found a solution for the test tool with the "About" requester by using the shortcut key "?"+<RCommand>, but now I have to add a shortcut command for the "Update All" item to the menu. It already appears, but there are are still some problems to solve ... Last edited by PeterK; 18 February 2024 at 14:54. |
18 February 2024, 21:57 | #10 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
All problems are solved now, as I hope.
I've rewritten my test program for the "Update all" Workbench menu, which can be used on a WB up to v45, because WB v47 has already a different menu layout (one additional item for disks). My program only does a simple check whether menu 0 item 5 looks like the "Version" entry for the "About" requester by checking the command shortcut key for being a "?". If that is not the case then the program won't do anything and just returns. Update: the following code is not perfect yet. It needs some optimizations and improvements to work safer and more reliable under critical circumstances. Code:
incdir "include:" include "exec/execbase.i" include "exec/initializers.i" include "dos/dos.i" include "dos/dosextens.i" include "devices/input.i" include "devices/inputevent.i" include "intuition/intuition.i" include "lvo/LVOs.i" _LVOPrivateOpenLibrary EQU -$32A ; _LVOexecPrivate17 MENU_RESCAN_ALL EQU (0 & $1F) | ((3 & $3F) << 5) | (($1F & $1F) << 11) MENU_0_ITEM_5 EQU (0 & $1F) | ((5 & $3F) << 5) | (($1F & $1F) << 11) main MOVEA.L (4).w,A6 ; execbase BTST.B #AFB_68020,AttnFlags+1(A6) BNE.S .cpuisok MOVEQ #RETURN_FAIL,D0 RTS DC.B "$VER: WBMenuRescanAll 1.0",0 CNOP 0,2 ; 2024 by Peter Keunecke .cpuisok MOVEA.L ThisTask(A6),A2 LEA pr_MsgPort(A2),A0 LEA DELdIOStdRequest\.mn_ReplyPort(PC),A1 MOVE.L A0,(A1) LEA DELuIOStdRequest\.mn_ReplyPort(PC),A1 MOVE.L A0,(A1) TST.L pr_CLI(A2) ; from CLI or WB ? BNE.S .openlibrary JSR _LVOWaitPort(A6) ; wait for startup MOVE.L D0,-(SP) ; save WB message LEA pr_MsgPort(A2),A0 JSR _LVOGetMsg(A6) ; remove Msg from port PEA .replyWBmsg(PC) ; WB patch for RTS from CLI calls .openlibrary MOVEQ #RETURN_ERROR,D2 MOVEQ #3,D0 JSR _LVOPrivateOpenLibrary(A6) MOVE.L D0,D6 ; intuibase BEQ.W .openfailed JSR _LVOForbid(A6) LEA WorkbenchPort(PC),A1 ; WB 3.1 has no Port in that list ! JSR _LVOFindPort(A6) MOVEQ #RETURN_WARN,D2 TST.L D0 ; Workbench MsgPort ? BEQ.S .tryscreen MOVEA.L D0,A0 MOVEA.L MP_SIGTASK(A0),A0 ; Workbench process MOVE.L pr_WindowPtr(A0),D0 ; it may have been disabled with -1 BGT.S .windowptr .tryscreen MOVEA.L D6,A0 ; intuibase MOVEA.L ib_ActiveScreen(A0),A0 MOVE.L sc_FirstWindow(A0),D0 .trywindow BEQ.S .nowindows MOVEA.L D0,A0 MOVE.L wd_Flags(A0),D1 ; check bit 25 for WFG_WBENCHWINDOW LSL.L #6,D1 BMI.S .windowptr MOVE.L (A0),D0 ; wd_NextWindow BRA.S .trywindow .wrongmenu MOVEA.L (4).w,A6 ; execbase .nowindows JSR _LVOPermit(A6) BRA.W .closelibrary .windowptr MOVEA.L D0,A2 ; a Workbench window MOVEQ #RETURN_ERROR,D2 MOVEA.L A2,A0 ; window MOVEA.L D6,A6 ; intuibase JSR _LVOActivateWindow(A6) MOVEA.L wd_MenuStrip(A2),A5 ; menu MOVEA.L A5,A0 MOVE.L #MENU_0_ITEM_5,D0 ; v47+ has a different menu layout! JSR _LVOItemAddress(A6) MOVEA.L D0,A0 ; is this the MenuItem "Version" ? CMPI.B #"?",mi_Command(A0) ; command = "?" ? BNE.S .wrongmenu ; abort now, don't touch this menu MOVEA.L A2,A0 ; window JSR _LVOClearMenuStrip(A6) MOVEA.L A5,A0 MOVE.L #MENU_RESCAN_ALL,D0 ; let's assume item 3 is "Update all" JSR _LVOItemAddress(A6) MOVEA.L D0,A0 ; add flags to MenuItem "Update all" MOVEQ #ITEMENABLED | COMMSEQ,D0 OR.W D0,mi_Flags(A0) MOVEQ #$7F,D0 ; set <DEL> as command shortcut key MOVE.B D0,mi_Command(A0) ; I hope that <DEL> is not yet in use MOVEA.L A2,A0 ; window MOVEA.L A5,A1 ; menu JSR _LVOSetMenuStrip(A6) MOVEA.L (4).w,A6 ; execbase JSR _LVOPermit(A6) LEA inputdevice(PC),A0 LEA DELdIOStdRequest(PC),A1 MOVEQ #0,D0 ; unit 0 MOVEQ #0,D1 ; no flags JSR _LVOOpenDevice(A6) TST.B D0 BNE.S .closelibrary LEA inputdevice(PC),A0 LEA DELuIOStdRequest(PC),A1 MOVEQ #0,D0 ; unit 0 MOVEQ #0,D1 ; no flags JSR _LVOOpenDevice(A6) TST.B D0 BNE.S .closedevice LEA DELdIOStdRequest(PC),A1 JSR _LVODoIO(A6) ; <DEL> down + RCommand LEA DELuIOStdRequest(PC),A1 JSR _LVODoIO(A6) ; <DEL> up MOVEQ #RETURN_OK,D2 LEA DELuIOStdRequest(PC),A1 JSR _LVOCloseDevice(A6) .closedevice LEA DELdIOStdRequest(PC),A1 JSR _LVOCloseDevice(A6) .closelibrary MOVEA.L D6,A1 ; intuibase JSR _LVOCloseLibrary(A6) .openfailed MOVE.L D2,D0 RTS ; CLI ends here, on WB to .replyWBmsg .replyWBmsg JSR _LVOForbid(A6) MOVEA.L (SP)+,A1 JSR _LVOReplyMsg(A6) ; WB unloads seglist MOVE.L D2,D0 ; set the final RC RTS ; return from WB tool DELdIOStdRequest .ln_Succ DC.L 0 .ln_Pred DC.L 0 .ln_Type DC.B 0 .ln_Pri DC.B 0 .ln_Name DC.L 0 .mn_ReplyPort DC.L 0 ; filled out at program start .mn_Length DC.W $30 ; size of IOStdRequest .io_Device DC.L 0 .io_Unit DC.L 0 .io_Command DC.W IND_WRITEEVENT .io_Flags DC.B 0 .io_Error DC.B 0 .io_Actual DC.L 0 .io_Length DC.L $12 ; size of InputEvent .io_Data DC.L DELdInputEvent .io_Offset DC.L 0 DELdInputEvent .ie_Next DC.L 0 .ie_Class DC.B IECLASS_RAWKEY .ie_SubClass DC.B IESUBCLASS_COMPATIBLE .ie_Code DC.W $0046 ; <DEL> down .ie_Qualifier DC.W IEQUALIFIER_RCOMMAND .ie_x DC.W 0 .ie_y DC.W 0 .ie_TimeStamp DC.L 0 DELuIOStdRequest .ln_Succ DC.L 0 .ln_Pred DC.L 0 .ln_Type DC.B 0 .ln_Pri DC.B 0 .ln_Name DC.L 0 .mn_ReplyPort DC.L 0 ; filled out at program start .mn_Length DC.W $30 ; size of IOStdRequest .io_Device DC.L 0 .io_Unit DC.L 0 .io_Command DC.W IND_WRITEEVENT .io_Flags DC.B 0 .io_Error DC.B 0 .io_Actual DC.L 0 .io_Length DC.L $12 ; size of InputEvent .io_Data DC.L DELuInputEvent .io_Offset DC.L 0 DELuInputEvent .ie_Next DC.L 0 .ie_Class DC.B IECLASS_RAWKEY .ie_SubClass DC.B IESUBCLASS_COMPATIBLE .ie_Code DC.W $00C6 ; <DEL> up .ie_Qualifier DC.W 0 .ie_x DC.W 0 .ie_y DC.W 0 .ie_TimeStamp DC.L 0 inputdevice DC.B "input.device",0 WorkbenchPort DC.B "WORKBENCH",0 CNOP 0,4 Last edited by PeterK; 22 February 2024 at 14:26. |
21 February 2024, 14:21 | #11 |
Camilla, AmigaOS Dev.
Join Date: Mar 2020
Location: Frederiksberg
Posts: 330
|
Hmm that is a very hacky solution. Did you try to do as aros-sg suggested in comment 4. That sounds like a much cleaner solution
|
21 February 2024, 14:56 | #12 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
What is so hacky with my solution?
I started this thread in the hope to get some useful suggestions, but there was nothing matching exactly my demands. I also checked the PowerWB code to get some inspiration, but that source looks so much different that I couldn't find a solution for my program. I already tested IDCMP messages to the window port before, but with the result that sending right mouse button events didn't work at all. And no, I don't want to create a completely new menu, I just want to access the item "Update All" in the existing WB menu. Unfortunately, the menu layout has already changed again on WB v47, and it seems to be quite difficult to check a particular menu item number for the function behind it which gets executed when the user selects that item. I guess that the menu item text is localized, so that makes it impossible to compare strings. +++ I just found an image of the WB menu in the PowerWB package with an interesting remark about the item positions. Look at the author's comment in the attached image below. That's exactly why I added my simple check for the menu layout. But, if you know how to write a better and more system friendly code for WB 3.1, don't hesitate to publish it here. Every suggestion that really works is welcome. No, WB v44+ won't need a tool like my RefreshIcons, which is now available at the end of my IconLib thread: https://eab.abime.net/showthread.php...34#post1670234 Last edited by PeterK; 21 February 2024 at 19:24. |
22 February 2024, 11:15 | #13 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,362
|
Multiple things. Intuition->FirstScreen is not Forbid-protected. It is protected by the intuition lock. Thus, at the time you look at this pointer, it may no longer be vaild because intuition is right now working on it. Similarly, the menu strip is also under control of its owner, namely the workbench, thus just looking at the pointer does not ensure that the pointer is actually valid at the time you check. That is, ItemAdress() may not function properly or crash in case you let it iterate over the menu of another process. ClearMenuStrip you call without knowing whether the workbench is probably currently trying to reach out for the menu, so you may crash the workbench at this point. You also assume that the menu you are looking for is in a particular position, which may be fine enough if the workbench is really the workbench. |
22 February 2024, 14:57 | #14 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Thank you for your suggestions to make my code safer and more reliable, Thor.
Is Intuition always not Forbid() protected in general or can it simply be reactivated at any time by some interrupts, maybe a requester with a message from an interrupt popping up on the screen suddenly or similar actions? I will try to improve my code by locking Intuition for a while and maybe the screen, too. Just a question concerning LockPubScreen("Workbench"): does that argument "Workbench" really ensure that the WB screen is returned, even if the user has renamed it already to something else. And Scout's window list also shows the name "Workbench Screen", which won't match in a string comparison with "Workbench". Can I rely on to get and lock the WB screen, whatever its actual name is? |
22 February 2024, 17:52 | #15 | ||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,362
|
Quote:
ItemAddress() is probably fine, but ClearMenuStrip() and AddMenuStrip() are certainly *not* right because they need to interact with the input handler (ensure that no menu is picked anymore, and wait for the user to stop playing with the menu). Also, to gain access to the workbench screen, I would use LockPubScreen() because that also ensures that the screen is not going away as long as you hold the lock. What remains as issue is how to get hold of the intuition menu and an active workbench window. Quote:
Greetings, Thomas |
||
23 February 2024, 15:03 | #16 |
Camilla, AmigaOS Dev.
Join Date: Mar 2020
Location: Frederiksberg
Posts: 330
|
So neither aros-sg nor I was suggesting that you emulate mouse movements. Sending that to the idcmp port will indeed not work. But sending a IDCMP_MENUPICK to a representative window (with a replyPort to yourself) will probably work.
This will avoid you having to send a keypress or mouseevent. However wb could still be in the middle of drawing a selection, or moving an icon, which could be bad. I don't have a solution for that right now. Checking if the menu layout is as expected can likely be done by looking at the workbench version number. And all Thomas said is very important. But as I said wb could be in the middle of something too. What you are trying to do is by definition hacky. So at the very least try it out. |
23 February 2024, 15:20 | #17 | |
Registered User
Join Date: Nov 2015
Location: Italy
Posts: 193
|
Quote:
It will work. I wrote PowerWB. Just try it out on 3.0 or 3.1. It extends WB by for example adding gadgets to titlebar to quickly change between "view by icon" and "view by name" or scroll with the cursor keys. It works by sending idcmp messages like IDCMP_MENUPICK or IDCMP_GADGETDOWN messages to the WB. |
|
23 February 2024, 15:57 | #18 | ||||
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Quote:
Quote:
Quote:
Quote:
|
||||
23 February 2024, 16:03 | #19 | |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,389
|
Quote:
No! IDCMP_GADGETDOWN was meant to be an alternative to IDCMP_MENUPICK, not a 2. message, and indeed you said 1. "or" 2.. My program has nothing to do with gadgets. There is still something else missing ... Last edited by PeterK; 23 February 2024 at 18:02. |
|
23 February 2024, 23:25 | #20 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,362
|
Quote:
Typically, the workbench would then abort dragging or drawing the crawling ants, and when this message is replied, the menu is opening. Then, when the user selects a menu item, a MENUPICK is send, thus possibly seconds later (or how long it takes for the user to make a choice). Thus, if you send a MENUPICK without a MENUVERIFY, then likely the workbench is confused. It also has a state machine driven by IDCMP events. Now, the problem is of course that if you send a bogus MENUVERIFY upfront, you do not know whether intuition sends a real MENUVERIFY right after (or right before), and you would leave the workbench in the state of having received two of these IDCMPs, and that's again a situation that does not happen in a real system, so anything can happen, actually. This complicated protocol is actually also the reason why MagicMenu is not (and cannot) fully work, but that's another story. So yes, certainly, just faking an IDCMP menupick does *not* work. That's more due to the menu system protocol than actually sending a custom message to the window port. |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Commodity that adds list of windows to WB menu? | coldacid | request.Apps | 6 | 25 June 2020 15:24 |
ClassicWB Scalos Menu - Item Renaming | Heywood | project.ClassicWB | 1 | 26 June 2019 15:50 |
Simplest way of creating a menu in WB? | Foebane | support.Apps | 8 | 22 September 2018 19:46 |
IBrowse custom contextual menu item | _amigan | support.Apps | 0 | 30 November 2012 17:13 |
scalos/wb top menu | _psy | project.ClassicWB | 3 | 03 January 2011 13:32 |
|
|