Problem reading the title string of a filer window
Gavin Cawley (8462) 70 posts |
I was just about to make an initial release of my tabbed container app, !tabby, that allows windows from other tasks to be organised under a common tab bar, but have found it doesn’t work for filer windows (which is something users may reasonably want to do). The problem is that I can’t discover the title string of the filer window to find out the name of the directory, which would be used as the label for the tab. The relevant code fragment is:
The problem is that info.info.title.indirecttext.bufflen seems to be always 14, regardless of the length of the actual title. It does the same thing for regular hard drive filer windows, ResourceFS and RamFS. I am using RPCEmu running 5.24, but we have also tested it on a Raspberry Pi running 5.28 and on a RiscPC running 3.70, and they all do the same thing. I expect I am missing something, but the code fragment seems to work for everything apart from filer windows. LOG is a call to my logging tool, if you want to see the code in greater context then both applications are available from https://github.com/usr-bin-gcc/Tabby P.S. I’m not sure which forum is the most appropriate for questions about programming, would this sort of thing be better in “community support” or “code review” |
Stuart Swales (8827) 1357 posts |
I think in the case of no-control-char-in-bufflen you need to loop retrieving further single bytes from We could request a fix for the Filer RISC OS 5 but that won’t help with current and retro systems. Indeed, the Filer may not be the only application that doesn’t set Be paranoid about the wimp_transferblock too – limit the initial transfer to the destination buffer size! |
Gavin Cawley (8462) 70 posts |
Thanks Stuart, I think that is unfortunately what I may have to do :-( I would be better if the filer accurately reported the size of the buffer (especially as it is part of the OS), but I think my app is doing something that was wasn’t anticipated by the authors! ;o) This is likely to be rather slow, which is a pity as the window title can change (e.g. when an edit has been made in !SrcEdit), and !tabby monitors the window title to see if it has been changed, so I don’t want to do something inefficient in the timer callback. Perhaps it needs to have a list of apps where the title actually needs to be monitored … or where we know it doesn’t. I’ll have to think about that. |
Gavin Cawley (8462) 70 posts |
Requesting a fix for RISC OS 5 sounds like a good idea. It isn’t something that is likely to create too many problems, but the documentation should be a reliable guide to what the OS actually does. |
Stuart Swales (8827) 1357 posts |
A subsequent slow byte transfer loop would only be needed when you have retrieved the icon data’s buffer up to bufflen (in one fast block transfer) and can’t find a CtrlChar in there. Ideally you’d be able to grab another block to append but for buffers near the application memory (or RMA) limit Wimp_TransferBlock is likely to unhelpfully error rather than just limit the transfer to what’s achievable. At least from my reading of the docs. |
Gavin Cawley (8462) 70 posts |
Yes, that is a neat solution. The thing that worries me is that if I read more than the stated buffer length, there is no guarantee that it won’t overflow the memory that is actually allocated in the task that owns the window, so that means it is my application that is misbehaving, rather than the window owner. However, it doesn’t look as if I have much of an option. I had originally just viewed the program as a means to add a tab bar to !SrcEdit (solving my major irritation when programming on RISC OS ;o), but it probably has wider uses, so worth making it a bit more robust. |
Stuart Swales (8827) 1357 posts |
Wimp_TransferBlock should refuse to transfer memory that’s beyond the task allocated slot. |
Gavin Cawley (8462) 70 posts |
Thanks again for the advice Stuart, glad to hear that I wasn’t missing something in the end. Just in case it is useful to anyone else, this code seems to work O.K. for me
|
Alan Adams (2486) 1149 posts |
I’d be inclined to add an additional check that you don’t attempt to read more than approx 240 bytes – because I suspect that whatever is in the title needs to be passed in Wimp messages, so would be limited in that way. |
Gavin Cawley (8462) 70 posts |
Thanks Alan, the buffer that I am reading the title into is now limited to 256 bytes. I hope that no paths are longer than that in practice as otherwise the tab label won’t be very informative. |
Paolo Fabio Zaino (28) 1882 posts |
@ Gavin
Not sure if this can help you, but on my PowerFiler the tab that controls a filer directory shows only the name of the “leaf” (or last directory in the path). To see the full path, a user has to leave the mouse pointer on the tab for like a bit less than a second and it will be displayed as a “bubble” and disappear as soon as the user moves the mouse. This makes the tab title still useful and, in case of confusion, the user can actually read the full path anyway (the bubble wraps the full path). It may not be your “cup of tea” for the design, but it works. Good luck! :) |
Gavin Cawley (8462) 70 posts |
@Paolo It sounds like the optimal solution may be to recommend people use PowerFiler instead and to use !tabby for adding tabs to programs like !SrcEdit and !Draw, which was the original intention. It is also the approach I was going to use for my minimal IDE, which is intended to wrap around whatever editor the user prefers, which I think may be feasible. I started writing !tabby so that I would get less irritated by having lots of editor windows on the screen while I worked on the IDE. |
David J. Ruck (33) 1636 posts |
In my WindOpen module which matches window titles, I just to a Wimp_TransferBlock of 256 bytes, and ensure the string is terminated on the 255th byte. I’ve not come across anything, including the RISC OS 5 filer, that this didn’t work for. |
Stuart Swales (8827) 1357 posts |
Remember that anything < 0×20 is a terminator here, not just 0×00! By all means plonk a zero in your copy at this point to keep C happy but the source task might well be BASIC.
That would have been my first instinct, but then consider dynamically created title strings that happen to be stored right next to the end of the application slot. |
Gavin Cawley (8462) 70 posts |
Thanks David, that is good to know. I’m beginning to think that Filer windows are more trouble than they are worth, because of the way the adjust size icon works with them, which meas that the correct behaviour can’t be implemented as a single drag AFAICS. I think maybe !tabby should be reserved for windows with both a vertical and horizontal scroll bar. Just need to do a bit more testing needed… |
Gavin Cawley (8462) 70 posts |
“Remember that anything < 0×20 is a terminator here, not just 0×00!” ah, I had a look in the PRMs for the terminator characters, but couldn’t find them. Fixed now. |
Steve Fryatt (216) 2105 posts |
The documentation is a reliable guide: the Filer isn’t the OS in this situation, it’s just another application. AFAIK the Wimp doesn’t really care about the length of an indirected icon buffer except when it’s a writeable icon or when loading window templates; it only reads from it, so just runs up to the control character terminator. So you could fix the Filer, and still run in to other applications which get this wrong. Realistically, for a window title bar, the only thing that will care about the length is the application, if it’s being sensible enough to check it when writing into the buffer itself. Or, more bluntly: if you’re guddling around in other applications’ window and icon data, you’ll need to allow for what the full range of applications out there actually do – and not what they would do if written correctly and tested to any other criteria than “does it seem to work on my system”. |
Rick Murray (539) 13850 posts |
I would imagine that to be rare to the point of artificial. Why? First consider an assembler program. It’s fairly normal to work out how much memory is available and set R13 there, for a descending stack. In C, would it be possible? What reaches the end of memory would likely be a stack chunk in the heap, which in common with everywhere also grows backwards. Any data stashed on the stack will be local not global, which wouldn’t be a logical place for persistent data. Also assuming it’s just on the edge of application memory, otherwise the runtime will simply try to extend the slot to allow the heap to grow. BASIC? Could be doable if one fiddles with the slot and HIMEM, to put data beyond the area that BASIC manages. If using DIM, it won’t be there. One could, I suppose, manually put such data way at the end in any language, but like I said, it would be an artificial example. I trust that Wimp_TransferBlock would fail sensibly with a logical error that can be trapped and handled, rather than crashing out with an abort. |
Gavin Cawley (8462) 70 posts |
“the Filer isn’t the OS in this situation, it’s just another application.” I would regard it as still part of RISC OS, and ought to behave as expected. “Or, more bluntly: if you’re guddling around in other applications’ window and icon data, you’ll need to allow for what the full range of applications out there actually do” yes, I fully agree there, but only if that doesn’t require my application to do something incorrect. If I have to do something dodgy to make it work with some third-party application, then I’ll just add that application to a list of applications that are not supported, if it is part of RISC OS then that is more difficult. At the moment I am not experienced enough with RISC OS to be confident that what I am doing is sufficiently correct/safe. Stuart’s suggestion of reading it a byte at a time until a terminator is found is a good cautious solution, so that is what I have done for now. |
Steve Fryatt (216) 2105 posts |
That’s largely irrelevant, though, because the behaviour that you’re interested in here is what the Wimp does.
So look at what the Wimp does, since that’s the final arbiter here. If the title bar text is displayed in full despite the length value being wrong, then the Wimp is reading the buffer content up to the terminator and ignoring the length value. If you want to be able to read other applications’ title bar text reliably, then unfortunately you’ll need to do the same thing that the Wimp does. Not because it’s “right”, but because the Wimp has allowed it since Arthur and so it won’t just be the Filer that’s getting this wrong. |
Steve Fryatt (216) 2105 posts |
Anything that’s reallocating indirected window title buffers in BASIC is likely to be the kind of thing that’s managing its own data heap after HIMEM, though. Anything that’s using DIM for memory allocation is unlikely to have the ability to handle more than one document, and so will probably just allocate 256 bytes in its Templates file…
What happens if a C application is using flex? I thought that sat beyond the stack, and was bumped up if the stack or runtime heap needed to be extended – which is why there’s the option to fix it in place and stop it moving (which in turn prevents the runtime extending its memory space, AFAIK). ETA. Although anything sticking indirection blocks into flex will be placing them in the first block of the heap using some other non-shifting heap nested within it, with the shifting blocks above that. So your assumption probably holds. Although my gut feeling is that if the stars aligned the wrong way, a single, empty CashBook file might be in with a chance of this happening depending on how everything else was set up. |