Skip to content

Commit

Permalink
Expose getters for the currently focused Window
Browse files Browse the repository at this point in the history
Replace the last focused Window by the currently focused Window
on Linux, Windows and macOS.
  • Loading branch information
Sauermann authored and rsubtil committed Sep 6, 2023
1 parent 9652e29 commit c8de3a5
Show file tree
Hide file tree
Showing 13 changed files with 56 additions and 21 deletions.
6 changes: 6 additions & 0 deletions doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@
[b]Note:[/b] This doesn't affect native dialogs such as the ones spawned by [method DisplayServer.dialog_show].
</description>
</method>
<method name="get_top_popup_or_focused_window" qualifiers="const">
<return type="int" />
<description>
Returns the [method Object.get_instance_id] of the top [Popup] if available or of the currently focused [Window].
</description>
</method>
<method name="get_window_at_screen_position" qualifiers="const">
<return type="int" />
<param index="0" name="position" type="Vector2i" />
Expand Down
6 changes: 6 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@
[/codeblock]
</description>
</method>
<method name="get_top_popup_or_focused_window" qualifiers="const">
<return type="Window" />
<description>
Returns the top [Popup] if available or the currently focused [Window].
</description>
</method>
<method name="get_viewport_rid" qualifiers="const">
<return type="RID" />
<description>
Expand Down
5 changes: 3 additions & 2 deletions platform/linuxbsd/x11/display_server_x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3741,7 +3741,7 @@ DisplayServer::WindowID DisplayServerX11::_get_focused_window_or_popup() const {
return E->get();
}

return last_focused_window;
return currently_focused_window;
}

void DisplayServerX11::_dispatch_input_events(const Ref<InputEvent> &p_event) {
Expand Down Expand Up @@ -4346,7 +4346,7 @@ void DisplayServerX11::process_events() {
}

WindowData &wd = windows[window_id];
last_focused_window = window_id;
currently_focused_window = window_id;
wd.focused = true;

// Keep track of focus order for overlapping windows.
Expand Down Expand Up @@ -4401,6 +4401,7 @@ void DisplayServerX11::process_events() {
im_selection = Vector2i();
OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
}
currently_focused_window = INVALID_WINDOW_ID;
wd.focused = false;

Input::get_singleton()->release_pressed_events();
Expand Down
4 changes: 2 additions & 2 deletions platform/linuxbsd/x11/display_server_x11.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class DisplayServerX11 : public DisplayServer {
List<WindowID> popup_list;

WindowID window_mouseover_id = INVALID_WINDOW_ID;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID currently_focused_window = INVALID_WINDOW_ID;

WindowID window_id_counter = MAIN_WINDOW_ID;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
Expand Down Expand Up @@ -348,7 +348,7 @@ class DisplayServerX11 : public DisplayServer {

Context context = CONTEXT_ENGINE;

WindowID _get_focused_window_or_popup() const;
virtual WindowID _get_focused_window_or_popup() const override;

void _send_window_event(const WindowData &wd, WindowEvent p_event);
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
Expand Down
6 changes: 3 additions & 3 deletions platform/macos/display_server_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class DisplayServerMacOS : public DisplayServer {
bool keyboard_layout_dirty = true;

WindowID window_mouseover_id = INVALID_WINDOW_ID;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID currently_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
float display_max_scale = 1.f;
Point2i origin;
Expand Down Expand Up @@ -233,14 +233,14 @@ class DisplayServerMacOS : public DisplayServer {
void push_to_key_event_buffer(const KeyEvent &p_event);
void pop_last_key_event();
void update_im_text(const Point2i &p_selection, const String &p_text);
void set_last_focused_window(WindowID p_window);
void set_currently_focused_window(WindowID p_window);
bool mouse_process_popups(bool p_close = false);
void popup_open(WindowID p_window);
void popup_close(WindowID p_window);
void set_is_resizing(bool p_is_resizing);
bool get_is_resizing() const;
void reparent_check(WindowID p_window);
WindowID _get_focused_window_or_popup() const;
virtual WindowID _get_focused_window_or_popup() const override;
void mouse_enter_window(WindowID p_window);
void mouse_exit_window(WindowID p_window);

Expand Down
6 changes: 3 additions & 3 deletions platform/macos/display_server_macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@
return E->get();
}

return last_focused_window;
return currently_focused_window;
}

void DisplayServerMacOS::mouse_enter_window(WindowID p_window) {
Expand Down Expand Up @@ -718,8 +718,8 @@
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
}

void DisplayServerMacOS::set_last_focused_window(WindowID p_window) {
last_focused_window = p_window;
void DisplayServerMacOS::set_currently_focused_window(WindowID p_window) {
currently_focused_window = p_window;
}

void DisplayServerMacOS::set_is_resizing(bool p_is_resizing) {
Expand Down
6 changes: 4 additions & 2 deletions platform/macos/godot_window_delegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ - (void)windowDidBecomeKey:(NSNotification *)notification {
[self windowDidResize:notification]; // Emit resize event, to ensure content is resized if the window was resized while it was hidden.

wd.focused = true;
ds->set_last_focused_window(window_id);
ds->set_currently_focused_window(window_id);
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}

Expand All @@ -333,6 +333,7 @@ - (void)windowDidResignKey:(NSNotification *)notification {
}

wd.focused = false;
ds->set_currently_focused_window(DisplayServerMacOS::INVALID_WINDOW_ID);
ds->release_pressed_events();
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
Expand All @@ -346,6 +347,7 @@ - (void)windowDidMiniaturize:(NSNotification *)notification {
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);

wd.focused = false;
ds->set_currently_focused_window(DisplayServerMacOS::INVALID_WINDOW_ID);
ds->release_pressed_events();
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
Expand All @@ -359,7 +361,7 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification {
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if ([wd.window_object isKeyWindow]) {
wd.focused = true;
ds->set_last_focused_window(window_id);
ds->set_currently_focused_window(window_id);
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
}
Expand Down
14 changes: 7 additions & 7 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ DisplayServer::WindowID DisplayServerWindows::_get_focused_window_or_popup() con
return E->get();
}

return last_focused_window;
return currently_focused_window;
}

void DisplayServerWindows::_register_raw_input_devices(WindowID p_target_window) {
Expand Down Expand Up @@ -476,10 +476,10 @@ String DisplayServerWindows::clipboard_get() const {

Ref<Image> DisplayServerWindows::clipboard_get_image() const {
Ref<Image> image;
if (!windows.has(last_focused_window)) {
if (!windows.has(currently_focused_window)) {
return image; // No focused window?
}
if (!OpenClipboard(windows[last_focused_window].hWnd)) {
if (!OpenClipboard(windows[currently_focused_window].hWnd)) {
ERR_FAIL_V_MSG(image, "Unable to open clipboard.");
}
UINT png_format = RegisterClipboardFormatA("PNG");
Expand Down Expand Up @@ -1082,8 +1082,8 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
DestroyWindow(windows[p_window].hWnd);
windows.erase(p_window);

if (last_focused_window == p_window) {
last_focused_window = INVALID_WINDOW_ID;
if (currently_focused_window == p_window) {
currently_focused_window = INVALID_WINDOW_ID;
}
}

Expand Down Expand Up @@ -2843,7 +2843,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_SETFOCUS: {
windows[window_id].window_has_focus = true;
last_focused_window = window_id;
currently_focused_window = window_id;

// Restore mouse mode.
_set_mouse_mode_impl(mouse_mode);
Expand All @@ -2857,7 +2857,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_KILLFOCUS: {
windows[window_id].window_has_focus = false;
last_focused_window = window_id;
currently_focused_window = INVALID_WINDOW_ID;

// Release capture unconditionally because it can be set due to dragging, in addition to captured mode.
ReleaseCapture();
Expand Down
4 changes: 2 additions & 2 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ class DisplayServerWindows : public DisplayServer {
WindowID window_id_counter = MAIN_WINDOW_ID;
RBMap<WindowID, WindowData> windows;

WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID currently_focused_window = INVALID_WINDOW_ID;

HCURSOR hCursor;

Expand Down Expand Up @@ -476,7 +476,7 @@ class DisplayServerWindows : public DisplayServer {
void _update_real_mouse_position(WindowID p_window);

void _set_mouse_mode_impl(MouseMode p_mode);
WindowID _get_focused_window_or_popup() const;
virtual WindowID _get_focused_window_or_popup() const override;
void _register_raw_input_devices(WindowID p_target_window);

void _process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam);
Expand Down
5 changes: 5 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2450,6 +2450,10 @@ Window *Viewport::get_base_window() const {
return w;
}

Window *Viewport::get_top_popup_or_focused_window() const {
return gui.subwindow_focused;
}

void Viewport::_gui_remove_focus_for_window(Node *p_window) {
if (get_base_window() == p_window) {
gui_release_focus();
Expand Down Expand Up @@ -4427,6 +4431,7 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_embedding_subwindows", "enable"), &Viewport::set_embedding_subwindows);
ClassDB::bind_method(D_METHOD("is_embedding_subwindows"), &Viewport::is_embedding_subwindows);
ClassDB::bind_method(D_METHOD("get_embedded_subwindows"), &Viewport::get_embedded_subwindows);
ClassDB::bind_method(D_METHOD("get_top_popup_or_focused_window"), &Viewport::get_top_popup_or_focused_window);

ClassDB::bind_method(D_METHOD("set_canvas_cull_mask", "mask"), &Viewport::set_canvas_cull_mask);
ClassDB::bind_method(D_METHOD("get_canvas_cull_mask"), &Viewport::get_canvas_cull_mask);
Expand Down
1 change: 1 addition & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ class Viewport : public Node {

Viewport *get_parent_viewport() const;
Window *get_base_window() const;
Window *get_top_popup_or_focused_window() const;

void pass_mouse_focus_to(Viewport *p_viewport, Control *p_control);

Expand Down
9 changes: 9 additions & 0 deletions servers/display_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,14 @@ void DisplayServer::delete_sub_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}

ObjectID DisplayServer::get_top_popup_or_focused_window() const {
WindowID wid = _get_focused_window_or_popup();
if (wid == INVALID_WINDOW_ID) {
return ObjectID();
}
return window_get_attached_instance_id(wid);
}

void DisplayServer::window_set_exclusive(WindowID p_window, bool p_exclusive) {
// Do nothing, if not supported.
}
Expand Down Expand Up @@ -689,6 +697,7 @@ void DisplayServer::_bind_methods() {

ClassDB::bind_method(D_METHOD("get_window_list"), &DisplayServer::get_window_list);
ClassDB::bind_method(D_METHOD("get_window_at_screen_position", "position"), &DisplayServer::get_window_at_screen_position);
ClassDB::bind_method(D_METHOD("get_top_popup_or_focused_window"), &DisplayServer::get_top_popup_or_focused_window);

ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_get_active_popup"), &DisplayServer::window_get_active_popup);
Expand Down
5 changes: 5 additions & 0 deletions servers/display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ class DisplayServer : public Object {

typedef int WindowID;

private:
virtual WindowID _get_focused_window_or_popup() const { return MAIN_WINDOW_ID; };

public:
virtual Vector<DisplayServer::WindowID> get_window_list() const = 0;

enum WindowFlags {
Expand Down Expand Up @@ -367,6 +371,7 @@ class DisplayServer : public Object {
virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const;

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
ObjectID get_top_popup_or_focused_window() const;

virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const = 0;
Expand Down

0 comments on commit c8de3a5

Please sign in to comment.