From 77b78bf94fa15d0f1c15ab326927a433eab6dd57 Mon Sep 17 00:00:00 2001 From: Steve Fryatt Date: Tue, 5 Jul 2022 23:30:18 +0100 Subject: [PATCH] Improve details of pane optimisation in Chapter 5. --- Chapters/ch05-does-order-matter.xml | 33 +++++++++--------- Downloads/Chapter05/ColHead4/!Boot,feb | 24 +++++++++++++ .../Chapter05/ColHead4/!PaneDemo/!Boot,feb | 24 +++++++++++++ .../Chapter05/ColHead4/!PaneDemo/!Run,feb | 29 +++++++++++++++ .../ColHead4/!PaneDemo/!RunImage,ffb | Bin 0 -> 14960 bytes .../ColHead4/!PaneDemo/Templates,fec | Bin 0 -> 1377 bytes Downloads/Chapter05/ColHead4/!Run,feb | 27 ++++++++++++++ Downloads/Chapter05/ColHead4/!RunImage,ffb | Bin 0 -> 14960 bytes Downloads/Chapter05/ColHead4/Templates,fec | Bin 0 -> 1377 bytes 9 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 Downloads/Chapter05/ColHead4/!Boot,feb create mode 100644 Downloads/Chapter05/ColHead4/!PaneDemo/!Boot,feb create mode 100644 Downloads/Chapter05/ColHead4/!PaneDemo/!Run,feb create mode 100644 Downloads/Chapter05/ColHead4/!PaneDemo/!RunImage,ffb create mode 100644 Downloads/Chapter05/ColHead4/!PaneDemo/Templates,fec create mode 100644 Downloads/Chapter05/ColHead4/!Run,feb create mode 100644 Downloads/Chapter05/ColHead4/!RunImage,ffb create mode 100644 Downloads/Chapter05/ColHead4/Templates,fec diff --git a/Chapters/ch05-does-order-matter.xml b/Chapters/ch05-does-order-matter.xml index ec1c639..0681984 100644 --- a/Chapters/ch05-does-order-matter.xml +++ b/Chapters/ch05-does-order-matter.xml @@ -46,7 +46,7 @@

So far, we’ve seen how we can manually create one or more panes on our window, and have them behave in a number of distinct ways. Throughout the examples, however, the PROChandle_pane_windows() procedure has always called Wimp_OpenWindow for the different windows in a very specific order: first the pane, then the main window, and finally the pane again.

-

Back in we stated that this order was necessary, but hinted that we might be able to simplify things in some circumstances. Now, with all of the main details covered, it seems like a good time to go back and fill in this missing information!

+

Back in we stated that this order was necessary, but hinted that we might be able to simplify things in certain circumstances. Now, with all of the main details covered, it seems like a good time to go back and fill in this missing information!

@@ -111,29 +111,29 @@ toolbar%!28 = main%!28 SYS "Wimp_OpenWindow",,toolbar% ENDPROC -

Now that PROChandle_pane_windows() doesn’t open the main window, we will also need to make a small change to PROCopen_main_window so that it does that task for itself. The change is simply adding a call to Wimp_OpenWindow before the call to PROChandle_pane_windows(), at the end of the procedure.

+

Now that PROChandle_pane_windows() doesn’t open the main window, we will also need to make a small change to PROCopen_main_window so that it also does that task for itself. The change is simply adding a call to Wimp_OpenWindow before the call to PROChandle_pane_windows(), at the end of the procedure.

q%!28 = -1 : REM Window to open behind (-1 is top of stack) SYS "Wimp_OpenWindow",,q% PROChandle_pane_windows(q%) -

With all of these changes in place, a complete copy of the new application can be found in . When run, it might perform in a very similar way to from the previous chapter... or it might not.

+

With all of these changes in place, a complete copy of the new application can be found in . When run, it might perform in a very similar way to from the previous chapter... or it might not.

- +
Order does matter... sometimes -

If you download and run , you will either find that it behaves identically to , or that it exhibits a very obvious flicker from the toolbar whenever the window is dragged around with Select on the title bar. Which it does will depend on the version of the Window Manager you have on your system.

+

If you download and run , you will either find that it behaves identically to , or that it exhibits a very obvious flicker from the toolbar whenever the window is dragged around with Select on the title bar. Which it does will depend on the version of the Window Manager that you have present on your system.

To understand the differences, we’ll consider what happens to the main window and its toolbar pane when they’re dragged with Select at the top of the window stack. shows the initial positions of the two windows in the stack, at the point just before an Open_Window_Request event arrives to ask our application to open the main window at the top of the stack.

-

If we follow the new approach outlined in this chapter with , the first thing that our application does is to call the PROCopen_window_request() procedure, which in turn calls Wimp_OpenWindow for the main window using all of the values supplied by the Wimp. This will result in the main window being inserted at the top of the window stack as shown in – pushing the toolbar pane down below it.

+

If we follow the new approach outlined in this chapter with , then the first thing that our application does is to call the PROCopen_window_request() procedure, which in turn calls Wimp_OpenWindow for the main window using all of the values supplied by the Wimp. This will result in the main window being inserted at the top of the window stack as shown in – pushing the toolbar pane down below it.

@@ -153,22 +153,22 @@ PROChandle_pane_windows(q%)

If the main window moved during opening, then the last thing that PROChandle_pane_windows() will do is to re-position and re-open the toolbar pane – exactly as shown in .

-

The difference between the two approaches can be seen in and : in our new approach, the main window and its toolbar pane are briefly swapped over during the opening sequence, while in our original code, they are not.

+

The difference between the two approaches can be seen in and : in our new approach, the main window and its toolbar pane are very briefly swapped over during the opening sequence, whilst in our original code they are not.

A question of efficiency -

The difference described in the previous section matters, because of a small improvement introduced as part of the Nested Wimp. A couple of the changes documented in the Nested Window Manager Functional Specification are “Redraw Optimisation” and improvements to the “Invalid Rectangle Handling”. Between them, these have a big impact on the handling of panes.

+

The difference described in the previous section can matter a lot but, because of a small improvement introduced as part of the Nested Wimp, only with older versions of the Window Manager. A couple of the changes documented in the Nested Window Manager Functional Specification are “Redraw Optimisation” and improvements to the “Invalid Rectangle Handling”. Between them, these have a big impact on the handling of panes.

-

When an application calls Wimp_OpenWindow, the window in question isn’t immediately opened. Instead, the details are logged in a list of pending updates along with any other windows to be opened or closed – which are all actioned after the application next calls Wimp_Poll. This means that when our application opens its main window and toolbar pane, both windows will be updated together after control has returned to the Wimp.

+

When an application calls Wimp_OpenWindow, the window in question isn’t immediately opened. Instead, the details are logged in a list of pending updates along with any other windows to be opened or closed – all of which are actioned after the application next calls Wimp_Poll. This means that when our application opens its main window and toolbar pane, both windows will be updated together after control has returned to the Wimp.

-

Prior to the Nested Wimp, all of these pending actions would be carried out in full, in the order that they were specified. In contrast, the Nested Wimp scans the whole list and optimises out any inefficiencies, before carrying out the minimum number of actions required to achieve the end result.

+

Prior to the Nested Wimp, all of these pending actions would be carried out in full, in the order that they were specified. In contrast, the Nested Wimp scans the whole list of requests and optimises out any inefficiencies, before carrying out the minimum number of actions actually required to achieve the end result.

-

What this means in practice is that the Nested Wimp will notice that despite the toolbar pane ending up behind the main window in , it ends up back in from in – and so there’s no point redrawing the main window during the short period that it is on top.

+

What this means in practice is that the Nested Wimp will notice that, despite the toolbar pane ending up behind the main window in , it ultimately ends up back in front in . As a result, the Wimp will conclude that there’s no point redrawing the area of the main window which will be ending up behind the pane, even during the short period that it is on top – and so won’t ask for it to be done.

-

On earlier versions of the Wimp, however, our new optimised approach will result in the main window and its toolbar pane following the sequence shown in on every Open_Window_Request event. This produces a very visible flickering effect.

+

On earlier versions of the Wimp, however, our new optimised approach will result in the main window and its toolbar pane following the sequence shown in on every Open_Window_Request event. This produces a very visible flickering effect as each is redrawn in turn.

@@ -177,18 +177,19 @@ PROChandle_pane_windows(q%)
Is it any use? -

Given all of this, is the optimisation described in this chapter of any use? The answer is “yes,” but probably not in all circumstances.

+

Given all of this, is the optimisation described in this chapter of any use? The answer is “yes,” but not in all circumstances.

-

If an application needs the Nested Wimp for some other reason, and will not run without it, then there’s no harm in relying on the redraw optimisation in order to simplify the pane handling code. However, it’s also worth remembering that the Nested Wimp will deal with many pane requirements – including those in this chapter – directly, with no need for any custom event handling; we’ll see how this works in the next chapter. The main omission is for panes which fall outside the outline of the parent window, such as the side toolbox that we created in .

+

If an application needs the Nested Wimp for some other reason, and will therefore not be able to run without it, then there’s no harm in relying on the redraw optimisation in order to simplify the pane handling code. However, it’s also worth remembering that the Nested Wimp will deal with many pane requirements – including those in this chapter – directly, with no need for any custom event handling; we’ll see how this works in the next chapter. The main thing that the Nested Wimp does not support is panes which fall outside the outline of the parent window, such as the side toolbox that we created in .

For applications which do not need the Nested Wimp for other reasons, and would otherwise work fine back to RISC OS 3 or earlier, it seems a shame to restrict their compatibility for no good reason. Save for the situation when the window first opens, the more compatible solution is no less efficient than this optimised one: they both call Wimp_OpenWindow once for the main window and once for each pane.

-

If you do use the optimisation, though, it’s a good idea to check for its presence in the !Run of the application using an *RMEnsure.

+

Which approach to use will be a decision for individual developers, based on their applications’s requirements. If you do use the optimisation, though, it’s a good idea to check for its presence in the !Run of the application using an *RMEnsure.

RMEnsure WindowManager 3.80 Error PaneDemo requires the Nested Window Manager. - +

A version of the code with this change can be found in , and is the recommended way to approach this optimisation. There are no changes from aside from the fact that it will politely refuse to start on a system without the Nested Wimp – preventing any unwanted behaviour from affecting the user.

+
\ No newline at end of file diff --git a/Downloads/Chapter05/ColHead4/!Boot,feb b/Downloads/Chapter05/ColHead4/!Boot,feb new file mode 100644 index 0000000..1835fe7 --- /dev/null +++ b/Downloads/Chapter05/ColHead4/!Boot,feb @@ -0,0 +1,24 @@ +| >!Boot +| +| Copyright 2021-2022, Stephen Fryatt (info@stevefryatt.org.uk) +| +| This file is part of PaneDemo: +| +| http://www.stevefryatt.org.uk/risc-os/panes +| +| Permission is hereby granted, free of charge, to any person obtaining +| a copy of this software and associated documentation files (the +| "Software"), to deal in the Software without restriction, including +| without limitation the rights to use, copy, modify, merge, publish, +| distribute, sublicense, and/or sell copies of the Software, and to +| permit persons to whom the Software is furnished to do so. +| +| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +If ""="" Then Set PaneDemo$Dir diff --git a/Downloads/Chapter05/ColHead4/!PaneDemo/!Boot,feb b/Downloads/Chapter05/ColHead4/!PaneDemo/!Boot,feb new file mode 100644 index 0000000..1835fe7 --- /dev/null +++ b/Downloads/Chapter05/ColHead4/!PaneDemo/!Boot,feb @@ -0,0 +1,24 @@ +| >!Boot +| +| Copyright 2021-2022, Stephen Fryatt (info@stevefryatt.org.uk) +| +| This file is part of PaneDemo: +| +| http://www.stevefryatt.org.uk/risc-os/panes +| +| Permission is hereby granted, free of charge, to any person obtaining +| a copy of this software and associated documentation files (the +| "Software"), to deal in the Software without restriction, including +| without limitation the rights to use, copy, modify, merge, publish, +| distribute, sublicense, and/or sell copies of the Software, and to +| permit persons to whom the Software is furnished to do so. +| +| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +If ""="" Then Set PaneDemo$Dir diff --git a/Downloads/Chapter05/ColHead4/!PaneDemo/!Run,feb b/Downloads/Chapter05/ColHead4/!PaneDemo/!Run,feb new file mode 100644 index 0000000..a10cc85 --- /dev/null +++ b/Downloads/Chapter05/ColHead4/!PaneDemo/!Run,feb @@ -0,0 +1,29 @@ +| >!Run +| +| Copyright 2021-2022, Stephen Fryatt (info@stevefryatt.org.uk) +| +| This file is part of PaneDemo: +| +| http://www.stevefryatt.org.uk/risc-os/panes +| +| Permission is hereby granted, free of charge, to any person obtaining +| a copy of this software and associated documentation files (the +| "Software"), to deal in the Software without restriction, including +| without limitation the rights to use, copy, modify, merge, publish, +| distribute, sublicense, and/or sell copies of the Software, and to +| permit persons to whom the Software is furnished to do so. +| +| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Set PaneDemo$Dir + +RMEnsure WindowManager 3.80 Error PaneDemo requires the Nested Window Manager. + +WimpSlot -min 96K -max 96K +Run .!RunImage diff --git a/Downloads/Chapter05/ColHead4/!PaneDemo/!RunImage,ffb b/Downloads/Chapter05/ColHead4/!PaneDemo/!RunImage,ffb new file mode 100644 index 0000000000000000000000000000000000000000..beb76b58c31fec94a2cc68dcd72fbecfbd21bd15 GIT binary patch literal 14960 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 RjSb4aAU|@Xj867H{|h7S^XC8n literal 0 HcmV?d00001 diff --git a/Downloads/Chapter05/ColHead4/!PaneDemo/Templates,fec b/Downloads/Chapter05/ColHead4/!PaneDemo/Templates,fec new file mode 100644 index 0000000000000000000000000000000000000000..3f3953c3d229819b4dd8f6451834a9da587c773b GIT binary patch literal 1377 zcmY+E&1=+96vgk%s8i9vsD&w_@OG^rl1y7$!9uHpC{!7$NEa?lZR`xT$(YF?f{P+9 zT!_?_f`5RB;8qt^5Cpq$(S=|U#UethxNsp@@FSj+-s!~0+}zCl-IMcPUXnPDV@Zv3 zIDe55!A~k-Fm=Me7+7C7%igTWID++)Zq2u}-rOYe4K>!!1i|!#8(Qq=SnLpqaw3D< zM5fW#8nBFain)=`<}_M|-bJC5II&rn9XS>!c2#&JT;E}Y|%au4wm|0gk@HDvS` zFQF$wYz5ncSU`Oa`3LfjtQ1eVGoE!lE3239=cvD_`gzsgf%Xw%H&`d)mg=9XzS0cq zLBq4~H>Q3Rnf|lL^uGe_ZA1}_{uR{ee+`-bBh9E9go!-S7gS$X{bOjKBYL2rf2Zn) zRe#nC8@0esE-*3?G$RvLYYkJ!7KQGNRdIc5PDft7>iOnac-4)f{ibA> z91?c;jVN>@&(xtXRo9=KuK81h&H>vtJ!S7g(!P(S!`QqoOlmYQQeEFu8OG!=CvIS@ z8;IK=^8HsF7qEfkL-PLya&{(}o=5@QMs(mBYsibp=+E0$PUhd|f7bn%k>Ni(nBw#&r@!*MhfCa8tq%^L8Mbg;3+U&%V4u90OE`arz$2VISL9q*i+@1!Run +| +| Copyright 2021-2022, Stephen Fryatt (info@stevefryatt.org.uk) +| +| This file is part of PaneDemo: +| +| http://www.stevefryatt.org.uk/risc-os/panes +| +| Permission is hereby granted, free of charge, to any person obtaining +| a copy of this software and associated documentation files (the +| "Software"), to deal in the Software without restriction, including +| without limitation the rights to use, copy, modify, merge, publish, +| distribute, sublicense, and/or sell copies of the Software, and to +| permit persons to whom the Software is furnished to do so. +| +| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Set PaneDemo$Dir + +WimpSlot -min 96K -max 96K +Run .!RunImage diff --git a/Downloads/Chapter05/ColHead4/!RunImage,ffb b/Downloads/Chapter05/ColHead4/!RunImage,ffb new file mode 100644 index 0000000000000000000000000000000000000000..700ef6e1fb1cc4281c93e045d5493f91d3e9d445 GIT binary patch literal 14960 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 RjSb4aAU|@Xj867H{|o7X^X32m literal 0 HcmV?d00001 diff --git a/Downloads/Chapter05/ColHead4/Templates,fec b/Downloads/Chapter05/ColHead4/Templates,fec new file mode 100644 index 0000000000000000000000000000000000000000..3f3953c3d229819b4dd8f6451834a9da587c773b GIT binary patch literal 1377 zcmY+E&1=+96vgk%s8i9vsD&w_@OG^rl1y7$!9uHpC{!7$NEa?lZR`xT$(YF?f{P+9 zT!_?_f`5RB;8qt^5Cpq$(S=|U#UethxNsp@@FSj+-s!~0+}zCl-IMcPUXnPDV@Zv3 zIDe55!A~k-Fm=Me7+7C7%igTWID++)Zq2u}-rOYe4K>!!1i|!#8(Qq=SnLpqaw3D< zM5fW#8nBFain)=`<}_M|-bJC5II&rn9XS>!c2#&JT;E}Y|%au4wm|0gk@HDvS` zFQF$wYz5ncSU`Oa`3LfjtQ1eVGoE!lE3239=cvD_`gzsgf%Xw%H&`d)mg=9XzS0cq zLBq4~H>Q3Rnf|lL^uGe_ZA1}_{uR{ee+`-bBh9E9go!-S7gS$X{bOjKBYL2rf2Zn) zRe#nC8@0esE-*3?G$RvLYYkJ!7KQGNRdIc5PDft7>iOnac-4)f{ibA> z91?c;jVN>@&(xtXRo9=KuK81h&H>vtJ!S7g(!P(S!`QqoOlmYQQeEFu8OG!=CvIS@ z8;IK=^8HsF7qEfkL-PLya&{(}o=5@QMs(mBYsibp=+E0$PUhd|f7bn%k>Ni(nBw#&r@!*MhfCa8tq%^L8Mbg;3+U&%V4u90OE`arz$2VISL9q*i+@1