- Library code update
- project update (added Eigen) git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@94 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -43,7 +43,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en
|
||||
|
||||
JUCEApplicationBase* app = JUCEApplicationBase::createInstance();
|
||||
if (! app->initialiseApp())
|
||||
exit (0);
|
||||
exit (app->getApplicationReturnValue());
|
||||
|
||||
jassert (MessageManager::getInstance()->isThisTheMessageThread());
|
||||
}
|
||||
@@ -91,7 +91,7 @@ DECLARE_JNI_CLASS (CanvasMinimal, "android/graphics/Canvas");
|
||||
METHOD (hasFocus, "hasFocus", "()Z") \
|
||||
METHOD (invalidate, "invalidate", "(IIII)V") \
|
||||
METHOD (containsPoint, "containsPoint", "(II)Z") \
|
||||
METHOD (showKeyboard, "showKeyboard", "(Z)V") \
|
||||
METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \
|
||||
METHOD (createGLView, "createGLView", "()L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$OpenGLView;") \
|
||||
|
||||
DECLARE_JNI_CLASS (ComponentPeerView, JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView");
|
||||
@@ -234,14 +234,14 @@ public:
|
||||
view.callIntMethod (ComponentPeerView.getTop));
|
||||
}
|
||||
|
||||
Point<int> localToGlobal (Point<int> relativePosition) override
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override
|
||||
{
|
||||
return relativePosition + getScreenPosition();
|
||||
return relativePosition + getScreenPosition().toFloat();
|
||||
}
|
||||
|
||||
Point<int> globalToLocal (Point<int> screenPosition) override
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override
|
||||
{
|
||||
return screenPosition - getScreenPosition();
|
||||
return screenPosition - getScreenPosition().toFloat();
|
||||
}
|
||||
|
||||
void setMinimised (bool shouldBeMinimised) override
|
||||
@@ -320,7 +320,7 @@ public:
|
||||
lastMousePos = pos;
|
||||
|
||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
||||
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons(), time);
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time);
|
||||
|
||||
if (isValidPeer (this))
|
||||
handleMouseDragCallback (index, pos, time);
|
||||
@@ -333,8 +333,8 @@ public:
|
||||
jassert (index < 64);
|
||||
touchesDown = (touchesDown | (1 << (index & 63)));
|
||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
|
||||
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons()
|
||||
.withFlags (ModifierKeys::leftButtonModifier), time);
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons()
|
||||
.withFlags (ModifierKeys::leftButtonModifier), time);
|
||||
}
|
||||
|
||||
void handleMouseUpCallback (int index, Point<float> pos, int64 time)
|
||||
@@ -347,7 +347,7 @@ public:
|
||||
if (touchesDown == 0)
|
||||
currentModifiers = currentModifiers.withoutMouseButtons();
|
||||
|
||||
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons(), time);
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time);
|
||||
}
|
||||
|
||||
void handleKeyDownCallback (int k, int kc)
|
||||
@@ -378,14 +378,30 @@ public:
|
||||
handleFocusLoss();
|
||||
}
|
||||
|
||||
void textInputRequired (const Point<int>&) override
|
||||
static const char* getVirtualKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept
|
||||
{
|
||||
view.callVoidMethod (ComponentPeerView.showKeyboard, true);
|
||||
switch (type)
|
||||
{
|
||||
case TextInputTarget::textKeyboard: return "text";
|
||||
case TextInputTarget::numericKeyboard: return "number";
|
||||
case TextInputTarget::urlKeyboard: return "textUri";
|
||||
case TextInputTarget::emailAddressKeyboard: return "textEmailAddress";
|
||||
case TextInputTarget::phoneNumberKeyboard: return "phone";
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return "text";
|
||||
}
|
||||
|
||||
void textInputRequired (Point<int>, TextInputTarget& target) override
|
||||
{
|
||||
view.callVoidMethod (ComponentPeerView.showKeyboard,
|
||||
javaString (getVirtualKeyboardType (target.getKeyboardType())).get());
|
||||
}
|
||||
|
||||
void dismissPendingTextInput() override
|
||||
{
|
||||
view.callVoidMethod (ComponentPeerView.showKeyboard, false);
|
||||
view.callVoidMethod (ComponentPeerView.showKeyboard, javaString ("").get());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -595,12 +611,12 @@ bool MouseInputSource::SourceList::addSource()
|
||||
return true;
|
||||
}
|
||||
|
||||
Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
return AndroidComponentPeer::lastMousePos.toInt();
|
||||
return AndroidComponentPeer::lastMousePos;
|
||||
}
|
||||
|
||||
void MouseInputSource::setRawMousePosition (Point<int>)
|
||||
void MouseInputSource::setRawMousePosition (Point<float>)
|
||||
{
|
||||
// not needed
|
||||
}
|
||||
|
||||
@@ -24,6 +24,14 @@
|
||||
|
||||
class UIViewComponentPeer;
|
||||
|
||||
// The way rotation works changed in iOS8..
|
||||
static bool isUsingOldRotationMethod() noexcept
|
||||
{
|
||||
static bool isPreV8 = ([[[UIDevice currentDevice] systemVersion] compare: @"8.0"
|
||||
options: NSNumericSearch] == NSOrderedAscending);
|
||||
return isPreV8;
|
||||
}
|
||||
|
||||
namespace Orientations
|
||||
{
|
||||
static Desktop::DisplayOrientation convertToJuce (UIInterfaceOrientation orientation)
|
||||
@@ -42,12 +50,15 @@ namespace Orientations
|
||||
|
||||
static CGAffineTransform getCGTransformFor (const Desktop::DisplayOrientation orientation) noexcept
|
||||
{
|
||||
switch (orientation)
|
||||
if (isUsingOldRotationMethod())
|
||||
{
|
||||
case Desktop::upsideDown: return CGAffineTransformMake (-1, 0, 0, -1, 0, 0);
|
||||
case Desktop::rotatedClockwise: return CGAffineTransformMake (0, -1, 1, 0, 0, 0);
|
||||
case Desktop::rotatedAntiClockwise: return CGAffineTransformMake (0, 1, -1, 0, 0, 0);
|
||||
default: break;
|
||||
switch (orientation)
|
||||
{
|
||||
case Desktop::upsideDown: return CGAffineTransformMake (-1, 0, 0, -1, 0, 0);
|
||||
case Desktop::rotatedClockwise: return CGAffineTransformMake (0, -1, 1, 0, 0, 0);
|
||||
case Desktop::rotatedAntiClockwise: return CGAffineTransformMake (0, 1, -1, 0, 0, 0);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return CGAffineTransformIdentity;
|
||||
@@ -85,10 +96,10 @@ using namespace juce;
|
||||
|
||||
- (void) drawRect: (CGRect) r;
|
||||
|
||||
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
- (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event;
|
||||
|
||||
- (BOOL) becomeFirstResponder;
|
||||
- (BOOL) resignFirstResponder;
|
||||
@@ -106,6 +117,7 @@ using namespace juce;
|
||||
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation;
|
||||
- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration: (NSTimeInterval) duration;
|
||||
- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation;
|
||||
- (void) viewWillTransitionToSize: (CGSize) size withTransitionCoordinator: (id<UIViewControllerTransitionCoordinator>) coordinator;
|
||||
|
||||
- (void) viewDidLoad;
|
||||
- (void) viewWillAppear: (BOOL) animated;
|
||||
@@ -145,8 +157,8 @@ public:
|
||||
|
||||
Rectangle<int> getBounds() const override { return getBounds (! isSharedWindow); }
|
||||
Rectangle<int> getBounds (bool global) const;
|
||||
Point<int> localToGlobal (Point<int> relativePosition) override;
|
||||
Point<int> globalToLocal (Point<int> screenPosition) override;
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override;
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override;
|
||||
void setAlpha (float newAlpha) override;
|
||||
void setMinimised (bool) override {}
|
||||
bool isMinimised() const override { return false; }
|
||||
@@ -168,7 +180,7 @@ public:
|
||||
void viewFocusLoss();
|
||||
bool isFocused() const override;
|
||||
void grabFocus() override;
|
||||
void textInputRequired (const Point<int>&) override;
|
||||
void textInputRequired (Point<int>, TextInputTarget&) override;
|
||||
|
||||
BOOL textViewReplaceCharacters (Range<int>, const String&);
|
||||
void updateHiddenTextContent (TextInputTarget*);
|
||||
@@ -189,7 +201,7 @@ public:
|
||||
bool isSharedWindow, fullScreen, insideDrawRect;
|
||||
static ModifierKeys currentModifiers;
|
||||
|
||||
static int64 getMouseTime (UIEvent* e)
|
||||
static int64 getMouseTime (UIEvent* e) noexcept
|
||||
{
|
||||
return (Time::currentTimeMillis() - Time::getMillisecondCounter())
|
||||
+ (int64) ([e timestamp] * 1000.0);
|
||||
@@ -197,26 +209,29 @@ public:
|
||||
|
||||
static Rectangle<int> rotatedScreenPosToReal (const Rectangle<int>& r)
|
||||
{
|
||||
const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds));
|
||||
|
||||
switch ([[UIApplication sharedApplication] statusBarOrientation])
|
||||
if (isUsingOldRotationMethod())
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
return r;
|
||||
const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds));
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
|
||||
r.getWidth(), r.getHeight());
|
||||
switch ([[UIApplication sharedApplication] statusBarOrientation])
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
return r;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
return Rectangle<int> (r.getY(), screen.getHeight() - r.getRight(),
|
||||
r.getHeight(), r.getWidth());
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
|
||||
r.getWidth(), r.getHeight());
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
return Rectangle<int> (screen.getWidth() - r.getBottom(), r.getX(),
|
||||
r.getHeight(), r.getWidth());
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
return Rectangle<int> (r.getY(), screen.getHeight() - r.getRight(),
|
||||
r.getHeight(), r.getWidth());
|
||||
|
||||
default: jassertfalse; // unknown orientation!
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
return Rectangle<int> (screen.getWidth() - r.getBottom(), r.getX(),
|
||||
r.getHeight(), r.getWidth());
|
||||
|
||||
default: jassertfalse; // unknown orientation!
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -224,26 +239,29 @@ public:
|
||||
|
||||
static Rectangle<int> realScreenPosToRotated (const Rectangle<int>& r)
|
||||
{
|
||||
const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds));
|
||||
|
||||
switch ([[UIApplication sharedApplication] statusBarOrientation])
|
||||
if (isUsingOldRotationMethod())
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
return r;
|
||||
const Rectangle<int> screen (convertToRectInt ([UIScreen mainScreen].bounds));
|
||||
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
|
||||
r.getWidth(), r.getHeight());
|
||||
switch ([[UIApplication sharedApplication] statusBarOrientation])
|
||||
{
|
||||
case UIInterfaceOrientationPortrait:
|
||||
return r;
|
||||
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
return Rectangle<int> (screen.getHeight() - r.getBottom(), r.getX(),
|
||||
r.getHeight(), r.getWidth());
|
||||
case UIInterfaceOrientationPortraitUpsideDown:
|
||||
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
|
||||
r.getWidth(), r.getHeight());
|
||||
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
return Rectangle<int> (r.getY(), screen.getWidth() - r.getRight(),
|
||||
r.getHeight(), r.getWidth());
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
return Rectangle<int> (screen.getHeight() - r.getBottom(), r.getX(),
|
||||
r.getHeight(), r.getWidth());
|
||||
|
||||
default: jassertfalse; // unknown orientation!
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
return Rectangle<int> (r.getY(), screen.getWidth() - r.getRight(),
|
||||
r.getHeight(), r.getWidth());
|
||||
|
||||
default: jassertfalse; // unknown orientation!
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -273,6 +291,13 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
static void sendScreenBoundsUpdate (JuceUIViewController* c)
|
||||
{
|
||||
JuceUIView* juceView = (JuceUIView*) [c view];
|
||||
jassert (juceView != nil && juceView->owner != nullptr);
|
||||
juceView->owner->updateTransformAndScreenBounds();
|
||||
}
|
||||
|
||||
} // (juce namespace)
|
||||
|
||||
//==============================================================================
|
||||
@@ -301,19 +326,23 @@ private:
|
||||
- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation
|
||||
{
|
||||
(void) fromInterfaceOrientation;
|
||||
|
||||
JuceUIView* juceView = (JuceUIView*) [self view];
|
||||
jassert (juceView != nil && juceView->owner != nullptr);
|
||||
juceView->owner->updateTransformAndScreenBounds();
|
||||
|
||||
sendScreenBoundsUpdate (self);
|
||||
[UIView setAnimationsEnabled: YES];
|
||||
}
|
||||
|
||||
- (void) viewWillTransitionToSize: (CGSize) size withTransitionCoordinator: (id<UIViewControllerTransitionCoordinator>) coordinator
|
||||
{
|
||||
[super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];
|
||||
sendScreenBoundsUpdate (self);
|
||||
|
||||
// On some devices the screen-size isn't yet updated at this point, so also trigger another
|
||||
// async update to double-check..
|
||||
MessageManager::callAsync ([=]() { sendScreenBoundsUpdate (self); });
|
||||
}
|
||||
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
JuceUIView* juceView = (JuceUIView*) [self view];
|
||||
jassert (juceView != nil && juceView->owner != nullptr);
|
||||
juceView->owner->updateTransformAndScreenBounds();
|
||||
sendScreenBoundsUpdate (self);
|
||||
}
|
||||
|
||||
- (void) viewWillAppear: (BOOL) animated
|
||||
@@ -477,7 +506,7 @@ void ModifierKeys::updateCurrentModifiers() noexcept
|
||||
currentModifiers = UIViewComponentPeer::currentModifiers;
|
||||
}
|
||||
|
||||
Point<int> juce_lastMousePos;
|
||||
Point<float> juce_lastMousePos;
|
||||
|
||||
//==============================================================================
|
||||
UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyleFlags, UIView* viewToAttachTo)
|
||||
@@ -603,14 +632,14 @@ Rectangle<int> UIViewComponentPeer::getBounds (const bool global) const
|
||||
return convertToRectInt (r);
|
||||
}
|
||||
|
||||
Point<int> UIViewComponentPeer::localToGlobal (Point<int> relativePosition)
|
||||
Point<float> UIViewComponentPeer::localToGlobal (Point<float> relativePosition)
|
||||
{
|
||||
return relativePosition + getBounds (true).getPosition();
|
||||
return relativePosition + getBounds (true).getPosition().toFloat();
|
||||
}
|
||||
|
||||
Point<int> UIViewComponentPeer::globalToLocal (Point<int> screenPosition)
|
||||
Point<float> UIViewComponentPeer::globalToLocal (Point<float> screenPosition)
|
||||
{
|
||||
return screenPosition - getBounds (true).getPosition();
|
||||
return screenPosition - getBounds (true).getPosition().toFloat();
|
||||
}
|
||||
|
||||
void UIViewComponentPeer::setAlpha (float newAlpha)
|
||||
@@ -702,10 +731,7 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow)
|
||||
|
||||
void UIViewComponentPeer::toBehind (ComponentPeer* other)
|
||||
{
|
||||
UIViewComponentPeer* const otherPeer = dynamic_cast <UIViewComponentPeer*> (other);
|
||||
jassert (otherPeer != nullptr); // wrong type of window?
|
||||
|
||||
if (otherPeer != nullptr)
|
||||
if (UIViewComponentPeer* const otherPeer = dynamic_cast<UIViewComponentPeer*> (other))
|
||||
{
|
||||
if (isSharedWindow)
|
||||
{
|
||||
@@ -716,6 +742,10 @@ void UIViewComponentPeer::toBehind (ComponentPeer* other)
|
||||
// don't know how to do this
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse; // wrong type of window?
|
||||
}
|
||||
}
|
||||
|
||||
void UIViewComponentPeer::setIcon (const Image& /*newIcon*/)
|
||||
@@ -736,8 +766,8 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons
|
||||
continue;
|
||||
|
||||
CGPoint p = [touch locationInView: view];
|
||||
const Point<int> pos ((int) p.x, (int) p.y);
|
||||
juce_lastMousePos = pos + getBounds (true).getPosition();
|
||||
const Point<float> pos (p.x, p.y);
|
||||
juce_lastMousePos = pos + getBounds (true).getPosition().toFloat();
|
||||
|
||||
const int64 time = getMouseTime (event);
|
||||
const int touchIndex = currentTouches.getIndexOfTouch (touch);
|
||||
@@ -781,7 +811,7 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons
|
||||
|
||||
if (isUp || isCancel)
|
||||
{
|
||||
handleMouseEvent (touchIndex, Point<int> (-1, -1), modsToSend, time);
|
||||
handleMouseEvent (touchIndex, Point<float> (-1.0f, -1.0f), modsToSend, time);
|
||||
if (! isValidPeer (this))
|
||||
return;
|
||||
}
|
||||
@@ -828,12 +858,28 @@ void UIViewComponentPeer::grabFocus()
|
||||
}
|
||||
}
|
||||
|
||||
void UIViewComponentPeer::textInputRequired (const Point<int>&)
|
||||
void UIViewComponentPeer::textInputRequired (Point<int>, TextInputTarget&)
|
||||
{
|
||||
}
|
||||
|
||||
static UIKeyboardType getUIKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TextInputTarget::textKeyboard: return UIKeyboardTypeAlphabet;
|
||||
case TextInputTarget::numericKeyboard: return UIKeyboardTypeNumbersAndPunctuation;
|
||||
case TextInputTarget::urlKeyboard: return UIKeyboardTypeURL;
|
||||
case TextInputTarget::emailAddressKeyboard: return UIKeyboardTypeEmailAddress;
|
||||
case TextInputTarget::phoneNumberKeyboard: return UIKeyboardTypePhonePad;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return UIKeyboardTypeDefault;
|
||||
}
|
||||
|
||||
void UIViewComponentPeer::updateHiddenTextContent (TextInputTarget* target)
|
||||
{
|
||||
view->hiddenTextView.keyboardType = getUIKeyboardType (target->getKeyboardType());
|
||||
view->hiddenTextView.text = juceStringToNS (target->getTextInRange (Range<int> (0, target->getHighlightedRegion().getStart())));
|
||||
view->hiddenTextView.selectedRange = NSMakeRange (target->getHighlightedRegion().getStart(), 0);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ private:
|
||||
|
||||
- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex
|
||||
{
|
||||
owner->buttonClicked (buttonIndex);
|
||||
owner->buttonClicked ((int) buttonIndex);
|
||||
alertView.hidden = true;
|
||||
}
|
||||
|
||||
@@ -312,12 +312,12 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
return juce_lastMousePos;
|
||||
}
|
||||
|
||||
void MouseInputSource::setRawMousePosition (Point<int>)
|
||||
void MouseInputSource::setRawMousePosition (Point<float>)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -42,99 +42,134 @@ bool FileChooser::isPlatformDialogAvailable()
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileChooser::showPlatformDialog (Array<File>& results,
|
||||
const String& title,
|
||||
const File& file,
|
||||
const String& filters,
|
||||
bool isDirectory,
|
||||
bool /* selectsFiles */,
|
||||
bool isSave,
|
||||
bool /* warnAboutOverwritingExistingFiles */,
|
||||
bool selectMultipleFiles,
|
||||
FilePreviewComponent* /* previewComponent */)
|
||||
static uint64 getTopWindowID() noexcept
|
||||
{
|
||||
String separator;
|
||||
StringArray args;
|
||||
if (TopLevelWindow* top = TopLevelWindow::getActiveTopLevelWindow())
|
||||
return (uint64) (pointer_sized_uint) top->getWindowHandle();
|
||||
|
||||
const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
|
||||
const bool isKdeFullSession = SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String::empty)
|
||||
.equalsIgnoreCase ("true");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exeIsAvailable ("kdialog") && (isKdeFullSession || ! exeIsAvailable ("zenity")))
|
||||
static bool isKdeFullSession()
|
||||
{
|
||||
return SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String())
|
||||
.equalsIgnoreCase ("true");
|
||||
}
|
||||
|
||||
static void addKDialogArgs (StringArray& args, String& separator,
|
||||
const String& title, const File& file, const String& filters,
|
||||
bool isDirectory, bool isSave, bool selectMultipleFiles)
|
||||
{
|
||||
args.add ("kdialog");
|
||||
|
||||
if (title.isNotEmpty())
|
||||
args.add ("--title=" + title);
|
||||
|
||||
if (uint64 topWindowID = getTopWindowID())
|
||||
{
|
||||
// use kdialog for KDE sessions or if zenity is missing
|
||||
args.add ("kdialog");
|
||||
args.add ("--attach");
|
||||
args.add (String (topWindowID));
|
||||
}
|
||||
|
||||
if (title.isNotEmpty())
|
||||
args.add ("--title=" + title);
|
||||
|
||||
if (selectMultipleFiles)
|
||||
{
|
||||
separator = "\n";
|
||||
args.add ("--multiple");
|
||||
args.add ("--separate-output");
|
||||
args.add ("--getopenfilename");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSave) args.add ("--getsavefilename");
|
||||
else if (isDirectory) args.add ("--getexistingdirectory");
|
||||
else args.add ("--getopenfilename");
|
||||
}
|
||||
|
||||
String startPath;
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
startPath = file.getFullPathName();
|
||||
}
|
||||
else if (file.getParentDirectory().exists())
|
||||
{
|
||||
startPath = file.getParentDirectory().getFullPathName();
|
||||
}
|
||||
else
|
||||
{
|
||||
startPath = File::getSpecialLocation (File::userHomeDirectory).getFullPathName();
|
||||
|
||||
if (isSave)
|
||||
startPath += "/" + file.getFileName();
|
||||
}
|
||||
|
||||
args.add (startPath);
|
||||
args.add (filters.replaceCharacter (';', ' '));
|
||||
if (selectMultipleFiles)
|
||||
{
|
||||
separator = "\n";
|
||||
args.add ("--multiple");
|
||||
args.add ("--separate-output");
|
||||
args.add ("--getopenfilename");
|
||||
}
|
||||
else
|
||||
{
|
||||
// zenity
|
||||
args.add ("zenity");
|
||||
args.add ("--file-selection");
|
||||
|
||||
if (title.isNotEmpty())
|
||||
args.add ("--title=" + title);
|
||||
|
||||
if (selectMultipleFiles)
|
||||
{
|
||||
separator = ":";
|
||||
args.add ("--multiple");
|
||||
args.add ("--separator=" + separator);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDirectory) args.add ("--directory");
|
||||
if (isSave) args.add ("--save");
|
||||
}
|
||||
|
||||
if (file.isDirectory())
|
||||
file.setAsCurrentWorkingDirectory();
|
||||
else if (file.getParentDirectory().exists())
|
||||
file.getParentDirectory().setAsCurrentWorkingDirectory();
|
||||
else
|
||||
File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory();
|
||||
|
||||
if (! file.getFileName().isEmpty())
|
||||
args.add ("--filename=" + file.getFileName());
|
||||
if (isSave) args.add ("--getsavefilename");
|
||||
else if (isDirectory) args.add ("--getexistingdirectory");
|
||||
else args.add ("--getopenfilename");
|
||||
}
|
||||
|
||||
File startPath;
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
startPath = file;
|
||||
}
|
||||
else if (file.getParentDirectory().exists())
|
||||
{
|
||||
startPath = file.getParentDirectory();
|
||||
}
|
||||
else
|
||||
{
|
||||
startPath = File::getSpecialLocation (File::userHomeDirectory);
|
||||
|
||||
if (isSave)
|
||||
startPath = startPath.getChildFile (file.getFileName());
|
||||
}
|
||||
|
||||
args.add (startPath.getFullPathName());
|
||||
args.add (filters.replaceCharacter (';', ' '));
|
||||
}
|
||||
|
||||
static void addZenityArgs (StringArray& args, String& separator,
|
||||
const String& title, const File& file, const String& filters,
|
||||
bool isDirectory, bool isSave, bool selectMultipleFiles)
|
||||
{
|
||||
args.add ("zenity");
|
||||
args.add ("--file-selection");
|
||||
|
||||
if (title.isNotEmpty())
|
||||
args.add ("--title=" + title);
|
||||
|
||||
if (selectMultipleFiles)
|
||||
{
|
||||
separator = ":";
|
||||
args.add ("--multiple");
|
||||
args.add ("--separator=" + separator);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDirectory) args.add ("--directory");
|
||||
if (isSave) args.add ("--save");
|
||||
}
|
||||
|
||||
if (filters.isNotEmpty() && filters != "*" && filters != "*.*")
|
||||
{
|
||||
args.add ("--file-filter");
|
||||
args.add (filters.replaceCharacter (';', ' '));
|
||||
|
||||
args.add ("--file-filter");
|
||||
args.add ("All files | *");
|
||||
}
|
||||
|
||||
if (file.isDirectory())
|
||||
file.setAsCurrentWorkingDirectory();
|
||||
else if (file.getParentDirectory().exists())
|
||||
file.getParentDirectory().setAsCurrentWorkingDirectory();
|
||||
else
|
||||
File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory();
|
||||
|
||||
if (! file.getFileName().isEmpty())
|
||||
args.add ("--filename=" + file.getFileName());
|
||||
|
||||
// supplying the window ID of the topmost window makes sure that Zenity pops up..
|
||||
if (uint64 topWindowID = getTopWindowID())
|
||||
setenv ("WINDOWID", String (topWindowID).toRawUTF8(), true);
|
||||
}
|
||||
|
||||
void FileChooser::showPlatformDialog (Array<File>& results,
|
||||
const String& title, const File& file, const String& filters,
|
||||
bool isDirectory, bool /* selectsFiles */,
|
||||
bool isSave, bool /* warnAboutOverwritingExistingFiles */,
|
||||
bool selectMultipleFiles, FilePreviewComponent*)
|
||||
{
|
||||
const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
|
||||
|
||||
StringArray args;
|
||||
String separator;
|
||||
|
||||
// use kdialog for KDE sessions or if zenity is missing
|
||||
if (exeIsAvailable ("kdialog") && (isKdeFullSession() || ! exeIsAvailable ("zenity")))
|
||||
addKDialogArgs (args, separator, title, file, filters, isDirectory, isSave, selectMultipleFiles);
|
||||
else
|
||||
addZenityArgs (args, separator, title, file, filters, isDirectory, isSave, selectMultipleFiles);
|
||||
|
||||
args.add ("2>/dev/null"); // (to avoid logging info ending up in the results)
|
||||
|
||||
ChildProcess child;
|
||||
|
||||
@@ -33,17 +33,18 @@ struct Atoms
|
||||
{
|
||||
Atoms()
|
||||
{
|
||||
Protocols = getIfExists ("WM_PROTOCOLS");
|
||||
ProtocolList [TAKE_FOCUS] = getIfExists ("WM_TAKE_FOCUS");
|
||||
ProtocolList [DELETE_WINDOW] = getIfExists ("WM_DELETE_WINDOW");
|
||||
ProtocolList [PING] = getIfExists ("_NET_WM_PING");
|
||||
ChangeState = getIfExists ("WM_CHANGE_STATE");
|
||||
State = getIfExists ("WM_STATE");
|
||||
UserTime = getCreating ("_NET_WM_USER_TIME");
|
||||
ActiveWin = getCreating ("_NET_ACTIVE_WINDOW");
|
||||
Pid = getCreating ("_NET_WM_PID");
|
||||
WindowType = getIfExists ("_NET_WM_WINDOW_TYPE");
|
||||
WindowState = getIfExists ("_NET_WM_STATE");
|
||||
protocols = getIfExists ("WM_PROTOCOLS");
|
||||
protocolList [TAKE_FOCUS] = getIfExists ("WM_TAKE_FOCUS");
|
||||
protocolList [DELETE_WINDOW] = getIfExists ("WM_DELETE_WINDOW");
|
||||
protocolList [PING] = getIfExists ("_NET_WM_PING");
|
||||
changeState = getIfExists ("WM_CHANGE_STATE");
|
||||
state = getIfExists ("WM_STATE");
|
||||
userTime = getCreating ("_NET_WM_USER_TIME");
|
||||
activeWin = getCreating ("_NET_ACTIVE_WINDOW");
|
||||
pid = getCreating ("_NET_WM_PID");
|
||||
windowType = getIfExists ("_NET_WM_WINDOW_TYPE");
|
||||
windowState = getIfExists ("_NET_WM_STATE");
|
||||
compositingManager = getCreating ("_NET_WM_CM_S0");
|
||||
|
||||
XdndAware = getCreating ("XdndAware");
|
||||
XdndEnter = getCreating ("XdndEnter");
|
||||
@@ -88,8 +89,8 @@ struct Atoms
|
||||
PING = 2
|
||||
};
|
||||
|
||||
Atom Protocols, ProtocolList[3], ChangeState, State, UserTime,
|
||||
ActiveWin, Pid, WindowType, WindowState,
|
||||
Atom protocols, protocolList[3], changeState, state, userTime,
|
||||
activeWin, pid, windowType, windowState, compositingManager,
|
||||
XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus,
|
||||
XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList,
|
||||
XdndActionDescription, XdndActionCopy, XdndActionPrivate,
|
||||
@@ -314,6 +315,11 @@ namespace XRender
|
||||
return xRenderQueryVersion != nullptr;
|
||||
}
|
||||
|
||||
static bool hasCompositingWindowManager()
|
||||
{
|
||||
return XGetSelectionOwner (display, Atoms::get().compositingManager) != 0;
|
||||
}
|
||||
|
||||
static XRenderPictFormat* findPictureFormat()
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
@@ -915,7 +921,7 @@ public:
|
||||
clientMsg.window = windowH;
|
||||
clientMsg.type = ClientMessage;
|
||||
clientMsg.format = 32;
|
||||
clientMsg.message_type = Atoms::get().WindowState;
|
||||
clientMsg.message_type = Atoms::get().windowState;
|
||||
clientMsg.data.l[0] = 0; // Remove
|
||||
clientMsg.data.l[1] = fs;
|
||||
clientMsg.data.l[2] = 0;
|
||||
@@ -971,14 +977,14 @@ public:
|
||||
|
||||
Rectangle<int> getBounds() const override { return bounds; }
|
||||
|
||||
Point<int> localToGlobal (Point<int> relativePosition) override
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override
|
||||
{
|
||||
return relativePosition + bounds.getPosition();
|
||||
return relativePosition + bounds.getPosition().toFloat();
|
||||
}
|
||||
|
||||
Point<int> globalToLocal (Point<int> screenPosition) override
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override
|
||||
{
|
||||
return screenPosition - bounds.getPosition();
|
||||
return screenPosition - bounds.getPosition().toFloat();
|
||||
}
|
||||
|
||||
void setAlpha (float /* newAlpha */) override
|
||||
@@ -1002,7 +1008,7 @@ public:
|
||||
clientMsg.window = windowH;
|
||||
clientMsg.type = ClientMessage;
|
||||
clientMsg.format = 32;
|
||||
clientMsg.message_type = Atoms::get().ChangeState;
|
||||
clientMsg.message_type = Atoms::get().changeState;
|
||||
clientMsg.data.l[0] = IconicState;
|
||||
|
||||
ScopedXLock xlock;
|
||||
@@ -1018,10 +1024,10 @@ public:
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
const Atoms& atoms = Atoms::get();
|
||||
GetXProperty prop (windowH, atoms.State, 0, 64, false, atoms.State);
|
||||
GetXProperty prop (windowH, atoms.state, 0, 64, false, atoms.state);
|
||||
|
||||
return prop.success
|
||||
&& prop.actualType == atoms.State
|
||||
&& prop.actualType == atoms.state
|
||||
&& prop.actualFormat == 32
|
||||
&& prop.numItems > 0
|
||||
&& ((unsigned long*) prop.data)[0] == IconicState;
|
||||
@@ -1039,7 +1045,7 @@ public:
|
||||
r = Desktop::getInstance().getDisplays().getMainDisplay().userArea;
|
||||
|
||||
if (! r.isEmpty())
|
||||
setBounds (r, shouldBeFullScreen);
|
||||
setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, r), shouldBeFullScreen);
|
||||
|
||||
component.repaint();
|
||||
}
|
||||
@@ -1081,9 +1087,7 @@ public:
|
||||
{
|
||||
for (int i = windowListSize; --i >= 0;)
|
||||
{
|
||||
LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (windowList[i]);
|
||||
|
||||
if (peer != 0)
|
||||
if (LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (windowList[i]))
|
||||
{
|
||||
result = (peer == this);
|
||||
break;
|
||||
@@ -1109,9 +1113,9 @@ public:
|
||||
if (c == &component)
|
||||
break;
|
||||
|
||||
// TODO: needs scaling correctly
|
||||
if (c->contains (localPos + bounds.getPosition() - c->getScreenPosition()))
|
||||
return false;
|
||||
if (ComponentPeer* peer = c->getPeer())
|
||||
if (peer->contains (localPos + bounds.getPosition() - peer->getBounds().getPosition(), true))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (trueIfInAChildWindow)
|
||||
@@ -1152,7 +1156,7 @@ public:
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.serial = 0;
|
||||
ev.xclient.send_event = True;
|
||||
ev.xclient.message_type = Atoms::get().ActiveWin;
|
||||
ev.xclient.message_type = Atoms::get().activeWin;
|
||||
ev.xclient.window = windowH;
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = 2;
|
||||
@@ -1178,10 +1182,7 @@ public:
|
||||
|
||||
void toBehind (ComponentPeer* other) override
|
||||
{
|
||||
LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);
|
||||
jassert (otherPeer != nullptr); // wrong type of window?
|
||||
|
||||
if (otherPeer != nullptr)
|
||||
if (LinuxComponentPeer* const otherPeer = dynamic_cast<LinuxComponentPeer*> (other))
|
||||
{
|
||||
setMinimised (false);
|
||||
|
||||
@@ -1190,6 +1191,8 @@ public:
|
||||
ScopedXLock xlock;
|
||||
XRestackWindows (display, newStack, 2);
|
||||
}
|
||||
else
|
||||
jassertfalse; // wrong type of window?
|
||||
}
|
||||
|
||||
bool isFocused() const override
|
||||
@@ -1217,11 +1220,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void textInputRequired (const Point<int>&) override {}
|
||||
void textInputRequired (Point<int>, TextInputTarget&) override {}
|
||||
|
||||
void repaint (const Rectangle<int>& area) override
|
||||
{
|
||||
repainter->repaint (area.getIntersection (component.getLocalBounds()));
|
||||
repainter->repaint (area.getIntersection (bounds.withZeroOrigin()));
|
||||
}
|
||||
|
||||
void performAnyPendingRepaintsNow() override
|
||||
@@ -1327,6 +1330,7 @@ public:
|
||||
|
||||
default:
|
||||
#if JUCE_USE_XSHM
|
||||
if (XSHMHelpers::isShmAvailable())
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
if (event.xany.type == XShmGetEventBase (display))
|
||||
@@ -1368,7 +1372,7 @@ public:
|
||||
const ModifierKeys oldMods (currentModifiers);
|
||||
bool keyPressed = false;
|
||||
|
||||
if ((sym & 0xff00) == 0xff00 || sym == XK_ISO_Left_Tab)
|
||||
if ((sym & 0xff00) == 0xff00 || keyCode == XK_ISO_Left_Tab)
|
||||
{
|
||||
switch (sym) // Translate keypad
|
||||
{
|
||||
@@ -1427,6 +1431,11 @@ public:
|
||||
keyCode &= 0xff;
|
||||
break;
|
||||
|
||||
case XK_ISO_Left_Tab:
|
||||
keyPressed = true;
|
||||
keyCode = XK_Tab & 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (sym >= XK_F1 && sym <= XK_F16)
|
||||
{
|
||||
@@ -1490,9 +1499,9 @@ public:
|
||||
}
|
||||
|
||||
template <typename EventType>
|
||||
static Point<int> getMousePos (const EventType& e) noexcept
|
||||
static Point<float> getMousePos (const EventType& e) noexcept
|
||||
{
|
||||
return Point<int> (e.x, e.y);
|
||||
return Point<float> ((float) e.x, (float) e.y);
|
||||
}
|
||||
|
||||
void handleWheelEvent (const XButtonPressedEvent& buttonPressEvent, const float amount)
|
||||
@@ -1698,11 +1707,11 @@ public:
|
||||
{
|
||||
const Atoms& atoms = Atoms::get();
|
||||
|
||||
if (clientMsg.message_type == atoms.Protocols && clientMsg.format == 32)
|
||||
if (clientMsg.message_type == atoms.protocols && clientMsg.format == 32)
|
||||
{
|
||||
const Atom atom = (Atom) clientMsg.data.l[0];
|
||||
|
||||
if (atom == atoms.ProtocolList [Atoms::PING])
|
||||
if (atom == atoms.protocolList [Atoms::PING])
|
||||
{
|
||||
Window root = RootWindow (display, DefaultScreen (display));
|
||||
|
||||
@@ -1711,7 +1720,7 @@ public:
|
||||
XSendEvent (display, root, False, NoEventMask, &event);
|
||||
XFlush (display);
|
||||
}
|
||||
else if (atom == atoms.ProtocolList [Atoms::TAKE_FOCUS])
|
||||
else if (atom == atoms.protocolList [Atoms::TAKE_FOCUS])
|
||||
{
|
||||
if ((getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0)
|
||||
{
|
||||
@@ -1726,7 +1735,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (atom == atoms.ProtocolList [Atoms::DELETE_WINDOW])
|
||||
else if (atom == atoms.protocolList [Atoms::DELETE_WINDOW])
|
||||
{
|
||||
handleUserClosingWindow();
|
||||
}
|
||||
@@ -1902,7 +1911,8 @@ private:
|
||||
for (const Rectangle<int>* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i)
|
||||
{
|
||||
#if JUCE_USE_XSHM
|
||||
++shmPaintsPending;
|
||||
if (XSHMHelpers::isShmAvailable())
|
||||
++shmPaintsPending;
|
||||
#endif
|
||||
|
||||
static_cast<XBitmapImage*> (image.getPixelData())
|
||||
@@ -2166,7 +2176,7 @@ private:
|
||||
|
||||
netHints[1] = Atoms::getIfExists ("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
|
||||
|
||||
xchangeProperty (windowH, Atoms::get().WindowType, XA_ATOM, 32, &netHints, 2);
|
||||
xchangeProperty (windowH, Atoms::get().windowType, XA_ATOM, 32, &netHints, 2);
|
||||
|
||||
int numHints = 0;
|
||||
|
||||
@@ -2177,7 +2187,7 @@ private:
|
||||
netHints [numHints++] = Atoms::getIfExists ("_NET_WM_STATE_ABOVE");
|
||||
|
||||
if (numHints > 0)
|
||||
xchangeProperty (windowH, Atoms::get().WindowState, XA_ATOM, 32, &netHints, numHints);
|
||||
xchangeProperty (windowH, Atoms::get().windowState, XA_ATOM, 32, &netHints, numHints);
|
||||
}
|
||||
|
||||
void createWindow (Window parentToAddTo)
|
||||
@@ -2254,10 +2264,10 @@ private:
|
||||
|
||||
// Associate the PID, allowing to be shut down when something goes wrong
|
||||
unsigned long pid = getpid();
|
||||
xchangeProperty (windowH, atoms.Pid, XA_CARDINAL, 32, &pid, 1);
|
||||
xchangeProperty (windowH, atoms.pid, XA_CARDINAL, 32, &pid, 1);
|
||||
|
||||
// Set window manager protocols
|
||||
xchangeProperty (windowH, atoms.Protocols, XA_ATOM, 32, atoms.ProtocolList, 2);
|
||||
xchangeProperty (windowH, atoms.protocols, XA_ATOM, 32, atoms.protocolList, 2);
|
||||
|
||||
// Set drag and drop flags
|
||||
xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32, atoms.allowedMimeTypes, numElementsInArray (atoms.allowedMimeTypes));
|
||||
@@ -2314,7 +2324,7 @@ private:
|
||||
|
||||
long getUserTime() const
|
||||
{
|
||||
GetXProperty prop (windowH, Atoms::get().UserTime, 0, 65536, false, XA_CARDINAL);
|
||||
GetXProperty prop (windowH, Atoms::get().userTime, 0, 65536, false, XA_CARDINAL);
|
||||
return prop.success ? *(long*) prop.data : 0;
|
||||
}
|
||||
|
||||
@@ -3042,10 +3052,10 @@ void Desktop::Displays::findDisplays (float masterScale)
|
||||
d.userArea = d.totalArea = Rectangle<int> (screens[j].x_org,
|
||||
screens[j].y_org,
|
||||
screens[j].width,
|
||||
screens[j].height) * masterScale;
|
||||
screens[j].height) / masterScale;
|
||||
d.isMain = (index == 0);
|
||||
d.scale = masterScale;
|
||||
d.dpi = getDisplayDPI (index);
|
||||
d.dpi = getDisplayDPI (0); // (all screens share the same DPI)
|
||||
|
||||
displays.add (d);
|
||||
}
|
||||
@@ -3114,14 +3124,20 @@ bool MouseInputSource::SourceList::addSource()
|
||||
|
||||
bool Desktop::canUseSemiTransparentWindows() noexcept
|
||||
{
|
||||
int matchedDepth = 0;
|
||||
const int desiredDepth = 32;
|
||||
#if JUCE_USE_XRENDER
|
||||
if (XRender::hasCompositingWindowManager())
|
||||
{
|
||||
int matchedDepth = 0, desiredDepth = 32;
|
||||
|
||||
return Visuals::findVisualFormat (desiredDepth, matchedDepth) != 0
|
||||
&& (matchedDepth == desiredDepth);
|
||||
return Visuals::findVisualFormat (desiredDepth, matchedDepth) != 0
|
||||
&& matchedDepth == desiredDepth;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
Window root, child;
|
||||
int x, y, winx, winy;
|
||||
@@ -3138,14 +3154,14 @@ Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
x = y = -1;
|
||||
}
|
||||
|
||||
return Point<int> (x, y);
|
||||
return Point<float> ((float) x, (float) y);
|
||||
}
|
||||
|
||||
void MouseInputSource::setRawMousePosition (Point<int> newPosition)
|
||||
void MouseInputSource::setRawMousePosition (Point<float> newPosition)
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
Window root = RootWindow (display, DefaultScreen (display));
|
||||
XWarpPointer (display, None, root, 0, 0, 0, 0, newPosition.getX(), newPosition.getY());
|
||||
XWarpPointer (display, None, root, 0, 0, 0, 0, roundToInt (newPosition.getX()), roundToInt (newPosition.getY()));
|
||||
}
|
||||
|
||||
double Desktop::getDefaultMasterScale()
|
||||
@@ -3364,7 +3380,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
|
||||
|
||||
void MouseCursor::showInWindow (ComponentPeer* peer) const
|
||||
{
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer))
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (peer))
|
||||
lp->showMouseCursor ((Cursor) getHandle());
|
||||
}
|
||||
|
||||
@@ -3388,7 +3404,7 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi
|
||||
|
||||
if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0))
|
||||
if (Component* sourceComp = draggingSource->getComponentUnderMouse())
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (sourceComp->getPeer()))
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (sourceComp->getPeer()))
|
||||
return lp->externalDragFileInit (files, canMoveFiles);
|
||||
|
||||
// This method must be called in response to a component's mouseDown or mouseDrag event!
|
||||
@@ -3403,7 +3419,7 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
|
||||
|
||||
if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0))
|
||||
if (Component* sourceComp = draggingSource->getComponentUnderMouse())
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (sourceComp->getPeer()))
|
||||
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (sourceComp->getPeer()))
|
||||
return lp->externalDragTextInit (text);
|
||||
|
||||
// This method must be called in response to a component's mouseDown or mouseDrag event!
|
||||
|
||||
@@ -295,14 +295,14 @@ public:
|
||||
return getBounds (! isSharedWindow);
|
||||
}
|
||||
|
||||
Point<int> localToGlobal (Point<int> relativePosition) override
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override
|
||||
{
|
||||
return relativePosition + getBounds (true).getPosition();
|
||||
return relativePosition + getBounds (true).getPosition().toFloat();
|
||||
}
|
||||
|
||||
Point<int> globalToLocal (Point<int> screenPosition) override
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override
|
||||
{
|
||||
return screenPosition - getBounds (true).getPosition();
|
||||
return screenPosition - getBounds (true).getPosition().toFloat();
|
||||
}
|
||||
|
||||
void setAlpha (float newAlpha) override
|
||||
@@ -369,7 +369,7 @@ public:
|
||||
|
||||
// (can't call the component's setBounds method because that'll reset our fullscreen flag)
|
||||
if (r != component.getBounds() && ! r.isEmpty())
|
||||
setBounds (r, shouldBeFullScreen);
|
||||
setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, r), shouldBeFullScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,16 +390,37 @@ public:
|
||||
return ComponentPeer::isKioskMode();
|
||||
}
|
||||
|
||||
static bool isWindowAtPoint (NSWindow* w, NSPoint screenPoint)
|
||||
{
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
if ([NSWindow respondsToSelector: @selector (windowNumberAtPoint:belowWindowWithWindowNumber:)])
|
||||
return [NSWindow windowNumberAtPoint: screenPoint belowWindowWithWindowNumber: 0] == [w windowNumber];
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
|
||||
{
|
||||
NSRect frameRect = [view frame];
|
||||
NSRect viewFrame = [view frame];
|
||||
|
||||
if (! (isPositiveAndBelow (localPos.getX(), (int) frameRect.size.width)
|
||||
&& isPositiveAndBelow (localPos.getY(), (int) frameRect.size.height)))
|
||||
if (! (isPositiveAndBelow (localPos.getX(), (int) viewFrame.size.width)
|
||||
&& isPositiveAndBelow (localPos.getY(), (int) viewFrame.size.height)))
|
||||
return false;
|
||||
|
||||
NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + localPos.getX(),
|
||||
frameRect.origin.y + frameRect.size.height - localPos.getY())];
|
||||
if (NSWindow* const viewWindow = [view window])
|
||||
{
|
||||
const NSRect windowFrame = [viewWindow frame];
|
||||
const NSPoint windowPoint = [view convertPoint: NSMakePoint (localPos.x, localPos.y) toView: nil];
|
||||
const NSPoint screenPoint = NSMakePoint (windowFrame.origin.x + windowPoint.x,
|
||||
windowFrame.origin.y + windowFrame.size.height - windowPoint.y);
|
||||
|
||||
if (! isWindowAtPoint (viewWindow, screenPoint))
|
||||
return false;
|
||||
}
|
||||
|
||||
NSView* v = [view hitTest: NSMakePoint (viewFrame.origin.x + localPos.getX(),
|
||||
viewFrame.origin.y + viewFrame.size.height - localPos.getY())];
|
||||
|
||||
return trueIfInAChildWindow ? (v != nil)
|
||||
: (v == view);
|
||||
@@ -553,19 +574,11 @@ public:
|
||||
{
|
||||
currentModifiers = currentModifiers.withoutMouseButtons();
|
||||
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
if ([NSWindow respondsToSelector: @selector (windowNumberAtPoint:belowWindowWithWindowNumber:)]
|
||||
&& [NSWindow windowNumberAtPoint: [[ev window] convertBaseToScreen: [ev locationInWindow]]
|
||||
belowWindowWithWindowNumber: 0] != [window windowNumber])
|
||||
{
|
||||
// moved into another window which overlaps this one, so trigger an exit
|
||||
handleMouseEvent (0, Point<int> (-1, -1), currentModifiers, getMouseTime (ev));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (isWindowAtPoint ([ev window], [[ev window] convertBaseToScreen: [ev locationInWindow]]))
|
||||
sendMouseEvent (ev);
|
||||
}
|
||||
else
|
||||
// moved into another window which overlaps this one, so trigger an exit
|
||||
handleMouseEvent (0, Point<float> (-1.0f, -1.0f), currentModifiers, getMouseTime (ev));
|
||||
|
||||
showArrowCursorIfNeeded();
|
||||
}
|
||||
@@ -936,7 +949,7 @@ public:
|
||||
MouseInputSource mouse = desktop.getMainMouseSource();
|
||||
|
||||
if (mouse.getComponentUnderMouse() == nullptr
|
||||
&& desktop.findComponentAt (mouse.getScreenPosition()) == nullptr)
|
||||
&& desktop.findComponentAt (mouse.getScreenPosition().roundToInt()) == nullptr)
|
||||
{
|
||||
[[NSCursor arrowCursor] set];
|
||||
}
|
||||
@@ -1010,10 +1023,10 @@ public:
|
||||
+ (int64) ([e timestamp] * 1000.0);
|
||||
}
|
||||
|
||||
static Point<int> getMousePos (NSEvent* e, NSView* view)
|
||||
static Point<float> getMousePos (NSEvent* e, NSView* view)
|
||||
{
|
||||
NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil];
|
||||
return Point<int> ((int) p.x, (int) ([view frame].size.height - p.y));
|
||||
return Point<float> ((float) p.x, (float) ([view frame].size.height - p.y));
|
||||
}
|
||||
|
||||
static int getModifierForButtonNumber (const NSInteger num)
|
||||
@@ -1136,8 +1149,9 @@ public:
|
||||
|
||||
bool isFocused() const override
|
||||
{
|
||||
return isSharedWindow ? this == currentlyFocusedPeer
|
||||
: [window isKeyWindow];
|
||||
return (isSharedWindow || ! JUCEApplication::isStandaloneApp())
|
||||
? this == currentlyFocusedPeer
|
||||
: [window isKeyWindow];
|
||||
}
|
||||
|
||||
void grabFocus() override
|
||||
@@ -1151,7 +1165,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void textInputRequired (const Point<int>&) override {}
|
||||
void textInputRequired (Point<int>, TextInputTarget&) override {}
|
||||
|
||||
//==============================================================================
|
||||
void repaint (const Rectangle<int>& area) override
|
||||
@@ -1221,6 +1235,8 @@ private:
|
||||
const Rectangle<int> clipBounds (clipW, clipH);
|
||||
const CGFloat viewH = [view frame].size.height;
|
||||
|
||||
clip.ensureStorageAllocated ((int) numRects);
|
||||
|
||||
for (int i = 0; i < numRects; ++i)
|
||||
clip.addWithoutMerging (clipBounds.getIntersection (Rectangle<int> (roundToInt (rects[i].origin.x) + offset.x,
|
||||
roundToInt (viewH - (rects[i].origin.y + rects[i].size.height)) + offset.y,
|
||||
@@ -1687,21 +1703,22 @@ private:
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct JuceNSWindowClass : public ObjCClass <NSWindow>
|
||||
struct JuceNSWindowClass : public ObjCClass<NSWindow>
|
||||
{
|
||||
JuceNSWindowClass() : ObjCClass <NSWindow> ("JUCEWindow_")
|
||||
JuceNSWindowClass() : ObjCClass<NSWindow> ("JUCEWindow_")
|
||||
{
|
||||
addIvar<NSViewComponentPeer*> ("owner");
|
||||
|
||||
addMethod (@selector (canBecomeKeyWindow), canBecomeKeyWindow, "c@:");
|
||||
addMethod (@selector (becomeKeyWindow), becomeKeyWindow, "v@:");
|
||||
addMethod (@selector (windowShouldClose:), windowShouldClose, "c@:@");
|
||||
addMethod (@selector (constrainFrameRect:toScreen:), constrainFrameRect, @encode (NSRect), "@:", @encode (NSRect), "@");
|
||||
addMethod (@selector (windowWillResize:toSize:), windowWillResize, @encode (NSSize), "@:@", @encode (NSSize));
|
||||
addMethod (@selector (zoom:), zoom, "v@:@");
|
||||
addMethod (@selector (windowWillMove:), windowWillMove, "v@:@");
|
||||
addMethod (@selector (canBecomeKeyWindow), canBecomeKeyWindow, "c@:");
|
||||
addMethod (@selector (becomeKeyWindow), becomeKeyWindow, "v@:");
|
||||
addMethod (@selector (windowShouldClose:), windowShouldClose, "c@:@");
|
||||
addMethod (@selector (constrainFrameRect:toScreen:), constrainFrameRect, @encode (NSRect), "@:", @encode (NSRect), "@");
|
||||
addMethod (@selector (windowWillResize:toSize:), windowWillResize, @encode (NSSize), "@:@", @encode (NSSize));
|
||||
addMethod (@selector (windowDidExitFullScreen:), windowDidExitFullScreen, "v@:@");
|
||||
addMethod (@selector (zoom:), zoom, "v@:@");
|
||||
addMethod (@selector (windowWillMove:), windowWillMove, "v@:@");
|
||||
addMethod (@selector (windowWillStartLiveResize:), windowWillStartLiveResize, "v@:@");
|
||||
addMethod (@selector (windowDidEndLiveResize:), windowDidEndLiveResize, "v@:@");
|
||||
addMethod (@selector (windowDidEndLiveResize:), windowDidEndLiveResize, "v@:@");
|
||||
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
addProtocol (@protocol (NSWindowDelegate));
|
||||
@@ -1767,6 +1784,11 @@ private:
|
||||
return frameRect.size;
|
||||
}
|
||||
|
||||
static void windowDidExitFullScreen (id, SEL, NSNotification*)
|
||||
{
|
||||
[NSApp setPresentationOptions: NSApplicationPresentationDefault];
|
||||
}
|
||||
|
||||
static void zoom (id self, SEL, id sender)
|
||||
{
|
||||
if (NSViewComponentPeer* const owner = getOwner (self))
|
||||
@@ -1865,7 +1887,7 @@ bool MouseInputSource::SourceList::addSource()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, bool allowMenusAndBars)
|
||||
void Desktop::setKioskComponent (Component* kioskComp, bool shouldBeEnabled, bool allowMenusAndBars)
|
||||
{
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
|
||||
|
||||
@@ -1876,13 +1898,15 @@ void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, boo
|
||||
if (peer->hasNativeTitleBar()
|
||||
&& [peer->window respondsToSelector: @selector (toggleFullScreen:)])
|
||||
{
|
||||
[peer->window performSelector: @selector (toggleFullScreen:)
|
||||
withObject: [NSNumber numberWithBool: (BOOL) enableOrDisable]];
|
||||
if (shouldBeEnabled && ! allowMenusAndBars)
|
||||
[NSApp setPresentationOptions: NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar];
|
||||
|
||||
[peer->window performSelector: @selector (toggleFullScreen:) withObject: nil];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (enableOrDisable)
|
||||
if (shouldBeEnabled)
|
||||
{
|
||||
if (peer->hasNativeTitleBar())
|
||||
[peer->window setStyleMask: NSBorderlessWindowMask];
|
||||
@@ -1904,9 +1928,7 @@ void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, boo
|
||||
}
|
||||
}
|
||||
#elif JUCE_SUPPORT_CARBON
|
||||
(void) kioskComp; (void) enableOrDisable; (void) allowMenusAndBars;
|
||||
|
||||
if (enableOrDisable)
|
||||
if (shouldBeEnabled)
|
||||
{
|
||||
SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0);
|
||||
kioskComp->setBounds (Desktop::getInstance().getDisplays().getMainDisplay().totalArea);
|
||||
@@ -1916,7 +1938,7 @@ void Desktop::setKioskComponent (Component* kioskComp, bool enableOrDisable, boo
|
||||
SetSystemUIMode (kUIModeNormal, 0);
|
||||
}
|
||||
#else
|
||||
(void) kioskComp; (void) enableOrDisable; (void) allowMenusAndBars;
|
||||
(void) kioskComp; (void) shouldBeEnabled; (void) allowMenusAndBars;
|
||||
|
||||
// If you're targeting OSes earlier than 10.6 and want to use this feature,
|
||||
// you'll need to enable JUCE_SUPPORT_CARBON.
|
||||
|
||||
@@ -209,16 +209,16 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
const NSPoint p ([NSEvent mouseLocation]);
|
||||
return Point<int> (roundToInt (p.x), roundToInt (getMainScreenHeight() - p.y));
|
||||
return Point<float> ((float) p.x, (float) (getMainScreenHeight() - p.y));
|
||||
}
|
||||
}
|
||||
|
||||
void MouseInputSource::setRawMousePosition (Point<int> newPosition)
|
||||
void MouseInputSource::setRawMousePosition (Point<float> newPosition)
|
||||
{
|
||||
// this rubbish needs to be done around the warp call, to avoid causing a
|
||||
// bizarre glitch..
|
||||
@@ -354,6 +354,30 @@ static Rectangle<int> convertDisplayRect (NSRect r, CGFloat mainScreenBottom)
|
||||
return convertToRectInt (r);
|
||||
}
|
||||
|
||||
static Desktop::Displays::Display getDisplayFromScreen (NSScreen* s, CGFloat& mainScreenBottom, const float masterScale)
|
||||
{
|
||||
Desktop::Displays::Display d;
|
||||
|
||||
d.isMain = (mainScreenBottom == 0);
|
||||
|
||||
if (d.isMain)
|
||||
mainScreenBottom = [s frame].size.height;
|
||||
|
||||
d.userArea = convertDisplayRect ([s visibleFrame], mainScreenBottom) / masterScale;
|
||||
d.totalArea = convertDisplayRect ([s frame], mainScreenBottom) / masterScale;
|
||||
d.scale = masterScale;
|
||||
|
||||
#if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
if ([s respondsToSelector: @selector (backingScaleFactor)])
|
||||
d.scale *= s.backingScaleFactor;
|
||||
#endif
|
||||
|
||||
NSSize dpi = [[[s deviceDescription] objectForKey: NSDeviceResolution] sizeValue];
|
||||
d.dpi = (dpi.width + dpi.height) / 2.0;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void Desktop::Displays::findDisplays (const float masterScale)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
@@ -363,30 +387,7 @@ void Desktop::Displays::findDisplays (const float masterScale)
|
||||
CGFloat mainScreenBottom = 0;
|
||||
|
||||
for (NSScreen* s in [NSScreen screens])
|
||||
{
|
||||
Display d;
|
||||
d.isMain = false;
|
||||
|
||||
if (mainScreenBottom == 0)
|
||||
{
|
||||
mainScreenBottom = [s frame].size.height;
|
||||
d.isMain = true;
|
||||
}
|
||||
|
||||
d.userArea = convertDisplayRect ([s visibleFrame], mainScreenBottom) / masterScale;
|
||||
d.totalArea = convertDisplayRect ([s frame], mainScreenBottom) / masterScale;
|
||||
d.scale = masterScale;
|
||||
|
||||
#if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
if ([s respondsToSelector: @selector (backingScaleFactor)])
|
||||
d.scale *= s.backingScaleFactor;
|
||||
#endif
|
||||
|
||||
NSSize dpi = [[[s deviceDescription] objectForKey: NSDeviceResolution] sizeValue];
|
||||
d.dpi = (dpi.width + dpi.height) / 2.0;
|
||||
|
||||
displays.add (d);
|
||||
}
|
||||
displays.add (getDisplayFromScreen (s, mainScreenBottom, masterScale));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@ static void setWindowZOrder (HWND hwnd, HWND insertAfter)
|
||||
//==============================================================================
|
||||
static void setDPIAwareness()
|
||||
{
|
||||
#if ! JUCE_DISABLE_WIN32_DPI_AWARENESS
|
||||
if (JUCEApplicationBase::isStandaloneApp())
|
||||
{
|
||||
if (setProcessDPIAwareness == nullptr)
|
||||
@@ -203,6 +204,7 @@ static void setDPIAwareness()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static double getGlobalDPI()
|
||||
@@ -704,8 +706,8 @@ public:
|
||||
r.top + windowBorder.getTop());
|
||||
}
|
||||
|
||||
Point<int> localToGlobal (Point<int> relativePosition) override { return relativePosition + getScreenPosition(); }
|
||||
Point<int> globalToLocal (Point<int> screenPosition) override { return screenPosition - getScreenPosition(); }
|
||||
Point<float> localToGlobal (Point<float> relativePosition) override { return relativePosition + getScreenPosition().toFloat(); }
|
||||
Point<float> globalToLocal (Point<float> screenPosition) override { return screenPosition - getScreenPosition().toFloat(); }
|
||||
|
||||
void setAlpha (float newAlpha) override
|
||||
{
|
||||
@@ -763,7 +765,7 @@ public:
|
||||
ShowWindow (hwnd, SW_SHOWNORMAL);
|
||||
|
||||
if (! boundsCopy.isEmpty())
|
||||
setBounds (boundsCopy, false);
|
||||
setBounds (ScalingHelpers::scaledScreenPosToUnscaled (component, boundsCopy), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -845,7 +847,7 @@ public:
|
||||
|
||||
void toBehind (ComponentPeer* other) override
|
||||
{
|
||||
if (HWNDComponentPeer* const otherPeer = dynamic_cast <HWNDComponentPeer*> (other))
|
||||
if (HWNDComponentPeer* const otherPeer = dynamic_cast<HWNDComponentPeer*> (other))
|
||||
{
|
||||
setMinimised (false);
|
||||
|
||||
@@ -877,7 +879,7 @@ public:
|
||||
shouldDeactivateTitleBar = oldDeactivate;
|
||||
}
|
||||
|
||||
void textInputRequired (const Point<int>&) override
|
||||
void textInputRequired (Point<int>, TextInputTarget&) override
|
||||
{
|
||||
if (! hasCreatedCaret)
|
||||
{
|
||||
@@ -902,10 +904,15 @@ public:
|
||||
|
||||
void performAnyPendingRepaintsNow() override
|
||||
{
|
||||
MSG m;
|
||||
if (component.isVisible()
|
||||
&& (PeekMessage (&m, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE) || isUsingUpdateLayeredWindow()))
|
||||
handlePaintMessage();
|
||||
if (component.isVisible())
|
||||
{
|
||||
WeakReference<Component> localRef (&component);
|
||||
MSG m;
|
||||
|
||||
if (isUsingUpdateLayeredWindow() || PeekMessage (&m, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
|
||||
if (localRef != nullptr) // (the PeekMessage call can dispatch messages, which may delete this comp)
|
||||
handlePaintMessage();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -955,7 +962,7 @@ public:
|
||||
static ModifierKeys modifiersAtLastCallback;
|
||||
|
||||
//==============================================================================
|
||||
class JuceDropTarget : public ComBaseClassHelper <IDropTarget>
|
||||
class JuceDropTarget : public ComBaseClassHelper<IDropTarget>
|
||||
{
|
||||
public:
|
||||
JuceDropTarget (HWNDComponentPeer& p) : ownerInfo (new OwnerInfo (p)) {}
|
||||
@@ -988,7 +995,7 @@ public:
|
||||
if (ownerInfo == nullptr)
|
||||
return S_FALSE;
|
||||
|
||||
ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos);
|
||||
ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos).roundToInt();
|
||||
const bool wasWanted = ownerInfo->owner.handleDragMove (ownerInfo->dragInfo);
|
||||
*pdwEffect = wasWanted ? (DWORD) DROPEFFECT_COPY : (DWORD) DROPEFFECT_NONE;
|
||||
return S_OK;
|
||||
@@ -999,7 +1006,7 @@ public:
|
||||
HRESULT hr = updateFileList (pDataObject);
|
||||
if (SUCCEEDED (hr))
|
||||
{
|
||||
ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos);
|
||||
ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos).roundToInt();
|
||||
const bool wasWanted = ownerInfo->owner.handleDragDrop (ownerInfo->dragInfo);
|
||||
*pdwEffect = wasWanted ? (DWORD) DROPEFFECT_COPY : (DWORD) DROPEFFECT_NONE;
|
||||
hr = S_OK;
|
||||
@@ -1013,9 +1020,10 @@ public:
|
||||
{
|
||||
OwnerInfo (HWNDComponentPeer& p) : owner (p) {}
|
||||
|
||||
Point<int> getMousePos (const POINTL& mousePos) const
|
||||
Point<float> getMousePos (const POINTL& mousePos) const
|
||||
{
|
||||
return owner.globalToLocal (Point<int> (mousePos.x, mousePos.y));
|
||||
return owner.globalToLocal (Point<float> (static_cast<float> (mousePos.x),
|
||||
static_cast<float> (mousePos.y)));
|
||||
}
|
||||
|
||||
template <typename CharType>
|
||||
@@ -1093,13 +1101,13 @@ public:
|
||||
|
||||
if (SUCCEEDED (fileData.error))
|
||||
{
|
||||
const LPDROPFILES dropFiles = static_cast <const LPDROPFILES> (fileData.data);
|
||||
const LPDROPFILES dropFiles = static_cast<const LPDROPFILES> (fileData.data);
|
||||
const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES));
|
||||
|
||||
if (dropFiles->fWide)
|
||||
ownerInfo->parseFileList (static_cast <const WCHAR*> (names), fileData.dataSize);
|
||||
ownerInfo->parseFileList (static_cast<const WCHAR*> (names), fileData.dataSize);
|
||||
else
|
||||
ownerInfo->parseFileList (static_cast <const char*> (names), fileData.dataSize);
|
||||
ownerInfo->parseFileList (static_cast<const char*> (names), fileData.dataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1294,7 +1302,7 @@ private:
|
||||
//==============================================================================
|
||||
static void* createWindowCallback (void* userData)
|
||||
{
|
||||
static_cast <HWNDComponentPeer*> (userData)->createWindow();
|
||||
static_cast<HWNDComponentPeer*> (userData)->createWindow();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1522,10 +1530,14 @@ private:
|
||||
// if something in a paint handler calls, e.g. a message box, this can become reentrant and
|
||||
// corrupt the image it's using to paint into, so do a check here.
|
||||
static bool reentrant = false;
|
||||
if (! (reentrant || dontRepaint))
|
||||
if (! reentrant)
|
||||
{
|
||||
const ScopedValueSetter<bool> setter (reentrant, true, false);
|
||||
performPaint (dc, rgn, regionType, paintStruct);
|
||||
|
||||
if (dontRepaint)
|
||||
component.handleCommandMessage (0); // (this triggers a repaint in the openGL context)
|
||||
else
|
||||
performPaint (dc, rgn, regionType, paintStruct);
|
||||
}
|
||||
|
||||
DeleteObject (rgn);
|
||||
@@ -1633,7 +1645,7 @@ private:
|
||||
handlePaint (*context);
|
||||
}
|
||||
|
||||
static_cast <WindowsBitmapImage*> (offscreenImage.getPixelData())
|
||||
static_cast<WindowsBitmapImage*> (offscreenImage.getPixelData())
|
||||
->blitToWindow (hwnd, dc, transparent, x, y, updateLayeredWindowAlpha);
|
||||
}
|
||||
|
||||
@@ -1643,7 +1655,7 @@ private:
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void doMouseEvent (Point<int> position)
|
||||
void doMouseEvent (Point<float> position)
|
||||
{
|
||||
handleMouseEvent (0, position, currentModifiers, getMouseEventTime());
|
||||
}
|
||||
@@ -1694,7 +1706,7 @@ private:
|
||||
return 1000 / 60; // Throttling the incoming mouse-events seems to still be needed in XP..
|
||||
}
|
||||
|
||||
void doMouseMove (Point<int> position)
|
||||
void doMouseMove (Point<float> position)
|
||||
{
|
||||
if (! isMouseOver)
|
||||
{
|
||||
@@ -1715,7 +1727,7 @@ private:
|
||||
}
|
||||
else if (! isDragging)
|
||||
{
|
||||
if (! contains (position, false))
|
||||
if (! contains (position.roundToInt(), false))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1730,7 +1742,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void doMouseDown (Point<int> position, const WPARAM wParam)
|
||||
void doMouseDown (Point<float> position, const WPARAM wParam)
|
||||
{
|
||||
if (GetCapture() != hwnd)
|
||||
SetCapture (hwnd);
|
||||
@@ -1743,7 +1755,7 @@ private:
|
||||
doMouseEvent (position);
|
||||
}
|
||||
|
||||
void doMouseUp (Point<int> position, const WPARAM wParam)
|
||||
void doMouseUp (Point<float> position, const WPARAM wParam)
|
||||
{
|
||||
updateModifiersFromWParam (wParam);
|
||||
const bool wasDragging = isDragging;
|
||||
@@ -1779,9 +1791,9 @@ private:
|
||||
doMouseEvent (getCurrentMousePos());
|
||||
}
|
||||
|
||||
ComponentPeer* findPeerUnderMouse (Point<int>& localPos)
|
||||
ComponentPeer* findPeerUnderMouse (Point<float>& localPos)
|
||||
{
|
||||
const Point<int> globalPos (getCurrentMousePosGlobal());
|
||||
const Point<int> globalPos (getCurrentMousePosGlobal().roundToInt());
|
||||
|
||||
// Because Windows stupidly sends all wheel events to the window with the keyboard
|
||||
// focus, we have to redirect them here according to the mouse pos..
|
||||
@@ -1791,7 +1803,7 @@ private:
|
||||
if (peer == nullptr)
|
||||
peer = this;
|
||||
|
||||
localPos = peer->globalToLocal (globalPos);
|
||||
localPos = peer->globalToLocal (globalPos.toFloat());
|
||||
return peer;
|
||||
}
|
||||
|
||||
@@ -1806,7 +1818,7 @@ private:
|
||||
wheel.isReversed = false;
|
||||
wheel.isSmooth = false;
|
||||
|
||||
Point<int> localPos;
|
||||
Point<float> localPos;
|
||||
if (ComponentPeer* const peer = findPeerUnderMouse (localPos))
|
||||
peer->handleMouseWheel (0, localPos, getMouseEventTime(), wheel);
|
||||
}
|
||||
@@ -1820,7 +1832,7 @@ private:
|
||||
if (getGestureInfo != nullptr && getGestureInfo ((HGESTUREINFO) lParam, &gi))
|
||||
{
|
||||
updateKeyModifiers();
|
||||
Point<int> localPos;
|
||||
Point<float> localPos;
|
||||
|
||||
if (ComponentPeer* const peer = findPeerUnderMouse (localPos))
|
||||
{
|
||||
@@ -1878,8 +1890,8 @@ private:
|
||||
bool isCancel = false;
|
||||
const int touchIndex = currentTouches.getIndexOfTouch (touch.dwID);
|
||||
const int64 time = getMouseEventTime();
|
||||
const Point<int> pos (globalToLocal (Point<int> ((int) TOUCH_COORD_TO_PIXEL (touch.x),
|
||||
(int) TOUCH_COORD_TO_PIXEL (touch.y))));
|
||||
const Point<float> pos (globalToLocal (Point<float> (static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.x)),
|
||||
static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.y)))));
|
||||
ModifierKeys modsToSend (currentModifiers);
|
||||
|
||||
if (isDown)
|
||||
@@ -1890,7 +1902,7 @@ private:
|
||||
if (! isPrimary)
|
||||
{
|
||||
// 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);
|
||||
handleMouseEvent (touchIndex, pos.toFloat(), modsToSend.withoutMouseButtons(), time);
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
}
|
||||
@@ -1916,14 +1928,14 @@ private:
|
||||
|
||||
if (! isPrimary)
|
||||
{
|
||||
handleMouseEvent (touchIndex, pos, modsToSend, time);
|
||||
handleMouseEvent (touchIndex, pos.toFloat(), modsToSend, time);
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((isUp || isCancel) && ! isPrimary)
|
||||
{
|
||||
handleMouseEvent (touchIndex, Point<int> (-10, -10), currentModifiers, time);
|
||||
handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, time);
|
||||
if (! isValidPeer (this))
|
||||
return false;
|
||||
}
|
||||
@@ -2203,6 +2215,22 @@ private:
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool handlePositionChanged()
|
||||
{
|
||||
const Point<float> pos (getCurrentMousePos());
|
||||
|
||||
if (contains (pos.roundToInt(), false))
|
||||
{
|
||||
doMouseEvent (pos);
|
||||
|
||||
if (! isValidPeer (this))
|
||||
return true;
|
||||
}
|
||||
|
||||
handleMovedOrResized();
|
||||
return ! dontRepaint; // to allow non-accelerated openGL windows to draw themselves correctly..
|
||||
}
|
||||
|
||||
void handleAppActivation (const WPARAM wParam)
|
||||
{
|
||||
modifiersAtLastCallback = -1;
|
||||
@@ -2213,7 +2241,7 @@ private:
|
||||
component.repaint();
|
||||
handleMovedOrResized();
|
||||
|
||||
if (! ComponentPeer::isValidPeer (this))
|
||||
if (! isValidPeer (this))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2235,6 +2263,24 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void handlePowerBroadcast (WPARAM wParam)
|
||||
{
|
||||
if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case PBT_APMSUSPEND: app->suspended(); break;
|
||||
|
||||
case PBT_APMQUERYSUSPENDFAILED:
|
||||
case PBT_APMRESUMECRITICAL:
|
||||
case PBT_APMRESUMESUSPEND:
|
||||
case PBT_APMRESUMEAUTOMATIC: app->resumed(); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleLeftClickInNCArea (WPARAM wParam)
|
||||
{
|
||||
if (! sendInputAttemptWhenModalMessage())
|
||||
@@ -2283,7 +2329,7 @@ private:
|
||||
{
|
||||
Desktop& desktop = Desktop::getInstance();
|
||||
|
||||
const_cast <Desktop::Displays&> (desktop.getDisplays()).refresh();
|
||||
const_cast<Desktop::Displays&> (desktop.getDisplays()).refresh();
|
||||
|
||||
if (fullScreen && ! isMinimised())
|
||||
{
|
||||
@@ -2321,17 +2367,18 @@ private:
|
||||
return MessageManager::getInstance()->callFunctionOnMessageThread (callback, userData);
|
||||
}
|
||||
|
||||
static Point<int> getPointFromLParam (LPARAM lParam) noexcept
|
||||
static Point<float> getPointFromLParam (LPARAM lParam) noexcept
|
||||
{
|
||||
return Point<int> (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
|
||||
return Point<float> (static_cast<float> (GET_X_LPARAM (lParam)),
|
||||
static_cast<float> (GET_Y_LPARAM (lParam)));
|
||||
}
|
||||
|
||||
static Point<int> getCurrentMousePosGlobal() noexcept
|
||||
static Point<float> getCurrentMousePosGlobal() noexcept
|
||||
{
|
||||
return getPointFromLParam (GetMessagePos());
|
||||
}
|
||||
|
||||
Point<int> getCurrentMousePos() noexcept
|
||||
Point<float> getCurrentMousePos() noexcept
|
||||
{
|
||||
return globalToLocal (getCurrentMousePosGlobal());
|
||||
}
|
||||
@@ -2411,18 +2458,10 @@ private:
|
||||
case WM_WINDOWPOSCHANGING: return handlePositionChanging (*(WINDOWPOS*) lParam);
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
const Point<int> pos (getCurrentMousePos());
|
||||
if (contains (pos, false))
|
||||
doMouseEvent (pos);
|
||||
}
|
||||
if (handlePositionChanged())
|
||||
return 0;
|
||||
|
||||
handleMovedOrResized();
|
||||
|
||||
if (dontRepaint)
|
||||
break; // needed for non-accelerated openGL windows to draw themselves correctly..
|
||||
|
||||
return 0;
|
||||
break;
|
||||
|
||||
//==============================================================================
|
||||
case WM_KEYDOWN:
|
||||
@@ -2531,6 +2570,10 @@ private:
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_POWERBROADCAST:
|
||||
handlePowerBroadcast (wParam);
|
||||
break;
|
||||
|
||||
case WM_SYNCPAINT:
|
||||
return 0;
|
||||
|
||||
@@ -2860,7 +2903,7 @@ private:
|
||||
|
||||
void moveCandidateWindowToLeftAlignWithSelection (HIMC hImc, ComponentPeer& peer, TextInputTarget* target) const
|
||||
{
|
||||
if (Component* const targetComp = dynamic_cast <Component*> (target))
|
||||
if (Component* const targetComp = dynamic_cast<Component*> (target))
|
||||
{
|
||||
const Rectangle<int> area (peer.getComponent().getLocalArea (targetComp, target->getCaretRectangle()));
|
||||
|
||||
@@ -2881,18 +2924,15 @@ private:
|
||||
ModifierKeys HWNDComponentPeer::currentModifiers;
|
||||
ModifierKeys HWNDComponentPeer::modifiersAtLastCallback;
|
||||
|
||||
ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo)
|
||||
ComponentPeer* Component::createNewPeer (int styleFlags, void* parentHWND)
|
||||
{
|
||||
return new HWNDComponentPeer (*this, styleFlags,
|
||||
(HWND) nativeWindowToAttachTo, false);
|
||||
return new HWNDComponentPeer (*this, styleFlags, (HWND) parentHWND, false);
|
||||
}
|
||||
|
||||
ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component* component, void* parent)
|
||||
ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& component, void* parentHWND)
|
||||
{
|
||||
jassert (component != nullptr);
|
||||
|
||||
return new HWNDComponentPeer (*component, ComponentPeer::windowIgnoresMouseClicks,
|
||||
(HWND) parent, true);
|
||||
return new HWNDComponentPeer (component, ComponentPeer::windowIgnoresMouseClicks,
|
||||
(HWND) parentHWND, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -2965,7 +3005,7 @@ bool JUCE_CALLTYPE Process::isForegroundProcess()
|
||||
fg = GetAncestor (fg, GA_ROOT);
|
||||
|
||||
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
|
||||
if (HWNDComponentPeer* const wp = dynamic_cast <HWNDComponentPeer*> (ComponentPeer::getPeer (i)))
|
||||
if (HWNDComponentPeer* const wp = dynamic_cast<HWNDComponentPeer*> (ComponentPeer::getPeer (i)))
|
||||
if (wp->isInside (fg))
|
||||
return true;
|
||||
|
||||
@@ -2991,7 +3031,7 @@ static BOOL CALLBACK enumAlwaysOnTopWindows (HWND hwnd, LPARAM lParam)
|
||||
if (GetWindowInfo (hwnd, &info)
|
||||
&& (info.dwExStyle & WS_EX_TOPMOST) != 0)
|
||||
{
|
||||
*reinterpret_cast <bool*> (lParam) = true;
|
||||
*reinterpret_cast<bool*> (lParam) = true;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -3126,16 +3166,17 @@ bool MouseInputSource::SourceList::addSource()
|
||||
return false;
|
||||
}
|
||||
|
||||
Point<int> MouseInputSource::getCurrentRawMousePosition()
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
POINT mousePos;
|
||||
GetCursorPos (&mousePos);
|
||||
return Point<int> (mousePos.x, mousePos.y);
|
||||
return Point<float> ((float) mousePos.x, (float) mousePos.y);
|
||||
}
|
||||
|
||||
void MouseInputSource::setRawMousePosition (Point<int> newPosition)
|
||||
void MouseInputSource::setRawMousePosition (Point<float> newPosition)
|
||||
{
|
||||
SetCursorPos (newPosition.x, newPosition.y);
|
||||
SetCursorPos (roundToInt (newPosition.x),
|
||||
roundToInt (newPosition.y));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -3195,7 +3236,7 @@ void SystemClipboard::copyTextToClipboard (const String& text)
|
||||
{
|
||||
if (HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bytesNeeded + sizeof (WCHAR)))
|
||||
{
|
||||
if (WCHAR* const data = static_cast <WCHAR*> (GlobalLock (bufH)))
|
||||
if (WCHAR* const data = static_cast<WCHAR*> (GlobalLock (bufH)))
|
||||
{
|
||||
text.copyToUTF16 (data, bytesNeeded);
|
||||
GlobalUnlock (bufH);
|
||||
|
||||
Reference in New Issue
Block a user