Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup fixes for X11 display server #41456

Merged
merged 4 commits into from Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
249 changes: 168 additions & 81 deletions platform/linuxbsd/display_server_x11.cpp

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions platform/linuxbsd/display_server_x11.h
Expand Up @@ -132,6 +132,9 @@ class DisplayServerX11 : public DisplayServer {

ObjectID instance_id;

bool menu_type = false;
bool no_focus = false;

//better to guess on the fly, given WM can change it
//WindowMode mode;
bool fullscreen = false; //OS can't exit from this mode
Expand Down Expand Up @@ -277,6 +280,7 @@ class DisplayServerX11 : public DisplayServer {
virtual Vector<DisplayServer::WindowID> get_window_list() const;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
Expand Down
1 change: 1 addition & 0 deletions platform/osx/display_server_osx.h
Expand Up @@ -230,6 +230,7 @@ class DisplayServerOSX : public DisplayServer {
virtual Vector<int> get_window_list() const override;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;

virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
Expand Down
11 changes: 8 additions & 3 deletions platform/osx/display_server_osx.mm
Expand Up @@ -2314,18 +2314,23 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay
_THREAD_SAFE_METHOD_

WindowID id = _create_window(p_mode, p_rect);
WindowData &wd = windows[id];
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
}
}

return id;
}

void DisplayServerOSX::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];

if (wd.no_focus) {
[wd.window_object orderFront:nil];
} else {
[wd.window_object makeKeyAndOrderFront:nil];
}
return id;
}

void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) {
Expand Down Expand Up @@ -3774,7 +3779,7 @@ Point2i window_position(
window_set_flag(WindowFlags(i), true, main_window);
}
}
[windows[main_window].window_object makeKeyAndOrderFront:nil];
show_window(MAIN_WINDOW_ID);

#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
Expand Down
20 changes: 12 additions & 8 deletions platform/windows/display_server_windows.cpp
Expand Up @@ -493,15 +493,21 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
wd.no_focus = true;
}

_update_window_style(window_id);
return window_id;
}

ShowWindow(wd.hWnd, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
if (!(p_flags & WINDOW_FLAG_NO_FOCUS_BIT)) {
void DisplayServerWindows::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];

if (p_id != MAIN_WINDOW_ID) {
_update_window_style(p_id);
}

ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
if (!wd.no_focus) {
SetForegroundWindow(wd.hWnd); // Slightly Higher Priority
SetFocus(wd.hWnd); // Sets Keyboard Focus To
}

return window_id;
}

void DisplayServerWindows::delete_sub_window(WindowID p_window) {
Expand Down Expand Up @@ -3139,9 +3145,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}

ShowWindow(windows[MAIN_WINDOW_ID].hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(windows[MAIN_WINDOW_ID].hWnd); // Slightly Higher Priority
SetFocus(windows[MAIN_WINDOW_ID].hWnd); // Sets Keyboard Focus To
show_window(MAIN_WINDOW_ID);

#if defined(VULKAN_ENABLED)

Expand Down
1 change: 1 addition & 0 deletions platform/windows/display_server_windows.h
Expand Up @@ -461,6 +461,7 @@ class DisplayServerWindows : public DisplayServer {
virtual Vector<DisplayServer::WindowID> get_window_list() const;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_window);
virtual void delete_sub_window(WindowID p_window);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
Expand Down
68 changes: 41 additions & 27 deletions scene/gui/popup.cpp
Expand Up @@ -41,55 +41,71 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
}
}

void Popup::_parent_focused() {
_close_pressed();
void Popup::_initialize_visible_parents() {
visible_parents.clear();

Window *parent_window = this;
while (parent_window) {
parent_window = parent_window->get_parent_visible_window();
if (parent_window) {
visible_parents.push_back(parent_window);
parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
}
}
}

void Popup::_deinitialize_visible_parents() {
for (uint32_t i = 0; i < visible_parents.size(); ++i) {
visible_parents[i]->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
visible_parents[i]->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
}

visible_parents.clear();
}

void Popup::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
parent_visible = get_parent_visible_window();
if (parent_visible) {
parent_visible->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
}
_initialize_visible_parents();
} else {
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
}

_deinitialize_visible_parents();
emit_signal("popup_hide");
}

} break;
case NOTIFICATION_EXIT_TREE: {
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
if (has_focus()) {
popped_up = true;
}
} break;
case NOTIFICATION_EXIT_TREE: {
_deinitialize_visible_parents();
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
_close_pressed();

} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
_close_pressed();
} break;
}
}

void Popup::_close_pressed() {
Window *parent_window = parent_visible;
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
void Popup::_parent_focused() {
if (popped_up) {
_close_pressed();
}
}

void Popup::_close_pressed() {
popped_up = false;

_deinitialize_visible_parents();

call_deferred("hide");

emit_signal("cancelled");

if (parent_window) {
//parent_window->grab_focus();
}
}

void Popup::set_as_minsize() {
Expand Down Expand Up @@ -130,8 +146,6 @@ Rect2i Popup::_popup_adjust_rect() const {
}

Popup::Popup() {
parent_visible = nullptr;

set_wrap_controls(true);
set_visible(false);
set_transient(true);
Expand Down
9 changes: 8 additions & 1 deletion scene/gui/popup.h
Expand Up @@ -33,12 +33,19 @@

#include "scene/main/window.h"

#include "core/local_vector.h"

class Popup : public Window {
GDCLASS(Popup, Window);

Window *parent_visible;
LocalVector<Window *> visible_parents;
bool popped_up = false;

void _input_from_window(const Ref<InputEvent> &p_event);

void _initialize_visible_parents();
void _deinitialize_visible_parents();

void _parent_focused();

protected:
Expand Down
5 changes: 3 additions & 2 deletions scene/main/window.cpp
Expand Up @@ -246,7 +246,10 @@ void Window::_make_window() {
}
}

_update_window_callbacks();

RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
DisplayServer::get_singleton()->show_window(window_id);
}

void Window::_update_from_window() {
Expand Down Expand Up @@ -378,7 +381,6 @@ void Window::set_visible(bool p_visible) {
}
if (p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) {
_make_window();
_update_window_callbacks();
}
} else {
if (visible) {
Expand Down Expand Up @@ -737,7 +739,6 @@ void Window::_notification(int p_what) {
//create
if (visible) {
_make_window();
_update_window_callbacks();
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions servers/display_server.cpp
Expand Up @@ -186,6 +186,10 @@ DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}

void DisplayServer::show_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}

void DisplayServer::delete_sub_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.h
Expand Up @@ -220,6 +220,7 @@ class DisplayServer : public Object {
};

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
Expand Down