Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions core/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ int _OS::get_mouse_button_state() const {
return OS::get_singleton()->get_mouse_button_state();
}

void _OS::set_drag_mode(DragMode p_drag_mode) {

OS::get_singleton()->set_drag_mode(OS::DragMode(p_drag_mode));
}

_OS::DragMode _OS::get_drag_mode() const {

return DragMode(OS::get_singleton()->get_drag_mode());
}

String _OS::get_unique_id() const {
return OS::get_singleton()->get_unique_id();
}
Expand Down Expand Up @@ -1145,6 +1155,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_touchscreen_ui_hint"), &_OS::has_touchscreen_ui_hint);

ClassDB::bind_method(D_METHOD("set_window_title", "title"), &_OS::set_window_title);
ClassDB::bind_method(D_METHOD("set_drag_mode", "drag_mode"), &_OS::set_drag_mode);
ClassDB::bind_method(D_METHOD("get_drag_mode"), &_OS::get_drag_mode);

ClassDB::bind_method(D_METHOD("set_low_processor_usage_mode", "enable"), &_OS::set_low_processor_usage_mode);
ClassDB::bind_method(D_METHOD("is_in_low_processor_usage_mode"), &_OS::is_in_low_processor_usage_mode);
Expand Down Expand Up @@ -1251,6 +1263,7 @@ void _OS::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_screen_on"), "set_keep_screen_on", "is_keep_screen_on");
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"), "set_screen_orientation", "get_screen_orientation");
ADD_GROUP("Window", "window_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "drag_mode", PROPERTY_HINT_ENUM, "None,Move,Resize Top,Resize Left,Resize Bottom,Resize Right,Resize Top Left,Resize Top Right,Resize Bottom Right,Resize Bottom Left"), "set_drag_mode", "get_drag_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_borderless"), "set_borderless_window", "get_borderless_window");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_per_pixel_transparency_enabled"), "set_window_per_pixel_transparency_enabled", "get_window_per_pixel_transparency_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_fullscreen"), "set_window_fullscreen", "is_window_fullscreen");
Expand Down Expand Up @@ -1281,6 +1294,17 @@ void _OS::_bind_methods() {
BIND_ENUM_CONSTANT(MONTH_NOVEMBER);
BIND_ENUM_CONSTANT(MONTH_DECEMBER);

BIND_ENUM_CONSTANT(DRAG_MODE_NONE);
BIND_ENUM_CONSTANT(DRAG_MODE_MOVE);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_TOP);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_RIGHT);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_BOTTOM);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_LEFT);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_TOPLEFT);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_TOPRIGHT);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_BOTTOMRIGHT);
BIND_ENUM_CONSTANT(DRAG_MODE_RESIZE_BOTTOMLEFT);

BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_LANDSCAPE);
BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_PORTRAIT);
BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
Expand Down
18 changes: 18 additions & 0 deletions core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ class _OS : public Object {
void set_window_title(const String &p_title);
int get_mouse_button_state() const;

enum DragMode {

DRAG_MODE_NONE,
DRAG_MODE_MOVE,
DRAG_MODE_RESIZE_TOP,
DRAG_MODE_RESIZE_RIGHT,
DRAG_MODE_RESIZE_BOTTOM,
DRAG_MODE_RESIZE_LEFT,
DRAG_MODE_RESIZE_TOPLEFT,
DRAG_MODE_RESIZE_TOPRIGHT,
DRAG_MODE_RESIZE_BOTTOMRIGHT,
DRAG_MODE_RESIZE_BOTTOMLEFT
};

void set_drag_mode(DragMode p_drag_mode);
DragMode get_drag_mode() const;

void set_clipboard(const String &p_text);
String get_clipboard() const;

Expand Down Expand Up @@ -357,6 +374,7 @@ VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
VARIANT_ENUM_CAST(_OS::DragMode);

class _Geometry : public Object {

Expand Down
5 changes: 5 additions & 0 deletions core/os/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ void OS::native_video_stop(){
void OS::set_mouse_mode(MouseMode p_mode) {
}

void OS::set_drag_mode(DragMode p_drag_mode) {
}

bool OS::can_use_threads() const {

#ifdef NO_THREADS
Expand All @@ -524,6 +527,8 @@ OS::MouseMode OS::get_mouse_mode() const {
return MOUSE_MODE_VISIBLE;
}

OS::DragMode OS::get_drag_mode() const { return DRAG_MODE_NONE; }

OS::LatinKeyboardVariant OS::get_latin_keyboard_variant() const {

return LATIN_KEYBOARD_QWERTY;
Expand Down
16 changes: 16 additions & 0 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ class OS {
virtual void set_mouse_mode(MouseMode p_mode);
virtual MouseMode get_mouse_mode() const;

enum DragMode {
DRAG_MODE_NONE,
DRAG_MODE_MOVE,
DRAG_MODE_RESIZE_TOP,
DRAG_MODE_RESIZE_RIGHT,
DRAG_MODE_RESIZE_BOTTOM,
DRAG_MODE_RESIZE_LEFT,
DRAG_MODE_RESIZE_TOPLEFT,
DRAG_MODE_RESIZE_TOPRIGHT,
DRAG_MODE_RESIZE_BOTTOMRIGHT,
DRAG_MODE_RESIZE_BOTTOMLEFT
};

virtual void set_drag_mode(DragMode p_drag_mode);
virtual DragMode get_drag_mode() const;

virtual void warp_mouse_position(const Point2 &p_to) {}
virtual Point2 get_mouse_position() const = 0;
virtual int get_mouse_button_state() const = 0;
Expand Down
52 changes: 52 additions & 0 deletions doc/classes/OS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@
Returns the current state of the device regarding battery and power. See [code]POWERSTATE_*[/code] constants.
</description>
</method>
<method name="get_drag_mode">
<return type="int" enum="OS.DragMode">
</return>
<description>
Returns the current window manager drag mode. (What action the window manager will take when the left mouse button is pressed and dragged in the window. Only valid on the [code]X11[/code] and [code]OSX[/code] platforms at the moment. See [code]DRAG_MODE_*[/code] constants.
</description>
</method>
<method name="get_process_id" qualifiers="const">
<return type="int">
</return>
Expand Down Expand Up @@ -663,6 +670,15 @@
Sets the game's icon.
</description>
</method>
<method name="set_drag_mode">
<return type="void">
</return>
<argument index="0" name="drag_mode" type="int" enum="OS.DragMode">
</argument>
<description>
Sets the window manager drag mode. (What action the window manager will take when the left mouse button is pressed and dragged in the window.) Useful for implementing custom window dragging and resize handles. Only valid on the [code]X11[/code] and [code]OSX[/code] platforms at the moment. Valid arguments are the [code]DRAG_MODE_*[/code] constants.
</description>
</method>
<method name="set_ime_position">
<return type="void">
</return>
Expand Down Expand Up @@ -773,6 +789,9 @@
<member name="window_size" type="Vector2" setter="set_window_size" getter="get_window_size">
The size of the window (without counting window manager decorations).
</member>
<member name="drag_mode" type="int" enum="OS.DragMode" setter="set_drag_mode" getter="get_drag_mode">
The window manager drag mode. (What action the window manager will take when the left mouse button is pressed and dragged in the window.) Used for implementing custom window dragging and resize handles. Only valid on the [code]X11[/code] and [code]OSX[/code] platforms at the moment. Valid arguments are the [code]DRAG_MODE_*[/code] constants.
</member>
</members>
<constants>
<constant name="DAY_SUNDAY" value="0" enum="Weekday">
Expand Down Expand Up @@ -892,5 +911,38 @@
<constant name="POWERSTATE_CHARGED" value="4" enum="PowerState">
Plugged in, battery fully charged.
</constant>
<constant name="DRAG_MODE_NONE" value="0" enum="DragMode">
Tells the window manager to ignore the click / drag and passes it to your game (default).
While any state other than [code]DRAG_MODE_NONE[/code] is active, mouse events will not be passed to your game.
[code]DRAG_MODE_NONE[/code] is the only valid mode when the mouse is constrained or grabbed by your window.
Once the window manager has completed an action other than [code]DRAG_MODE_NONE[/code] the mode will be automatically reset to [code]DRAG_MODE_NONE[/code].
</constant>
<constant name="DRAG_MODE_MOVE" value="1" enum="DragMode">
Tells the window manger to start moving your window.
</constant>
<constant name="DRAG_MODE_RESIZE_TOP" value="2" enum="DragMode">
Tells the window manger to resize your window from the top.
</constant>
<constant name="DRAG_MODE_RESIZE_RIGHT" value="3" enum="DragMode">
Tells the window manger to resize your window from the right.
</constant>
<constant name="DRAG_MODE_RESIZE_BOTTOM" value="4" enum="DragMode">
Tells the window manger to resize your window from the bottom.
</constant>
<constant name="DRAG_MODE_RESIZE_LEFT" value="5" enum="DragMode">
Tells the window manger to resize your window from the left.
</constant>
<constant name="DRAG_MODE_RESIZE_TOPLEFT" value="6" enum="DragMode">
Tells the window manger to resize your window from the top-left corner.
</constant>
<constant name="DRAG_MODE_RESIZE_TOPRIGHT" value="7" enum="DragMode">
Tells the window manger to resize your window from the top-right corner.
</constant>
<constant name="DRAG_MODE_RESIZE_BOTTOMRIGHT" value="8" enum="DragMode">
Tells the window manger to resize your window from the bottom-right corner.
</constant>
<constant name="DRAG_MODE_RESIZE_BOTTOMLEFT" value="9" enum="DragMode">
Tells the window manger to resize your window from the bottom-left corner.
</constant>
</constants>
</class>
5 changes: 5 additions & 0 deletions platform/osx/os_osx.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class OS_OSX : public OS_Unix {
CursorShape cursor_shape;
NSCursor *cursors[CURSOR_MAX];
MouseMode mouse_mode;
DragMode drag_mode;

String title;
bool minimized;
Expand Down Expand Up @@ -263,6 +264,10 @@ class OS_OSX : public OS_Unix {
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;

void set_drag_mode(DragMode p_drag_mode);
OS::DragMode get_drag_mode() const;
bool process_drag_mode(NSEvent *event);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • OS_OSX::process_drag_mode() is defined but not implemented (probably copy-paste from X11)
  • X11 and Windows platforms don't set default drag_mode value (DRAG_MODE_NONE).


void disable_crash_handler();
bool is_disable_crash_handler() const;

Expand Down
92 changes: 88 additions & 4 deletions platform/osx/os_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ - (BOOL)canBecomeKeyView {
return YES;
}

- (BOOL)mouseDownCanMoveWindow {
return YES;
}

- (BOOL)acceptsFirstResponder {
return YES;
}
Expand Down Expand Up @@ -591,18 +595,75 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
- (void)mouseDown:(NSEvent *)event {
if (([event modifierFlags] & NSEventModifierFlagControl)) {
mouse_down_control = true;

_mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true);
} else {
mouse_down_control = false;
_mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, true);
if (OS_OSX::singleton->drag_mode != OS::DRAG_MODE_MOVE) {
_mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, true);
}
}
}

- (void)mouseDragged:(NSEvent *)event {
[self mouseMoved:event];
// Prevent from being both movable and recieving drag events.
if ([[event window] isMovableByWindowBackground]) {
return;
}

NSRect frame = [[event window] frame];
switch (OS_OSX::singleton->drag_mode) {
case OS::DRAG_MODE_RESIZE_TOP:
[[event window] setFrame:NSMakeRect(
frame.origin.x, frame.origin.y, frame.size.width, frame.size.height - event.deltaY)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_BOTTOM:
[[event window] setFrame:NSMakeRect(
frame.origin.x, frame.origin.y - event.deltaY, frame.size.width, frame.size.height + event.deltaY)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_LEFT:
[[event window] setFrame:NSMakeRect(
frame.origin.x + event.deltaX, frame.origin.y, frame.size.width - event.deltaX, frame.size.height)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_RIGHT:
[[event window] setFrame:NSMakeRect(
frame.origin.x, frame.origin.y, frame.size.width + event.deltaX, frame.size.height)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_TOPLEFT:
[[event window] setFrame:NSMakeRect(
frame.origin.x + event.deltaX, frame.origin.y, frame.size.width - event.deltaX, frame.size.height - event.deltaY)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_BOTTOMLEFT:
[[event window] setFrame:NSMakeRect(
frame.origin.x + event.deltaX, frame.origin.y - event.deltaY, frame.size.width - event.deltaX, frame.size.height + event.deltaY)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_TOPRIGHT:
[[event window] setFrame:NSMakeRect(
frame.origin.x, frame.origin.y, frame.size.width + event.deltaX, frame.size.height - event.deltaY)
display:YES];
break;
case OS::DRAG_MODE_RESIZE_BOTTOMRIGHT:
[[event window] setFrame:NSMakeRect(
frame.origin.x, frame.origin.y - event.deltaY, frame.size.width + event.deltaX, frame.size.height + event.deltaY)
display:YES];
break;
default:
[self mouseMoved:event];
}
}

- (void)mouseUp:(NSEvent *)event {
if (OS_OSX::singleton->drag_mode == OS::DRAG_MODE_MOVE && [event clickCount] == 2) {
OS_OSX::singleton->set_window_maximized(!OS_OSX::singleton->is_window_maximized());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On macOS double-clicking window title should minimize window not maximize, and there's nothing like this implemented on other platforms.

return;
}

if (mouse_down_control) {
_mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, false);
} else {
Expand All @@ -623,8 +684,8 @@ - (void)mouseMoved:(NSEvent *)event {
mm->set_position(pos);
mm->set_global_position(pos);
Vector2 relativeMotion = Vector2();
relativeMotion.x = [event deltaX] * OS_OSX::singleton -> _mouse_scale(backingScaleFactor);
relativeMotion.y = [event deltaY] * OS_OSX::singleton -> _mouse_scale(backingScaleFactor);
relativeMotion.x = [event deltaX] * OS_OSX::singleton->_mouse_scale(backingScaleFactor);
relativeMotion.y = [event deltaY] * OS_OSX::singleton->_mouse_scale(backingScaleFactor);
mm->set_relative(relativeMotion);
get_key_modifier_state([event modifierFlags], mm);

Expand Down Expand Up @@ -1134,6 +1195,10 @@ - (BOOL)canBecomeKeyWindow {
return YES;
}

- (BOOL)mouseDownCanMoveWindow {
return YES;
}

@end

void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {
Expand Down Expand Up @@ -1273,6 +1338,9 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay
[window_object center];

[window_object setRestorable:NO];
if (p_desired.borderless_window) {
[window_object setHasShadow:YES];
}

unsigned int attributeCount = 0;

Expand Down Expand Up @@ -2321,6 +2389,7 @@ static int get_screen_index(NSScreen *screen) {

if (p_borderless) {
[window_object setStyleMask:NSWindowStyleMaskBorderless];
[window_object setHasShadow:YES];
} else {
if (layered_window)
set_window_per_pixel_transparency_enabled(false);
Expand Down Expand Up @@ -2580,6 +2649,20 @@ static int get_screen_index(NSScreen *screen) {
return mouse_mode;
}

void OS_OSX::set_drag_mode(DragMode p_drag_mode) {
if (p_drag_mode == DRAG_MODE_MOVE) {
[window_object setMovableByWindowBackground:YES];
} else {
[window_object setMovableByWindowBackground:NO];
}

drag_mode = p_drag_mode;
}

OS::DragMode OS_OSX::get_drag_mode() const {
return drag_mode;
}

String OS_OSX::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
Expand Down Expand Up @@ -2633,6 +2716,7 @@ static int get_screen_index(NSScreen *screen) {
memset(cursors, 0, sizeof(cursors));
key_event_pos = 0;
mouse_mode = OS::MOUSE_MODE_VISIBLE;
drag_mode = OS::DRAG_MODE_NONE;
main_loop = NULL;
singleton = this;
im_active = false;
Expand Down
Loading