diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 4e381e83a3..dbac461e49 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -37536,8 +37536,7 @@ AudioProcessorGraph::Node* AudioProcessorGraph::getNodeForId (const uint32 nodeI return nullptr; } -AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor, - uint32 nodeId) +AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor, uint32 nodeId) { if (newProcessor == nullptr) { @@ -37554,9 +37553,10 @@ AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const n // you can't add a node with an id that already exists in the graph.. jassert (getNodeForId (nodeId) == nullptr); removeNode (nodeId); - } - lastNodeId = nodeId; + if (nodeId > lastNodeId) + lastNodeId = nodeId; + } Node* const n = new Node (nodeId, newProcessor); nodes.add (n); @@ -40943,13 +40943,13 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo) { WeakReference safePointer (this); -#if JUCE_LINUX + #if JUCE_LINUX // it's wise to give the component a non-zero size before // putting it on the desktop, as X windows get confused by this, and // a (1, 1) minimum size is enforced here. setSize (jmax (1, getWidth()), jmax (1, getHeight())); -#endif + #endif const Point topLeft (getScreenPosition()); @@ -63127,7 +63127,7 @@ BEGIN_JUCE_NAMESPACE ComponentMovementWatcher::ComponentMovementWatcher (Component* const component_) : component (component_), - lastPeer (nullptr), + lastPeerID (0), reentrant (false), wasShowing (component_->isShowing()) { @@ -63153,15 +63153,16 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) const ScopedValueSetter setter (reentrant, true); ComponentPeer* const peer = component->getPeer(); + const uint32 peerID = peer != nullptr ? peer->getUniqueID() : 0; - if (peer != lastPeer) + if (peerID != lastPeerID) { componentPeerChanged(); if (component == nullptr) return; - lastPeer = peer; + lastPeerID = peerID; } unregister(); @@ -70439,7 +70440,9 @@ public: } resizeToBestWindowPos(); - addToDesktop (ComponentPeer::windowIsTemporary | getLookAndFeel().getMenuWindowFlags()); + addToDesktop (ComponentPeer::windowIsTemporary + | ComponentPeer::windowIgnoresKeyPresses + | getLookAndFeel().getMenuWindowFlags()); getActiveWindows().add (this); Desktop::getInstance().addGlobalMouseListener (this); @@ -70983,7 +70986,7 @@ private: for (int col = 0; col < numColumns; ++col) { - int i, colW = 50, colH = 0; + int i, colW = standardItemHeight, colH = 0; const int numChildren = jmin (items.size() - childNum, (items.size() + numColumns - 1) / numColumns); @@ -78530,6 +78533,7 @@ BEGIN_JUCE_NAMESPACE //#define JUCE_ENABLE_REPAINT_DEBUGGING 1 static Array heavyweightPeers; +static uint32 lastUniqueID = 1; ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_) : component (component_), @@ -78537,6 +78541,7 @@ ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_ lastPaintTime (0), constrainer (nullptr), lastDragAndDropCompUnderMouse (nullptr), + uniqueID (lastUniqueID += 2), // increment by 2 so that this can never hit 0 fakeMouseMessageSent (false), isWindowMinimised (false) { @@ -78546,7 +78551,6 @@ ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_ ComponentPeer::~ComponentPeer() { heavyweightPeers.removeValue (this); - Desktop::getInstance().triggerFocusCallback(); } @@ -78603,9 +78607,9 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) { Graphics g (&contextToPaintTo); - #if JUCE_ENABLE_REPAINT_DEBUGGING + #if JUCE_ENABLE_REPAINT_DEBUGGING g.saveState(); - #endif + #endif JUCE_TRY { @@ -78613,7 +78617,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) } JUCE_CATCH_EXCEPTION - #if JUCE_ENABLE_REPAINT_DEBUGGING + #if JUCE_ENABLE_REPAINT_DEBUGGING // enabling this code will fill all areas that get repainted with a colour overlay, to show // clearly when things are being repainted. g.restoreState(); @@ -78622,7 +78626,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) (uint8) Random::getSystemRandom().nextInt (255), (uint8) Random::getSystemRandom().nextInt (255), (uint8) 0x50)); - #endif + #endif /** If this fails, it's probably be because your CPU floating-point precision mode has been set to low.. This setting is sometimes changed by things like Direct3D, and can @@ -274275,6 +274279,9 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons { UITouch* touch = [touches objectAtIndex: i]; + if ([touch phase] == UITouchPhaseStationary) + continue; + CGPoint p = [touch locationInView: view]; const Point pos ((int) p.x, (int) p.y); juce_lastMousePos = pos + getScreenPosition(); @@ -274292,14 +274299,27 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons currentTouches.set (touchIndex, touch); } + ModifierKeys modsToSend (currentModifiers); + if (isDown) { - currentModifiers = currentModifiers.withoutMouseButtons(); - handleMouseEvent (touchIndex, pos, currentModifiers, time); + if ([touch phase] != UITouchPhaseBegan) + continue; + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + modsToSend = currentModifiers; + + // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. + handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), time); + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return; } else if (isUp) { + if (! ([touch phase] == UITouchPhaseEnded || [touch phase] == UITouchPhaseCancelled)) + continue; + + modsToSend = modsToSend.withoutMouseButtons(); currentTouches.set (touchIndex, nil); int totalActiveTouches = 0; @@ -274317,7 +274337,16 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons currentModifiers = currentModifiers.withoutMouseButtons(); } - handleMouseEvent (touchIndex, pos, currentModifiers, time); + handleMouseEvent (touchIndex, pos, modsToSend, time); + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return; + + if (isUp || isCancel) + { + handleMouseEvent (touchIndex, Point (-1, -1), currentModifiers, time); + if (! isValidPeer (this)) + return; + } } } @@ -274347,7 +274376,7 @@ void UIViewComponentPeer::viewFocusLoss() void juce_HandleProcessFocusChange() { - if (UIViewComponentPeer::isValidPeer (currentlyFocusedPeer)) + if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) { if (Process::isForegroundProcess()) { diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 2a78f0328c..6e98f5410f 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 84 +#define JUCE_BUILDNUMBER 85 /** Current Juce version number. @@ -58912,7 +58912,7 @@ public: private: WeakReference component; - ComponentPeer* lastPeer; + uint32 lastPeerID; Array registeredParentComps; bool reentrant, wasShowing; Rectangle lastBounds; @@ -64972,6 +64972,11 @@ public: */ int getStyleFlags() const noexcept { return styleFlags; } + /** Returns a unique ID for this peer. + Each peer that is created is given a different ID. + */ + uint32 getUniqueID() const noexcept { return uniqueID; } + /** Returns the raw handle to whatever kind of window is being used. On windows, this is probably a HWND, on the mac, it's likely to be a WindowRef, @@ -65231,6 +65236,7 @@ private: WeakReference lastFocusedComponent, dragAndDropTargetComponent; Component* lastDragAndDropCompUnderMouse; + const uint32 uniqueID; bool fakeMouseMessageSent : 1, isWindowMinimised : 1; friend class Component; diff --git a/src/audio/processors/juce_AudioProcessorGraph.cpp b/src/audio/processors/juce_AudioProcessorGraph.cpp index c5ed232621..0d73dc65d3 100644 --- a/src/audio/processors/juce_AudioProcessorGraph.cpp +++ b/src/audio/processors/juce_AudioProcessorGraph.cpp @@ -965,8 +965,7 @@ AudioProcessorGraph::Node* AudioProcessorGraph::getNodeForId (const uint32 nodeI return nullptr; } -AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor, - uint32 nodeId) +AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const newProcessor, uint32 nodeId) { if (newProcessor == nullptr) { @@ -983,9 +982,10 @@ AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const n // you can't add a node with an id that already exists in the graph.. jassert (getNodeForId (nodeId) == nullptr); removeNode (nodeId); - } - lastNodeId = nodeId; + if (nodeId > lastNodeId) + lastNodeId = nodeId; + } Node* const n = new Node (nodeId, newProcessor); nodes.add (n); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index b1f6a8eacb..2cf018da5c 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 84 +#define JUCE_BUILDNUMBER 85 /** Current Juce version number. diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index 4a5e9bb5d7..89b4548343 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -593,13 +593,13 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo) { WeakReference safePointer (this); -#if JUCE_LINUX + #if JUCE_LINUX // it's wise to give the component a non-zero size before // putting it on the desktop, as X windows get confused by this, and // a (1, 1) minimum size is enforced here. setSize (jmax (1, getWidth()), jmax (1, getHeight())); -#endif + #endif const Point topLeft (getScreenPosition()); diff --git a/src/gui/components/layout/juce_ComponentMovementWatcher.cpp b/src/gui/components/layout/juce_ComponentMovementWatcher.cpp index 2bab1057c2..ff0376e69a 100644 --- a/src/gui/components/layout/juce_ComponentMovementWatcher.cpp +++ b/src/gui/components/layout/juce_ComponentMovementWatcher.cpp @@ -29,12 +29,13 @@ BEGIN_JUCE_NAMESPACE #include "juce_ComponentMovementWatcher.h" #include "../../../containers/juce_ScopedValueSetter.h" +#include "../windows/juce_ComponentPeer.h" //============================================================================== ComponentMovementWatcher::ComponentMovementWatcher (Component* const component_) : component (component_), - lastPeer (nullptr), + lastPeerID (0), reentrant (false), wasShowing (component_->isShowing()) { @@ -61,15 +62,16 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) const ScopedValueSetter setter (reentrant, true); ComponentPeer* const peer = component->getPeer(); + const uint32 peerID = peer != nullptr ? peer->getUniqueID() : 0; - if (peer != lastPeer) + if (peerID != lastPeerID) { componentPeerChanged(); if (component == nullptr) return; - lastPeer = peer; + lastPeerID = peerID; } unregister(); diff --git a/src/gui/components/layout/juce_ComponentMovementWatcher.h b/src/gui/components/layout/juce_ComponentMovementWatcher.h index 64daf377bc..945f5d17da 100644 --- a/src/gui/components/layout/juce_ComponentMovementWatcher.h +++ b/src/gui/components/layout/juce_ComponentMovementWatcher.h @@ -80,7 +80,7 @@ public: private: //============================================================================== WeakReference component; - ComponentPeer* lastPeer; + uint32 lastPeerID; Array registeredParentComps; bool reentrant, wasShowing; Rectangle lastBounds; diff --git a/src/gui/components/menus/juce_PopupMenu.cpp b/src/gui/components/menus/juce_PopupMenu.cpp index 1da10e9c26..03c411563f 100644 --- a/src/gui/components/menus/juce_PopupMenu.cpp +++ b/src/gui/components/menus/juce_PopupMenu.cpp @@ -297,7 +297,9 @@ public: } resizeToBestWindowPos(); - addToDesktop (ComponentPeer::windowIsTemporary | getLookAndFeel().getMenuWindowFlags()); + addToDesktop (ComponentPeer::windowIsTemporary + | ComponentPeer::windowIgnoresKeyPresses + | getLookAndFeel().getMenuWindowFlags()); getActiveWindows().add (this); Desktop::getInstance().addGlobalMouseListener (this); @@ -849,7 +851,7 @@ private: for (int col = 0; col < numColumns; ++col) { - int i, colW = 50, colH = 0; + int i, colW = standardItemHeight, colH = 0; const int numChildren = jmin (items.size() - childNum, (items.size() + numColumns - 1) / numColumns); diff --git a/src/gui/components/windows/juce_ComponentPeer.cpp b/src/gui/components/windows/juce_ComponentPeer.cpp index d033c6a09a..a1eaddd928 100644 --- a/src/gui/components/windows/juce_ComponentPeer.cpp +++ b/src/gui/components/windows/juce_ComponentPeer.cpp @@ -42,7 +42,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== static Array heavyweightPeers; - +static uint32 lastUniqueID = 1; //============================================================================== ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_) @@ -51,6 +51,7 @@ ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_ lastPaintTime (0), constrainer (nullptr), lastDragAndDropCompUnderMouse (nullptr), + uniqueID (lastUniqueID += 2), // increment by 2 so that this can never hit 0 fakeMouseMessageSent (false), isWindowMinimised (false) { @@ -60,7 +61,6 @@ ComponentPeer::ComponentPeer (Component* const component_, const int styleFlags_ ComponentPeer::~ComponentPeer() { heavyweightPeers.removeValue (this); - Desktop::getInstance().triggerFocusCallback(); } @@ -120,9 +120,9 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) { Graphics g (&contextToPaintTo); - #if JUCE_ENABLE_REPAINT_DEBUGGING + #if JUCE_ENABLE_REPAINT_DEBUGGING g.saveState(); - #endif + #endif JUCE_TRY { @@ -130,7 +130,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) } JUCE_CATCH_EXCEPTION - #if JUCE_ENABLE_REPAINT_DEBUGGING + #if JUCE_ENABLE_REPAINT_DEBUGGING // enabling this code will fill all areas that get repainted with a colour overlay, to show // clearly when things are being repainted. g.restoreState(); @@ -139,7 +139,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) (uint8) Random::getSystemRandom().nextInt (255), (uint8) Random::getSystemRandom().nextInt (255), (uint8) 0x50)); - #endif + #endif /** If this fails, it's probably be because your CPU floating-point precision mode has been set to low.. This setting is sometimes changed by things like Direct3D, and can diff --git a/src/gui/components/windows/juce_ComponentPeer.h b/src/gui/components/windows/juce_ComponentPeer.h index 505ff8cefd..c739d5614e 100644 --- a/src/gui/components/windows/juce_ComponentPeer.h +++ b/src/gui/components/windows/juce_ComponentPeer.h @@ -103,6 +103,10 @@ public: */ int getStyleFlags() const noexcept { return styleFlags; } + /** Returns a unique ID for this peer. + Each peer that is created is given a different ID. + */ + uint32 getUniqueID() const noexcept { return uniqueID; } //============================================================================== /** Returns the raw handle to whatever kind of window is being used. @@ -374,6 +378,7 @@ private: //============================================================================== WeakReference lastFocusedComponent, dragAndDropTargetComponent; Component* lastDragAndDropCompUnderMouse; + const uint32 uniqueID; bool fakeMouseMessageSent : 1, isWindowMinimised : 1; friend class Component; diff --git a/src/native/mac/juce_ios_UIViewComponentPeer.mm b/src/native/mac/juce_ios_UIViewComponentPeer.mm index de01eeba37..573e0de7cf 100644 --- a/src/native/mac/juce_ios_UIViewComponentPeer.mm +++ b/src/native/mac/juce_ios_UIViewComponentPeer.mm @@ -735,6 +735,9 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons { UITouch* touch = [touches objectAtIndex: i]; + if ([touch phase] == UITouchPhaseStationary) + continue; + CGPoint p = [touch locationInView: view]; const Point pos ((int) p.x, (int) p.y); juce_lastMousePos = pos + getScreenPosition(); @@ -752,14 +755,27 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons currentTouches.set (touchIndex, touch); } + ModifierKeys modsToSend (currentModifiers); + if (isDown) { - currentModifiers = currentModifiers.withoutMouseButtons(); - handleMouseEvent (touchIndex, pos, currentModifiers, time); + if ([touch phase] != UITouchPhaseBegan) + continue; + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + modsToSend = currentModifiers; + + // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. + handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), time); + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return; } else if (isUp) { + if (! ([touch phase] == UITouchPhaseEnded || [touch phase] == UITouchPhaseCancelled)) + continue; + + modsToSend = modsToSend.withoutMouseButtons(); currentTouches.set (touchIndex, nil); int totalActiveTouches = 0; @@ -777,7 +793,16 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons currentModifiers = currentModifiers.withoutMouseButtons(); } - handleMouseEvent (touchIndex, pos, currentModifiers, time); + handleMouseEvent (touchIndex, pos, modsToSend, time); + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return; + + if (isUp || isCancel) + { + handleMouseEvent (touchIndex, Point (-1, -1), currentModifiers, time); + if (! isValidPeer (this)) + return; + } } } @@ -808,7 +833,7 @@ void UIViewComponentPeer::viewFocusLoss() void juce_HandleProcessFocusChange() { - if (UIViewComponentPeer::isValidPeer (currentlyFocusedPeer)) + if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) { if (Process::isForegroundProcess()) {