diff --git a/src/GUI/qml/AircraftVariantChoice.qml b/src/GUI/qml/AircraftVariantChoice.qml
index 72366387f..43d564d7f 100644
--- a/src/GUI/qml/AircraftVariantChoice.qml
+++ b/src/GUI/qml/AircraftVariantChoice.qml
@@ -92,10 +92,9 @@ Rectangle {
                 screenPos = _launcher.mapToGlobal(title, Qt.point(0, 0))
             }
 
-            popupFrame.x = screenPos.x;
-            popupFrame.y = screenPos.y;
-            popupFrame.show()
-            tracker.window = popupFrame
+            var pop = popup.createObject(root, {x:screenPos.x, y:screenPos.y })
+            tracker.window = pop;
+            pop.show();
         }
     }
 
@@ -108,59 +107,63 @@ Rectangle {
         id: tracker
     }
 
-    Window {
-        id: popupFrame
+    Component {
+        id: popup
 
-        width: root.width
-        flags: Qt.Popup
-        height: choicesColumn.childrenRect.height
-        color: "white"
+        Window {
+            id: popupFrame
 
-        Rectangle {
-            border.width: 1
-            border.color: Style.minorFrameColor
-            anchors.fill: parent
-        }
+            width: root.width
+            flags: Qt.Popup
+            height: choicesColumn.childrenRect.height
+            color: "white"
 
-        Column {
-            id: choicesColumn
+            Rectangle {
+                border.width: 1
+                border.color: Style.minorFrameColor
+                anchors.fill: parent
+            }
 
-            Repeater {
-                // would prefer the model to be conditional on visiblity,
-                // but this trips up the Window sizing on Linux (Ubuntu at
-                // least) and we get a mis-aligned origin
-                model: aircraftInfo.variantNames
+            Column {
+                id: choicesColumn
 
-                delegate: Item {
-                    width: popupFrame.width
-                    height: choiceText.implicitHeight
+                Repeater {
+                    // would prefer the model to be conditional on visiblity,
+                    // but this trips up the Window sizing on Linux (Ubuntu at
+                    // least) and we get a mis-aligned origin
+                    model: aircraftInfo.variantNames
 
-                    Text {
-                        id: choiceText
-                        text: modelData
+                    delegate: Item {
+                        width: popupFrame.width
+                        height: choiceText.implicitHeight
 
-                        // allow override the size in case the title size is enormous
-                        font.pixelSize: (popupFontPixelSize > 0) ? popupFontPixelSize : title.font.pixelSize
+                        Text {
+                            id: choiceText
+                            text: modelData
 
-                        color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
-                        anchors {
-                            left: parent.left
-                            right: parent.right
-                            margins: 4
+                            // allow override the size in case the title size is enormous
+                            font.pixelSize: (root.popupFontPixelSize > 0) ? root.popupFontPixelSize : title.font.pixelSize
+
+                            color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
+                            anchors {
+                                left: parent.left
+                                right: parent.right
+                                margins: 4
+                            }
                         }
-                    }
 
-                    MouseArea {
-                        id: choiceArea
-                        hoverEnabled: true
-                        anchors.fill: parent
-                        onClicked: {
-                            popupFrame.hide()
-                            root.selected(model.index)
+                        MouseArea {
+                            id: choiceArea
+                            hoverEnabled: true
+                            anchors.fill: parent
+                            onClicked: {
+                                popupFrame.close()
+                                root.selected(model.index)
+                            }
                         }
-                    }
-                } // of delegate Item
-            } // of Repeater
-        }
-    } // of popup frame
+                    } // of delegate Item
+                } // of Repeater
+            }
+        } // of popup frame
+    } // of popup component
 }
diff --git a/src/GUI/qml/HistoryPopup.qml b/src/GUI/qml/HistoryPopup.qml
index a731fff39..83aa58a50 100644
--- a/src/GUI/qml/HistoryPopup.qml
+++ b/src/GUI/qml/HistoryPopup.qml
@@ -37,11 +37,12 @@ Item {
             hoverEnabled: root.enabled
             enabled: root.enabled
             onClicked: {
-                var screenPos = _launcher.mapToGlobal(button, Qt.point(-popupFrame.width, 0))
-                popupFrame.x = screenPos.x;
-                popupFrame.y = screenPos.y;
-                popupFrame.visible = true
-                tracker.window = popupFrame
+                var pop = popup.createObject(root)
+                var screenPos = _launcher.mapToGlobal(button, Qt.point(-pop.width, 0))
+                pop.y = screenPos.y;
+                pop.x = screenPos.x;
+                tracker.window = pop;
+                pop.show();
             }
         }
     }
@@ -50,51 +51,54 @@ Item {
         id: tracker
     }
 
-    Window {
-        id: popupFrame
+    Component {
+        id: popup
 
-        flags: Qt.Popup
-        height: choicesColumn.childrenRect.height + Style.margin * 2
-        width: choicesColumn.childrenRect.width + Style.margin * 2
-        visible: false
-        color: "white"
+        Window {
+            id: popupFrame
 
-        Rectangle {
-            border.width: 1
-            border.color: Style.minorFrameColor
-            anchors.fill: parent
-        }
+            flags: Qt.Popup
+            height: choicesColumn.childrenRect.height + Style.margin * 2
+            width: choicesColumn.childrenRect.width + Style.margin * 2
+            color: "white"
 
-        // text repeater
-        Column {
-            id: choicesColumn
-            spacing: Style.margin
-            x: Style.margin
-            y: Style.margin
+            Rectangle {
+                border.width: 1
+                border.color: Style.minorFrameColor
+                anchors.fill: parent
+            }
 
-            Repeater {
-                id: choicesRepeater
-                model: root.model
-                delegate:
-                    StyledText {
-                        id: choiceText
+            // text repeater
+            Column {
+                id: choicesColumn
+                spacing: Style.margin
+                x: Style.margin
+                y: Style.margin
 
-                        // Taken from TableViewItemDelegateLoader.qml to follow QML role conventions
-                        text: model && model.hasOwnProperty(displayRole) ? model[displayRole] // Qml ListModel and QAbstractItemModel
-                                                                         : modelData && modelData.hasOwnProperty(displayRole) ? modelData[displayRole] // QObjectList / QObject
-                                                                                                                              : modelData != undefined ? modelData : "" // Models without role
-                        height: implicitHeight + Style.margin
+                Repeater {
+                    id: choicesRepeater
+                    model: root.model
+                    delegate:
+                        StyledText {
+                            id: choiceText
 
-                        MouseArea {
-                            width: popupFrame.width // full width of the popup
-                            height: parent.height
-                            onClicked: {
-                                popupFrame.visible = false
-                                root.selected(model.index);
+                            // Taken from TableViewItemDelegateLoader.qml to follow QML role conventions
+                            text: model && model.hasOwnProperty(displayRole) ? model[displayRole] // Qml ListModel and QAbstractItemModel
+                                                                             : modelData && modelData.hasOwnProperty(displayRole) ? modelData[displayRole] // QObjectList / QObject
+                                                                                                                                  : modelData != undefined ? modelData : "" // Models without role
+                            height: implicitHeight + Style.margin
+
+                            MouseArea {
+                                width: popupFrame.width // full width of the popup
+                                height: parent.height
+                                onClicked: {
+                                    root.selected(model.index);
+                                    popupFrame.close()
+                                }
                             }
-                        }
-                    } // of Text delegate
-            } // text repeater
-        } // text column
-    } // of popup Window
+                        } // of Text delegate
+                } // text repeater
+            } // text column
+        } // of popup Window
+    }
 }
diff --git a/src/GUI/qml/NumericalEdit.qml b/src/GUI/qml/NumericalEdit.qml
index 6bc417b5a..8cb3d934f 100644
--- a/src/GUI/qml/NumericalEdit.qml
+++ b/src/GUI/qml/NumericalEdit.qml
@@ -101,6 +101,15 @@ FocusScope {
         }
     }
 
+    function showUnitsMenu()
+    {
+
+        var screenPos = _launcher.mapToGlobal(editFrame, Qt.point(0, editFrame.height))
+        var pop = popup.createObject(root, {x:screenPos.x, y:screenPos.y })
+        tracker.window = pop;
+        pop.show();
+    }
+
     Component.onCompleted: {
         // ensure any initial value is accepted by our mode.
         // this stops people passing in completely wrong quantities
@@ -196,7 +205,7 @@ FocusScope {
             anchors.left: parent.left
             anchors.margins: Style.margin
             text: visible ? units.shortText : ""
-            onClicked: unitSelectionPopup.show()
+            onClicked: root.showUnitsMenu()
             clickable: (units.numChoices > 1)
         }
 
@@ -251,7 +260,7 @@ FocusScope {
             anchors.baseline: edit.baseline
             anchors.right: upDownArea.left
             text: visible ? units.shortText : ""
-            onClicked: unitSelectionPopup.show()
+            onClicked: root.showUnitsMenu();
             clickable: (units.numChoices > 1)
         }
 
@@ -324,76 +333,69 @@ FocusScope {
         id: tracker
     }
 
-    Window {
-        id: unitSelectionPopup
-        visible: false
-        flags: Qt.Popup
-        color: "white"
-        height: choicesColumn.childrenRect.height + Style.margin * 2
-        width: choicesColumn.width + Style.margin * 2
+    Component {
+        id: popup
+        Window {
+            id: unitSelectionPopup
+            flags: Qt.Popup
+            color: "white"
+            height: choicesColumn.childrenRect.height + Style.margin * 2
+            width: choicesColumn.width + Style.margin * 2
 
-        function show()
-        {
-            var screenPos = _launcher.mapToGlobal(editFrame, Qt.point(0, editFrame.height))
-            unitSelectionPopup.x = screenPos.x;
-            unitSelectionPopup.y = screenPos.y;
-            unitSelectionPopup.visible = true
-            tracker.window = unitSelectionPopup
-        }
-
-        Rectangle {
-            border.width: 1
-            border.color: Style.minorFrameColor
-            anchors.fill: parent
-        }
-
-        // choice layout column
-        Column {
-            id: choicesColumn
-            spacing: Style.margin
-            x: Style.margin
-            y: Style.margin
-            width: menuWidth
-
-
-            function calculateMenuWidth()
-            {
-                var minWidth = 0;
-                for (var i = 0; i < choicesRepeater.count; i++) {
-                    minWidth = Math.max(minWidth, choicesRepeater.itemAt(i).implicitWidth);
-                }
-                return minWidth;
+            Rectangle {
+                border.width: 1
+                border.color: Style.minorFrameColor
+                anchors.fill: parent
             }
 
-            readonly property int menuWidth: calculateMenuWidth()
+            // choice layout column
+            Column {
+                id: choicesColumn
+                spacing: Style.margin
+                x: Style.margin
+                y: Style.margin
+                width: menuWidth
 
-            // main item repeater
-            Repeater {
-                id: choicesRepeater
-                model: units
-                delegate:
-                    Text {
-                        id: choiceText
-                        readonly property bool selected: units.selectedIndex === model.index
 
-                        text: model.longName
-                        height: implicitHeight + Style.margin
-                        font.pixelSize: Style.baseFontPixelSize
-                        color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
+                function calculateMenuWidth()
+                {
+                    var minWidth = 0;
+                    for (var i = 0; i < choicesRepeater.count; i++) {
+                        minWidth = Math.max(minWidth, choicesRepeater.itemAt(i).implicitWidth);
+                    }
+                    return minWidth;
+                }
 
-                        MouseArea {
-                            id: choiceArea
-                            width: unitSelectionPopup.width // full width of the popup
-                            height: parent.height
-                            hoverEnabled: true
+                readonly property int menuWidth: calculateMenuWidth()
 
-                            onClicked: {
-                                root.changeToUnits(model.index);
-                                unitSelectionPopup.visible = false;
+                // main item repeater
+                Repeater {
+                    id: choicesRepeater
+                    model: units
+                    delegate:
+                        Text {
+                            id: choiceText
+                            readonly property bool selected: units.selectedIndex === model.index
+
+                            text: model.longName
+                            height: implicitHeight + Style.margin
+                            font.pixelSize: Style.baseFontPixelSize
+                            color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
+
+                            MouseArea {
+                                id: choiceArea
+                                width: unitSelectionPopup.width // full width of the popup
+                                height: parent.height
+                                hoverEnabled: true
+
+                                onClicked: {
+                                    root.changeToUnits(model.index);
+                                    unitSelectionPopup.close();
+                                }
                             }
-                        }
-                    } // of Text delegate
-            } // text repeater
-        } // text column
-    }
+                        } // of Text delegate
+                } // text repeater
+            } // text column
+        }
+    } // of popup component
 }