diff --git a/src/org/openstreetmap/josm/actions/mapmode/MapMode.java b/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
index 3ad0d71e27..62383c04c7 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
@@ -20,6 +20,8 @@ import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Logging;
+import org.openstreetmap.josm.tools.PlatformHook;
+import org.openstreetmap.josm.tools.PlatformManager;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
@@ -33,6 +35,16 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
     protected boolean ctrl;
     protected boolean alt;
     protected boolean shift;
+    /**
+     * {@code true} if the meta key was pressed (the "Windows" key or the Mac "Command" key)
+     * @since xxx
+     */
+    protected boolean meta;
+    /**
+     * @see PlatformHook#getMenuShortcutKeyMaskEx()
+     * @since xxx
+     */
+    protected boolean platformMenuShortcutKeyMask;
 
     /**
      * Constructor for mapmodes without a menu
@@ -154,7 +166,7 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
     }
 
     /**
-     * Update internal ctrl, alt, shift mask from given extended modifiers mask.
+     * Update internal ctrl, alt, shift, meta mask from given extended modifiers mask.
      * @param modifiers event extended modifiers mask
      * @since 12517
      */
@@ -162,6 +174,8 @@ public abstract class MapMode extends JosmAction implements MouseListener, Mouse
         ctrl = (modifiers & InputEvent.CTRL_DOWN_MASK) != 0;
         alt = (modifiers & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK)) != 0;
         shift = (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
+        meta = (modifiers & InputEvent.META_DOWN_MASK) != 0;
+        platformMenuShortcutKeyMask = (modifiers & PlatformManager.getPlatform().getMenuShortcutKeyMaskEx()) != 0;
     }
 
     /**
diff --git a/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java b/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
index 6983b3d585..7d50a22ba3 100644
--- a/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
+++ b/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
@@ -287,7 +287,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             return repaintIfRequired(newHighlight);
 
         // CTRL toggles selection, but if while dragging CTRL means merge
-        final boolean isToggleMode = ctrl && !dragInProgress();
+        final boolean isToggleMode = platformMenuShortcutKeyMask && !dragInProgress();
         if (c.isPresent() && (isToggleMode || !c.get().isSelected())) {
             // only highlight primitives that will change the selection
             // when clicked. I.e. don't highlight selected elements unless
@@ -317,7 +317,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             if (dragInProgress()) {
                 // only consider merge if ctrl is pressed and there are nodes in
                 // the selection that could be merged
-                if (!ctrl || getLayerManager().getEditDataSet().getSelectedNodes().isEmpty()) {
+                if (!platformMenuShortcutKeyMask || getLayerManager().getEditDataSet().getSelectedNodes().isEmpty()) {
                     c = "move";
                     break;
                 }
@@ -332,7 +332,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             c = (osm instanceof Way) ? "way" : c;
             if (shift) {
                 c += "_add";
-            } else if (ctrl) {
+            } else if (platformMenuShortcutKeyMask) {
                 c += osm == null || osm.isSelected() ? "_rm" : "_add";
             }
             break;
@@ -346,7 +346,13 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             if (lassoMode) {
                 c = "lasso";
             } else {
-                c = "rect" + (shift ? "_add" : (ctrl && !PlatformManager.isPlatformOsx() ? "_rm" : ""));
+                if (shift) {
+                    c = "rect_add";
+                } else if (platformMenuShortcutKeyMask) {
+                    c = "rect_rm";
+                } else {
+                    c = "rect";
+                }
             }
             break;
         }
@@ -408,7 +414,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
 
         // We don't want to change to draw tool if the user tries to (de)select
         // stuff but accidentally clicks in an empty area when selection is empty
-        cancelDrawMode = shift || ctrl;
+        cancelDrawMode = shift || platformMenuShortcutKeyMask;
         didMouseDrag = false;
         initialMoveThresholdExceeded = false;
         mouseDownTime = System.currentTimeMillis();
@@ -513,7 +519,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
         if (mode == Mode.MOVE) {
             // If ctrl is pressed we are in merge mode. Look for a nearby node,
             // highlight it and adjust the cursor accordingly.
-            final boolean canMerge = ctrl && !getLayerManager().getEditDataSet().getSelectedNodes().isEmpty();
+            final boolean canMerge = platformMenuShortcutKeyMask && !getLayerManager().getEditDataSet().getSelectedNodes().isEmpty();
             final OsmPrimitive p = canMerge ? findNodeToMergeTo(e.getPoint()) : null;
             boolean needsRepaint = removeHighlighting();
             if (p != null) {
@@ -669,9 +675,9 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
      */
     private void determineMapMode(boolean hasSelectionNearby) {
         if (getLayerManager().getEditDataSet() != null) {
-            if (shift && ctrl) {
+            if (shift && platformMenuShortcutKeyMask) {
                 mode = Mode.ROTATE;
-            } else if (alt && ctrl) {
+            } else if (alt && platformMenuShortcutKeyMask) {
                 mode = Mode.SCALE;
             } else if (hasSelectionNearby || dragInProgress()) {
                 mode = Mode.MOVE;
@@ -860,7 +866,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
         } else {
             // if small number of elements were moved,
             updateKeyModifiers(e);
-            if (ctrl) mergePrims(e.getPoint());
+            if (platformMenuShortcutKeyMask) mergePrims(e.getPoint());
         }
     }
 
@@ -978,7 +984,8 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
         // Virtual Ways: if non-empty the cursor is above a virtual node. So don't highlight
         // anything if about to drag the virtual node (i.e. !released) but continue if the
         // cursor is only released above a virtual node by accident (i.e. released). See #7018
-        if (ds == null || (shift && ctrl) || (ctrl && !released) || (virtualManager.hasVirtualWaysToBeConstructed() && !released))
+        if (ds == null || (shift && platformMenuShortcutKeyMask) || (platformMenuShortcutKeyMask && !released)
+                || (virtualManager.hasVirtualWaysToBeConstructed() && !released))
             return;
 
         if (!released) {
@@ -988,7 +995,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             shift |= ds.getSelected().containsAll(prims);
         }
 
-        if (ctrl) {
+        if (platformMenuShortcutKeyMask) {
             // Ctrl on an item toggles its selection status,
             // but Ctrl on an *area* just clears those items
             // out of the selection.
@@ -1106,7 +1113,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
                         // special case:  for cycle groups of 2, we can toggle to the
                         // true nearest primitive on mousePressed right away
                         if (cycleList.size() == 2 && !waitForMouseUpParameter) {
-                            if (!(osm.equals(old) || osm.isNew() || ctrl)) {
+                            if (!(osm.equals(old) || osm.isNew() || platformMenuShortcutKeyMask)) {
                                 cyclePrims = false;
                                 osm = old;
                             } // else defer toggling to mouseRelease time in those cases:
@@ -1154,7 +1161,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
                     if (nxt.isSelected()) {
                         foundInDS = nxt;
                         // first selected primitive in cycleList is found
-                        if (cyclePrims || ctrl) {
+                        if (cyclePrims || platformMenuShortcutKeyMask) {
                             ds.clearSelection(foundInDS); // deselect it
                             nxt = i.hasNext() ? i.next() : first;
                             // return next one in cycle list (last->first)
@@ -1165,7 +1172,7 @@ public class SelectAction extends MapMode implements ModifierExListener, KeyPres
             }
 
             // if "no-alt-cycling" is enabled, Ctrl-Click arrives here.
-            if (ctrl) {
+            if (platformMenuShortcutKeyMask) {
                 // a member of cycleList was found in the current dataset selection
                 if (foundInDS != null) {
                     // mouse was moved to a different selection group w/ a previous sel
diff --git a/src/org/openstreetmap/josm/gui/SelectionManager.java b/src/org/openstreetmap/josm/gui/SelectionManager.java
index 602f4491f9..0f9e4a0e92 100644
--- a/src/org/openstreetmap/josm/gui/SelectionManager.java
+++ b/src/org/openstreetmap/josm/gui/SelectionManager.java
@@ -26,6 +26,7 @@ import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
 import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable;
 import org.openstreetmap.josm.tools.ColorHelper;
+import org.openstreetmap.josm.tools.PlatformManager;
 
 /**
  * Manages the selection of a rectangle or a lasso loop. Listening to left and right mouse button
@@ -185,7 +186,7 @@ public class SelectionManager implements MouseListener, MouseMotionListener, Pro
         if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1 && MainApplication.getLayerManager().getActiveDataSet() != null) {
             SelectByInternalPointAction.performSelection(MainApplication.getMap().mapView.getEastNorth(e.getX(), e.getY()),
                     (e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0,
-                    (e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0);
+                    (e.getModifiersEx() & PlatformManager.getPlatform().getMenuShortcutKeyMaskEx()) != 0);
         } else if (e.getButton() == MouseEvent.BUTTON1) {
             mousePosStart = mousePos = e.getPoint();
 
