Checking for adjust-size presses
Chris (121) 472 posts |
I have a resizable window with text wrapped to the window’s visible area. When I drag the adjust-size tool icon, the contents have to be reflowed. This all works, but if I drag any great distance, then several redraw window requests are made before the desired size is settled on, which can make things laggy due to multiple reflows of the text. I was wondering whether one solution would be to reflow the contents properly only when the drag had finished – ie, the adjust-size icon has been released. So, if a redraw request comes in and the adjust-size icon is pressed, the window contents are just redrawn in place without reflowing, but if the icon has been released, the text is fully reflowed to wrap to the window’s new visible extent. If this is a sensible strategy, how do I find out the state of the adjust-size icon? Trawling through the PRMs has left me none the wiser. |
Graeme (8815) 108 posts |
You could redraw only after all the mouse buttons have been released. However, I think you would need to start capturing null poll events and manually force a redraw because the last redraw request sent may still have a mouse button pressed at the time. |
Matthew Phillips (473) 722 posts |
Good question. An alternative approach would be to check the state of the mouse buttons, and if Select or Adjust are currently held down, redraw without reflowing, enable null polls, and upon the next null poll reflow your text (probably by marking the whole window as needing redrawing) and mask the null events out again. Sorry – that was my idea having not looked in the PRMs at all. Here is a better one: Call Wimp_GetPointerInfo. This will tell you the button state in R1+8, the window handle in +12 and the icon handle in +16. The adjust size icon has handle -9. So check to see if the window is yours, the icon is adjust size, and the Select or Adjust mouse buttons are held down. |
Chris (121) 472 posts |
Great – thanks. I should have thought of that – I had a dim memory that tool icons were negative values, but couldn’t find where they were listed. |
nemo (145) 2611 posts |
It is wrong to look at the tool numbers. Window moves and resizes can be triggered by other methods that don’t have the pointer over that icon – see Wimp_DragBox types 1-4. |
Matthew Phillips (473) 722 posts |
Chris is trying to avoid the work of reflowing text too often during the user dragging to resize the window. If he adopts my second suggestion, of looking to see if the icon under the mouse is the adjust size icon and checking if Select or Adjust is currently held, that would allow him to reduce how much he reflows stuff while a drag is ongoing. I agree that window resizing can happen in other ways too, but the worst that can happen if he adopts my suggestion is that the full reflow work will end up being done every time in those cases. A more generic method would be to reflow the text when the window is first resized, but note the time, and inhibit further reflow being carried out for the next N centiseconds, making sure that you have a Wimp_PollIdle in place to get a null poll when things have settled down and reflow/redraw as needed. I’m not an expert on this stuff as I’ve not supported reflowing text like this in any applications I’ve written. If you’d like to explain the right way to do it, I’d be keen to learn as there is a window in RiscOSM that could do with enhancing like this, and it would save some time implementing it right first time! |
nemo (145) 2611 posts |
The simplest would be to check for button-still-down during the OpenWindow event that is resizing the window, and switch on an idle poll which will subsequently cause a reflow when it detects the button has been released. |
Matthew Phillips (473) 722 posts |
Ah – so my original suggestion before I looked things up in the PRMs was basically right. You mention Wimp_DragBox types 1-4, but only type 2 would affect the window in a way which required the text to be reflowed. I suppose Wimp_DragBox type 2 might be initiated by a third party Wimp experience enhancing module? I’m sure I’ve seen one that allows you to move windows about by dragging anywhere in the window, but as I keep my machines fairly vanilla I am not familiar with these. Aside from such utilities, I can’t think of any other means by which a rapid series of window resizes would occur, other than through dragging the adjust size icon. |
nemo (145) 2611 posts |
Sprinkle emojis liberally over this…
How many examples do you need for the point to be valid?
Indeed.
“I can’t think” is not a valid line of reasoning. Mode changes can cause resizes, obviously, but the fact is that any task can resize a window belonging to another task (prior to Wimp 3.8 one had to Wimp_SendMessage whereas now one can Wimp_OpenWindow, but so what). Just open a TaskWindow, point at some window and type:
So resizes can happen, by systems and mechanisms you haven’t yet encountered, and cannot be generalised to “The pointer will be over this part of the window furniture”. That is my point. |
Matthew Phillips (473) 722 posts |
I suppose it’s a case of being technically right versus being pragmatic. Often it’s more important to be technically right. My suggestion for checking the window furniture would help a lot for the most common cause of frequent window resizing and would not have made any other situations any worse. But checking for button-still-down during the OpenWindow event, and doing the reflow at the next null poll catches a (slightly?) wider range of cases without being too clever and prone to breakage. Even checking for button-still-down, as you suggested earlier, doesn’t cater for all the imaginable ways of having a rapid series of window resizes. |
nemo (145) 2611 posts |
Checking for mouse-down during resize is a heuristic – there simply isn’t an API to read the drag status. For mouse-initiated resizes (by any mechanism) it works well. For other forms of resize it’s harmless – the user will soon release the mouse button and the reflow will occur. The window furniture is a red herring and you must let it go. The other way is simply to defer all reflows to resizetime+delay and use PollIdle. This would keep deferring during your ‘rapid series’ of resizes. I implemented ‘outline-only redraw while scrolling’ in Vantage by this method. |
André Timmermans (100) 656 posts |
That one reminds me of the fatal flow of dragging in RISC OS: it informs you when the user releases the mouse but nothing signals you that the drag is aborted (for example when an error box pops up while you’re dragging). That’s why I always check for mouse-down while dragging. |
Steve Pampling (1551) 8198 posts |
I regard that as an example of why the single tasking, but can interrupt1 pretty much everything else, nature of the error “logging” / notification system in the OS is really bad2 1 How many people have never had an instance where the error pop-up was only truly cancellable by use of the power switch? 2 It’s almost like Windows in that infuriating, focus grabbing, for no reason at all, way |
Rick Murray (539) 13908 posts |
“It depends”. Often something that has borked can be convinced to get lost by using Alt-Break; but if that doesn’t work and the error won’t go away (like when the Wimp or MessageTrans gets its knickers tangled) then you’re screwed regardless of whether or not the error is blocking. If it wasn’t, the result would probably be worse as it would instantly freeze and possibly without anything on-screen to give some sort of indication that a “Ha! Ha! You thought you should save that file thirty seconds ago but you didn’t and now you’ve lost forty minutes of work! Ha! Ha!” scenario has just happened.
Nah, RISC OS is far better as it’s only the error boxen that grab focus like that. On Windows, it’s damn near everything. I don’t know about modern Windows, but things on XP liked to open a window, grab focus, and then flash the window button in the taskbar in a very mocking way. So I’m doing something and “Oh look!” it’s a big window popping up to thank me for installing a geniune HP cartridge in my printer (days ago). I’m with Instant Ink you twats, you’re hardly going to be sending me fakes (and it’s HP so you’re going to bend over backwards to block fakes from working anyway) so… um… eff off, maybe? Anyway, RISC OS… ;) There are numerous notifications lacking within the desktop. There’s no broadcast, for example, when a device is added or removed (I’m thinking USB here). There’s no notification for disc mounted/dismounted. Nor if a file handle has been closed (that might have stopped an amount of corruption back in the day if an app could have been aware that a file it has open, no longer is). No notification for keyboard/language change. And so on. I’ve just done some quick tests (NetSurf and Zap). If you begin a drag, then press ESC, the Save dialogue goes away but the drag remains active, and when dropped someplace the save then happens. That…doesn’t feel like the right behaviour. Though this is RISC OS and therefore it’s probably up to the app to correctly cancel the drag and nemo has probably written a missive on how we’re doing it wrongly anyway (and this would be point seven in a depressingly long list). ;) |
Steve Pampling (1551) 8198 posts |
That’s probably zero-point-seven-zero-zero to help fit all the items in a list that doesn’t go above an integer one hundred thousand, or so. :) Of error logging systems, whatever happened to the syslog variant that Julie was working on? I don’t recall seeing any source so that someone could continue if need be. |
André Timmermans (100) 656 posts |
And how many other pieces of software actually come with their sources. At least it’s her own implementation of the module so she is free to provide them or not, compare that to the numerous ports of gpl software that come without the sources of the RISC OS version. |
Steve Pampling (1551) 8198 posts |
Most of the other test/alpha/beta stuff from Julie, this was an instance where it didn’t appear. (shrug) |
nemo (145) 2611 posts |
Inescapable interactions such as drags that can’t be cancelled are very bad design. Always allow the user to change their mind. Having said that, I can imagine that on a VERY small screen it might be nice to make the menu disappear to reveal where you wanted to drag the icon… but a second Escape should certainly cancel the drag if you’ve cleverly coded it like that. |