PopupWindow objects can be clicked multiple times, opening multiple popup windows for the same object. How can I prevent this?

A bit more detail: I have an application which displays a graphic. The user can click on elements of the graphic to call up an information panel about that element using PopupWindow. The user might have several of these popups open at once. To prevent confusion, I would like to make sure that the user cannot open more than one popup per object. I can't see a straightforward approach to doing this, so I'm hoping for some ideas from this fine community.

Example code:

DynamicModule[{col = ConstantArray[Blue, 5]},
 Graphics[{Table[With[{i = i},
       col[[i]] = If[CurrentValue["MouseOver"], Red, Blue];
       {Dynamic@col[[i]], Disk[{i, 0}, 0.5]}],
       col[[i]] = If[CurrentValue["MouseOver"], Red, Blue];
       Framed[Style["Disk " <> ToString[i], White, 20], 
        FrameMargins -> 80, Background -> Dynamic@col[[i]]]], 
      WindowSize -> 280]
     ], {i, 5}]}]]

Here I have clicked on disk 4 twice, opening a duplicate of the information window. I want to prevent that:

enter image description here

  • $\begingroup$ Only idea I have is: You could give each PopupWindow title and then check every Notebooks[] every second or so to close duplicates? $\endgroup$
    – Ajasja
    Oct 30, 2012 at 11:57
  • $\begingroup$ You can define an index list for windows e.g. from 1 to 5. Before opening a window check if the index is still there in the list then remove the index and open the window else do nothing. $\endgroup$
    – s.s.o
    Oct 30, 2012 at 13:11
  • $\begingroup$ I don't think you can do that with PopoupWindow[], because once issued it will ever bring up a window with the specified contents. You can, however, create a notebook if it hasn't been created yet. You may use FE`Evaluate[FEPrivate`GetPopupList["MenuListWindows"]] to check the currently active notebooks. $\endgroup$ Oct 30, 2012 at 13:20
  • $\begingroup$ @belisarius, thanks. I'm not clear on what your code snippet gives that Notebooks[] doesn't? $\endgroup$ Oct 30, 2012 at 21:01
  • 1
    $\begingroup$ @YvesKlett, yes that's normal. You can change the behaviour with WindowFloating->False. $\endgroup$ Oct 31, 2012 at 8:58

1 Answer 1


The PopupWindow object is nothing more than a Button with a CreateDocument action:

PopupWindow[a, b] // InputForm

(* Button[a, CreateDocument[Internal`PopupWindowNotebook[b]], 
Appearance -> None, BaseStyle -> {}, DefaultBaseStyle -> {}] *)

Since CreateDocument returns a notebook object which can be assigned to a symbol, it is simple to check if there is an already open popup window. By inserting this check into the Button code, the desired behaviour is obtained:

singlePopup[pw_] := With[{p = Unique["popup"]},
  pw /. Button[a_, b_, c___] :>
    Button[a, If[! ValueQ[p] || Options[p] == $Failed, p = b], c]]

(* e.g. *) PopupWindow["Click here", "You clicked!"] // singlePopup
  • $\begingroup$ Very nice, a big +1 $\endgroup$ Oct 30, 2012 at 23:36
  • $\begingroup$ V11.3 appears to have broken this, so after poping up and then closing, you can no longer popup again. $\endgroup$
    – DrBubbles
    Mar 15, 2018 at 15:27
  • $\begingroup$ According to Wolfram support this is a bug and will be fixed in a future release. Options[NotebookObject["bad"]] will return an empty List, {}, instead of \$Failed. Support provided a workaround: Add Options[p] == {} to your If statement: singlePopup[pw_] := With[{p = Unique["popup"]}, pw /. Button[a_, b_, c___] :> Button[a, If[! ValueQ[p] || Options[p] == {} || Options[p] == $Failed, p = b], c]] $\endgroup$
    – DrBubbles
    Mar 20, 2018 at 14:45
  • $\begingroup$ @DrBubbles, thanks for the update. I actually ran across this today and changed Options to NotebookInformation which also worked. $\endgroup$ Mar 20, 2018 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.