diff options
Diffstat (limited to 'platform/macos/display_server_macos.mm')
| -rw-r--r-- | platform/macos/display_server_macos.mm | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index e8eb5b419b..9ef1446ea3 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -130,7 +130,7 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod wpos.x = CLAMP(wpos.x, srect.position.x, srect.position.x + srect.size.width - p_rect.size.width / 3); wpos.y = CLAMP(wpos.y, srect.position.y, srect.position.y + srect.size.height - p_rect.size.height / 3); } - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot passes a positive value. wpos.y *= -1; wpos += _get_screens_origin(); @@ -329,7 +329,7 @@ Point2i DisplayServerMacOS::_get_screens_origin() const { // Returns the native top-left screen coordinate of the smallest rectangle // that encompasses all screens. Needed in get_screen_position(), // window_get_position, and window_set_position() - // to convert between OS X native screen coordinates and the ones expected by Godot. + // to convert between macOS native screen coordinates and the ones expected by Godot. if (displays_arrangement_dirty) { const_cast<DisplayServerMacOS *>(this)->_update_displays_arrangement(); @@ -342,7 +342,7 @@ Point2i DisplayServerMacOS::_get_native_screen_position(int p_screen) const { NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; - // Return the top-left corner of the screen, for OS X the y starts at the bottom. + // Return the top-left corner of the screen, for macOS the y starts at the bottom. return Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * screen_get_max_scale(); } @@ -765,6 +765,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_TEXT_TO_SPEECH: case FEATURE_EXTEND_TO_TITLE: + case FEATURE_SCREEN_CAPTURE: return true; default: { } @@ -2126,7 +2127,7 @@ Point2i DisplayServerMacOS::screen_get_position(int p_screen) const { } Point2i position = _get_native_screen_position(p_screen) - _get_screens_origin(); - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot expects a positive value. position.y *= -1; return position; @@ -2249,6 +2250,35 @@ Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const { return Rect2i(); } +Color DisplayServerMacOS::screen_get_pixel(const Point2i &p_position) const { + Point2i position = p_position; + // macOS native y-coordinate relative to _get_screens_origin() is negative, + // Godot passes a positive value. + position.y *= -1; + position += _get_screens_origin(); + position /= screen_get_max_scale(); + + for (NSScreen *screen in [NSScreen screens]) { + NSRect frame = [screen frame]; + if (NSMouseInRect(NSMakePoint(position.x, position.y), frame, NO)) { + NSDictionary *screenDescription = [screen deviceDescription]; + CGDirectDisplayID display_id = [[screenDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; + CGImageRef image = CGDisplayCreateImageForRect(display_id, CGRectMake(position.x - frame.origin.x, frame.size.height - (position.y - frame.origin.y), 1, 1)); + if (image) { + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; + CGImageRelease(image); + NSColor *color = [bitmap colorAtX:0 y:0]; + if (color) { + CGFloat components[4]; + [color getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; + return Color(components[0], components[1], components[2], components[3]); + } + } + } + } + return Color(); +} + float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ @@ -2502,13 +2532,13 @@ Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const { const NSRect nsrect = [wd.window_object convertRectToScreen:contentRect]; Point2i pos; - // Return the position of the top-left corner, for OS X the y starts at the bottom. + // Return the position of the top-left corner, for macOS the y starts at the bottom. const float scale = screen_get_max_scale(); pos.x = nsrect.origin.x; pos.y = (nsrect.origin.y + nsrect.size.height); pos *= scale; pos -= _get_screens_origin(); - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot expects a positive value. pos.y *= -1; return pos; @@ -2523,13 +2553,13 @@ Point2i DisplayServerMacOS::window_get_position_with_decorations(WindowID p_wind const NSRect nsrect = [wd.window_object frame]; Point2i pos; - // Return the position of the top-left corner, for OS X the y starts at the bottom. + // Return the position of the top-left corner, for macOS the y starts at the bottom. const float scale = screen_get_max_scale(); pos.x = nsrect.origin.x; pos.y = (nsrect.origin.y + nsrect.size.height); pos *= scale; pos -= _get_screens_origin(); - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot expects a positive value. pos.y *= -1; return pos; @@ -2546,7 +2576,7 @@ void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID } Point2i position = p_position; - // OS X native y-coordinate relative to _get_screens_origin() is negative, + // macOS native y-coordinate relative to _get_screens_origin() is negative, // Godot passes a positive value. position.y *= -1; position += _get_screens_origin(); @@ -3491,14 +3521,16 @@ void DisplayServerMacOS::process_events() { } // Process "menu_callback"s. - for (MenuCall &E : deferred_menu_calls) { - Variant tag = E.tag; + while (List<MenuCall>::Element *call_p = deferred_menu_calls.front()) { + MenuCall call = call_p->get(); + deferred_menu_calls.pop_front(); // Remove before call to avoid infinite loop in case callback is using `process_events` (e.g. EditorProgress). + + Variant tag = call.tag; Variant *tagp = &tag; Variant ret; Callable::CallError ce; - E.callback.callp((const Variant **)&tagp, 1, ret, ce); + call.callback.callp((const Variant **)&tagp, 1, ret, ce); } - deferred_menu_calls.clear(); if (!drop_events) { _process_key_events(); @@ -3617,15 +3649,15 @@ DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, if (p_rendering_driver == "vulkan") { String executable_command; if (OS::get_singleton()->get_bundle_resource_dir() == OS::get_singleton()->get_executable_path().get_base_dir()) { - executable_command = vformat("%s --rendering-driver opengl3", OS::get_singleton()->get_executable_path()); + executable_command = vformat("\"%s\" --rendering-driver opengl3", OS::get_singleton()->get_executable_path()); } else { - executable_command = vformat("open %s --args --rendering-driver opengl3", OS::get_singleton()->get_bundle_resource_dir().path_join("../..").simplify_path()); + executable_command = vformat("open \"%s\" --args --rendering-driver opengl3", OS::get_singleton()->get_bundle_resource_dir().path_join("../..").simplify_path()); } OS::get_singleton()->alert( vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" "If possible, consider updating your macOS version or using the OpenGL 3 driver.\n\n" "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n'%s'", + "command line with the command:\n\n %s", executable_command), "Unable to initialize Vulkan video driver"); } else { |
