Initial version of GTK Wayland backend (#205)

* Obtaining Gtk backend and runtime and displaying it in About box.

* .fixes

* .csometics

* Initial iteration for GTK on Wayland. Works suprisingly stable.

* Disable X11Utils when Wayland backend detected.

* Cosmetics

* .native

* First iteration of CSD.

* .working

* .working

* Calculating additional window spaced used by CSD.

* Fix max window size problem.

* Fix issue with rendering.

* .refactoring

* Fix splash screen when SSD is enable.

* Fix issue with mouse scrolling when CSD is enable.

* Not ideal fix for no keyboard input in parent window.

* Fix problem with XDisplay compilation and change name of GdkBackend to GtkBackend.

* Introduce new WAYLAND flag.

* Ctrl::GetWndScreenRect() fix for X11.

* Fix to compile on mac

---------

Co-authored-by: Zbigniew Rębacz <zbigniew.rebacz@hotmail.com>
This commit is contained in:
Zbigniew Rębacz 2025-02-02 11:47:32 +01:00 committed by GitHub
parent 8077bb9c86
commit 511ff1e991
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 391 additions and 77 deletions

View file

@ -30,22 +30,42 @@ void Ctrl::Create(Ctrl *owner, bool popup)
w.gdk = nullptr;
TopWindow *tw = dynamic_cast<TopWindow *>(this);
GdkWindowTypeHint type_hint;
if(popup && !owner) {
gtk_window_set_decorated(gtk(), FALSE);
// gtk_window_set_has_frame(gtk(), FALSE);
gtk_window_set_type_hint(gtk(), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
type_hint = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
}
else
gtk_window_set_type_hint(gtk(), popup ? GDK_WINDOW_TYPE_HINT_COMBO
: tw && tw->tool ? GDK_WINDOW_TYPE_HINT_UTILITY
: owner ? GDK_WINDOW_TYPE_HINT_DIALOG
: GDK_WINDOW_TYPE_HINT_NORMAL);
else {
type_hint = popup ? GDK_WINDOW_TYPE_HINT_COMBO
: tw && tw->tool ? GDK_WINDOW_TYPE_HINT_UTILITY
: owner ? GDK_WINDOW_TYPE_HINT_DIALOG
: GDK_WINDOW_TYPE_HINT_NORMAL;
}
gtk_window_set_type_hint(gtk(), type_hint);
top->csd.Create(type_hint);
if (top->csd->IsEnable()) {
if (findarg(type_hint, GDK_WINDOW_TYPE_HINT_POPUP_MENU) >= 0) {
top->header = gtk_drawing_area_new();
gtk_widget_set_size_request(top->header, 1, 1);
gtk_window_set_titlebar(gtk(), top->header);
} else {
top->header = gtk_header_bar_new();
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(top->header), TRUE);
gtk_window_set_titlebar(gtk(), top->header);
}
top->drawing_area = gtk_drawing_area_new();
gtk_widget_set_can_focus(top->drawing_area, TRUE);
} else {
top->drawing_area = top->window;
}
top->cursor_id = -1;
gtk_widget_set_events(top->window, GDK_ALL_EVENTS_MASK & ~GDK_POINTER_MOTION_HINT_MASK);
g_signal_connect(top->window, "event", G_CALLBACK(GtkEvent), (gpointer)(uintptr_t)top->id);
g_signal_connect(top->window, "draw", G_CALLBACK(GtkDraw), (gpointer)(uintptr_t)top->id);
gtk_widget_set_events(top->drawing_area, GDK_ALL_EVENTS_MASK & ~GDK_POINTER_MOTION_HINT_MASK & ~GDK_SMOOTH_SCROLL_MASK);
g_signal_connect(top->drawing_area, "event", G_CALLBACK(GtkEvent), (gpointer)(uintptr_t)top->id);
g_signal_connect(top->drawing_area, "draw", G_CALLBACK(GtkDraw), (gpointer)(uintptr_t)top->id);
GdkWindowTypeHint hint = gtk_window_get_type_hint(gtk());
if(tw && findarg(hint, GDK_WINDOW_TYPE_HINT_NORMAL, GDK_WINDOW_TYPE_HINT_DIALOG, GDK_WINDOW_TYPE_HINT_UTILITY) >= 0)
@ -53,15 +73,20 @@ void Ctrl::Create(Ctrl *owner, bool popup)
Rect r = GetRect();
gtk_window_set_default_size (gtk(), LSC(r.GetWidth()), LSC(r.GetHeight()));
// TODO: Normalize
gtk_window_set_default_size(gtk(), LSC(r.GetWidth()), LSC(r.GetHeight()));
gtk_window_move(gtk(), LSC(r.left), LSC(r.top));
gtk_window_resize(gtk(), LSC(r.GetWidth()), LSC(r.GetHeight()));
if (top->header) {
gtk_container_add(GTK_CONTAINER(top->window), top->drawing_area);
gtk_widget_show_all(top->window);
} else {
gtk_widget_realize(top->window);
}
gtk_widget_realize(top->window);
w.gdk = gtk_widget_get_window(top->window);
if(owner && owner->top)
gtk_window_set_transient_for(gtk(), owner->gtk());
gtk_widget_set_app_paintable(top->window, TRUE);
@ -114,8 +139,10 @@ void Ctrl::WndDestroy()
activeCtrl = owner;
}
Top *top = GetTop();
if(top->im_context)
if(top->im_context) {
g_object_unref(top->im_context);
top->im_context = nullptr;
}
gtk_widget_destroy(top->window);
isopen = false;
popup = false;
@ -124,8 +151,14 @@ void Ctrl::WndDestroy()
int q = FindCtrl(this);
if(q >= 0)
wins.Remove(q);
if(owner)
if(owner) {
if(owner->utop->csd->IsEnable()) {
// TODO: This fix the problem with keyboard when backing to original window, but
// the previous control is not being focused like it should be.
gtk_window_set_focus(owner->gtk(), owner->utop->drawing_area);
}
owner->WndUpdate();
}
TopWindow *w = dynamic_cast<TopWindow *>(this);
if(w && w->overlapped.GetWidth() && w->overlapped.GetHeight())
SetRect(w->overlapped);