bugGNU Octave - Bugs: bug #52621, root graphics object property...

 
 

bug #52621: root graphics object property "currentfigure" does not respect figure "handlevisibility" property

Submitter:  -X- <jsh>
Submitted:  Fri 08 Dec 2017 02:41:09 AM UTC
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment (Rich Markup)
   

Comment Type & Canned Response:
       

 

( Jump to the original submission )

Mon 18 Dec 2017 07:12:12 PM UTC, comment #12: 

I changed the remaining instances of gcbf() where there might be problems with the new behavior.  Most of the time the code could just be deleted as it was unnecessary, so we get a small performance boost too!

Rik <rik5>
Project Administrator
Thu 14 Dec 2017 12:28:04 AM UTC, comment #11: 

I changed Octave's mechanisms around close() and closereq() functions to match Matlab's behavior.  See cset http://hg.savannah.gnu.org/hgweb/octave/rev/9213b8166af9.

Rik <rik5>
Project Administrator
Tue 12 Dec 2017 12:13:13 AM UTC, comment #10: 

Looking at closereq.m, we would need to slow things down and use a for loop in the m-file if we want to implement things exactly like Matlab.

Currently, the code just collects the figures to process and then runs

  __go_execute_callback__ (figs, "closerequestfcn");

If every figure to be closed should be the gcf then this would need to be modified to

for fig = figs
  figure (fig{1});  # make figure current
  __go_execute_callback__ (fig{1}, "closerequestfcn");
endfor

Actually, since figure.m is a reasonably complex m-file, we might want to shorten that up by just using

set (0, "currentfigure", fig{1});

Rik <rik5>
Project Administrator
Mon 11 Dec 2017 11:49:32 PM UTC, comment #9: 

@Pantxo: Interesting.  In the documentation I see

    The close operation executes the function defined by the figure CloseRequestFcn property. The default function is closereq.

    The closereq function unconditionally deletes the current figure, destroying the window. The closereq function takes advantage of the fact that the close command makes each figure specified as an argument the current figure before calling its respective close request function.

The closereq function honors the ShowHiddenHandles property setting during figure deletion and does not delete hidden figures.

So it is the case that closereq doesn't delete HiddenHandle figures, but if "clase all hidden" is used it must delete these figures too.  It sounds like 'close all hidden' changes the HandleVisibility property.

One other thing, could you test this in Matlab?

close all
figure
closereq

Does it issue a warning?

Rik <rik5>
Project Administrator
Mon 11 Dec 2017 10:57:51 PM UTC, comment #8: 

@Rik: sorry, I had seen those warning during tests but hadn't had time to look at them.

  • closereq: according to the ML doc for the "closerequestfcn" property [1], "close" should make figure current before evaluating the closerequestfcn so that closereq can rely on gcf (instead of gcbf) to call the "delete" function.
  • others: I had no time to look at them but I am under the impression that we can workaround the possibly empty gcbf using "ancestor (hax, 'figure')".

[1] https://fr.mathworks.com/help/matlab/ref/matlab.ui.figure-properties.html#buiwuyk-1-CloseRequestFcn

Pantxo Diribarne <pantxo>
Project Member
Mon 11 Dec 2017 05:23:32 PM UTC, comment #7: 

@Pantxo: Good work.  I checked in the patch here http://hg.savannah.gnu.org/hgweb/octave/rev/41cf6ee90cb6.

This is enough of a change that odd side effects are likely to crop up for a while.  For example, I tried this.

octave:2> h1 = figure
h1 =  1
octave:3> h2 = figure
h2 =  2
octave:4> set (h1, 'handlevisibility', 'off')
octave:5> close all   # At this point, h2 was closed
octave:6> close all hidden
warning: closereq: calling closereq from octave prompt is not supported, use 'close' instead
warning: called from
    closereq at line 38 column 5
    close at line 99 column 3

The problem is in closereq.m

  cf = gcbf ();
  if (isempty (cf))
    warning ("closereq: calling closereq from octave prompt is not supported, use 'close' instead");
    cf = get (0, "currentfigure");
  endif

The file closereq.m is trying to use gcbf to see whether a callback is executing.  It seems like either we could get rid of the warning (which still wouldn't work for hidden figures), we could modify close.m to reset the handlevisibility property of all objects that it is about to call the closerequestfcn, or we have to invent something in C++ graphics code that allows gcbf to show through for figures which are being deleted (maybe when the "beingdeleted" property is true?).

I looked through the m-files for gco, gcbo, gcbf instances which might cause problems.  The only ones that looked like they might be an issue were these from gcbf

gui/dialog.m:100:    "buttondownfcn", "if isempty (allchild (gcbf)), close (gcbf), endif",
plot/appearance/legend.m:1116:        && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off"))
plot/appearance/legend.m:1136:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
plot/appearance/legend.m:1146:        && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
plot/draw/colorbar.m:262:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off")))
plot/draw/colorbar.m:312:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off")))
plot/draw/colorbar.m:335:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off")))
plot/draw/colorbar.m:354:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")))
plot/draw/plotyy.m:207:      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
plot/util/closereq.m:36:  cf = gcbf ();
plot/util/private/__add_default_menu__.m:89:    set (gcbf, "filename", fname);

I haven't reviewed any of the other instances besides closereq.m which I stumbled upon.

Rik <rik5>
Project Administrator
Sun 10 Dec 2017 01:44:23 PM UTC, comment #6: 

@Rik: As suggested, I attached an updated cset that handles currentobject, currentaxes and callbackobject as well (plus corresponding BIST).

(file #42610)

Pantxo Diribarne <pantxo>
Project Member
Fri 08 Dec 2017 04:47:36 PM UTC, comment #5: 

@Pantxo: The patch works very well for the issue at hand.  Looking at the documentation for the Figure "handlevisibility" property for Matlab

Visibility of figure object, specified as 'on', 'callback', or 'off'.

This property determines whether a figure is in its parent’s (the root’s) list of children. HandleVisibility is useful for preventing command-line users from accidentally drawing into, or deleting a figure that contains only user interface components (such as a dialog box).

If an object is not in its parent's list of children, functions that find objects by searching the object hierarchy or querying properties cannot return that object. Such functions include get, findobj, gca, gcf, gco, newplot, cla, clf, and close.

When the HandleVisibility property value is restricted using the 'callback' or 'off' settings, the object does not appear in the parent object Children property, figures do not appear in the root CurrentFigure property, objects do not appear in the root CallbackObject property or in the figure CurrentObject property, and axes do not appear in their parent CurrentAxes property.

In the third paragraph Octave now implements the first two conditions

1) object does not appear in parent object's "children" property
2) figures do not appear in root object's "CurrentFigure" property

Would it be possible for you to code a solution for the next two conditions as well?

3) object does not appear in root "CallbackObject" property (which gco() uses)
4) axes objects do not appear in their parent's "CurrentAxes" property.

As test code for the last condition,

hf = figure();
hax = gca;
get (hf, "currentaxes")
set (hax, "handlevisibility", "off");
get (hf, "currentaxes")

when I run that today I get

octave:40> hf = figure();
octave:41> hax = gca;
octave:42> get (hf, "currentaxes")
ans = -40.859
octave:43> set (hax, "handlevisibility", "off");
octave:44> get (hf, "currentaxes")
ans = -40.859

Rik <rik5>
Project Administrator
Fri 08 Dec 2017 10:57:45 AM UTC, comment #4: 

I attached a patch that makes Octave behave as ML with regards to Rik's test. With this patch, the following test (not included in Rik's) returns "2" followed by "1":

figure (1);
figure (2);
gcf () ## 2
set (2, "handlevisibility", "off");
gcf () ## 1

This means changing the visibility of the currentfigure not only makes it "not current" but also sets the first existing-visible-figure in the stack "current".

(file #42605)

Pantxo Diribarne <pantxo>
Project Member
Fri 08 Dec 2017 09:36:38 AM UTC, comment #3: 

In Matlab R2016a:

>> close all hidden
h1 = figure (1);
get (0, 'children')
get (0, 'currentfigure')
set (h1, 'handlevisibility', 'off');
get (0, 'children')
get (0, 'currentfigure')
h2 = figure (2);
get (0, 'currentfigure')
figure (1)
get (0, 'currentfigure')

ans =

  Figure (1) with properties:

      Number: 1
        Name: ''
       Color: [0.9400 0.9400 0.9400]
    Position: [1256 1206 560 420]
       Units: 'pixels'

  Show all properties


ans =

  Figure (1) with properties:

      Number: 1
        Name: ''
       Color: [0.9400 0.9400 0.9400]
    Position: [1256 1206 560 420]
       Units: 'pixels'

  Show all properties


ans =

  0x0 empty GraphicsPlaceholder array.


ans =

  0x0 empty GraphicsPlaceholder array.


ans =

  Figure (2) with properties:

      Number: 2
        Name: ''
       Color: [0.9400 0.9400 0.9400]
    Position: [1256 1206 560 420]
       Units: 'pixels'

  Show all properties


ans =

  Figure (2) with properties:

      Number: 2
        Name: ''
       Color: [0.9400 0.9400 0.9400]
    Position: [1256 1206 560 420]
       Units: 'pixels'

  Show all properties

Markus Mützel <mmuetzel>
Project Member
Fri 08 Dec 2017 06:26:40 AM UTC, comment #2: 

It would be useful if someone with access to Matlab could run the following code and report back the results.

close all hidden
h1 = figure (1);
get (0, 'children')
get (0, 'currentfigure')
set (h1, 'handlevisibility', 'off');
get (0, 'children')
get (0, 'currentfigure')
h2 = figure (2);
get (0, 'currentfigure')
figure (1)
get (0, 'currentfigure')

Rik <rik5>
Project Administrator
Fri 08 Dec 2017 06:22:25 AM UTC, comment #1: 

Confirmed.  Although the details are a little bit intricate and I have retitled this bug report to reflect that.

Octave does implement handlevisibility as shown below.

>> close all hidden
>> h1 = figure (1);
>> h2 = figure (2);
>> get (0, 'children')
ans =

   2
   1

>> set (1, 'handlevisibility', 'off')
>> get (0, 'children')
ans =  2

The problem is that while the figure is removed from the list of children, it is not necessarily removed from the "currentfigure" property.

I can get your example code to work by forcing the "currentfigure" property to be empty.

>> close all hidden
>> f = figure('handlevisibility','off');
>> set (0, 'currentfigure', [])
>> plot (1:10, 1:10)
>> findall (0, 'type', 'figure')
ans =

   2
   1

Rik <rik5>
Project Administrator
Fri 08 Dec 2017 02:41:09 AM UTC, original submission:  

figure property handlevisibility is not respected (at least not with the Qt tookit on Octave Windows builds 4.0.3 and 4.2.1)

The following code snippet should open a new figure to plot in, instead the plot is drawn in the "invisible" figure.

f = figure('handlevisibility','off');
plot(1:10,1:10)
findall(0,'type','figure')  % there should be two figures

-X- <jsh>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #42610:  fig_visib2.patch added by pantxo (7KiB - text/x-patch)
file #42605:  fig_visib.patch added by pantxo (3KiB - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by pantxo (Updated the item)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by jsh (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only project members can vote.

     

     

     

     

    Follow 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-12-18 rik5 StatusPatch Reviewed Fixed
        Open/ClosedOpen Closed
    2017-12-11 rik5 StatusPatch Submitted Patch Reviewed
        Release4.2.1 dev
    2017-12-10 pantxo Attached File- Added fig_visib2.patch, #42610
    2017-12-08 pantxo Attached File- Added fig_visib.patch, #42605
        StatusConfirmed Patch Submitted
    2017-12-08 rik5 StatusNone Confirmed
        Operating SystemMicrosoft Windows Any
        Summaryfigure property handlevisibility is not respected root graphics object property "currentfigure" does not respect figure "handlevisibility" property

    Back to the top

    Powered by Savane 3.10