From b3fe362f4fdfb4d2f79b80dee39cac8869aa6d56 Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 10 Jan 2020 09:18:10 +0000 Subject: [PATCH] uppsrc: gtk3 replaces gtk2 as default linux backend git-svn-id: svn://ultimatepp.org/upp/trunk@13848 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/Ctrl.cpp | 1 + uppsrc/CtrlCore/CtrlCore.h | 1 + uppsrc/CtrlCore/CtrlCore.upp | 7 +- uppsrc/CtrlCore/CtrlDraw.cpp | 5 +- uppsrc/CtrlCore/Gtk.h | 21 +- uppsrc/CtrlCore/GtkApp.cpp | 12 +- uppsrc/CtrlCore/GtkCapture.cpp | 74 +++-- uppsrc/CtrlCore/GtkCreate.cpp | 20 +- uppsrc/CtrlCore/GtkCtrl.cpp | 2 +- uppsrc/CtrlCore/GtkCtrl.h | 21 +- uppsrc/CtrlCore/GtkDnD.cpp | 14 +- uppsrc/CtrlCore/GtkDrawOp.cpp | 18 +- uppsrc/CtrlCore/GtkEvent.cpp | 119 ++++---- uppsrc/CtrlCore/GtkTop.cpp | 22 +- uppsrc/CtrlCore/GtkWnd.cpp | 90 +++--- uppsrc/CtrlCore/GtkX11Util.cpp | 20 +- uppsrc/CtrlCore/Win32Wnd.cpp | 1 - uppsrc/CtrlCore/gtk3-todo.txt | 56 ++++ uppsrc/CtrlLib/Bar.h | 27 +- uppsrc/CtrlLib/Ch.cpp | 276 ++++++++++++++++++- uppsrc/CtrlLib/Ch.h | 27 +- uppsrc/CtrlLib/ChCoco.cpp | 29 -- uppsrc/CtrlLib/ChGtk.cpp | 15 +- uppsrc/CtrlLib/ChGtk0.cpp | 8 +- uppsrc/CtrlLib/ChGtk3.cpp | 482 +++++++++++++++++++++++++++++++++ uppsrc/CtrlLib/ColorPopup.cpp | 33 +-- uppsrc/CtrlLib/Ctrl.iml | 90 +++--- uppsrc/CtrlLib/CtrlLib.h | 1 - uppsrc/CtrlLib/CtrlLib.upp | 1 + uppsrc/CtrlLib/DlgColor.h | 3 - uppsrc/CtrlLib/DropChoice.cpp | 2 +- uppsrc/CtrlLib/EditField.cpp | 2 +- uppsrc/CtrlLib/MenuItem.cpp | 4 +- uppsrc/CtrlLib/MultiButton.cpp | 2 +- uppsrc/CtrlLib/Progress.cpp | 5 + uppsrc/CtrlLib/Progress.h | 1 + uppsrc/CtrlLib/Static.cpp | 44 +-- uppsrc/CtrlLib/StaticCtrl.h | 8 +- uppsrc/ide/LayDes/property.cpp | 2 +- 39 files changed, 1230 insertions(+), 336 deletions(-) create mode 100644 uppsrc/CtrlCore/gtk3-todo.txt create mode 100644 uppsrc/CtrlLib/ChGtk3.cpp diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index 0784532d2..62903a0bc 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -991,6 +991,7 @@ void Ctrl::ReSkin() return; lock++; ChReset(); + Csize.cx = Dsize.cx = IsNoLayoutZoom; if(s_chdefault) (*s_chdefault)(); if(skin) diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 1de5833c9..332f20efe 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -2,6 +2,7 @@ #define CTRLCORE_H #include +#include #ifdef flagNOGTK #undef flagGTK diff --git a/uppsrc/CtrlCore/CtrlCore.upp b/uppsrc/CtrlCore/CtrlCore.upp index ce27836b6..b621b984d 100644 --- a/uppsrc/CtrlCore/CtrlCore.upp +++ b/uppsrc/CtrlCore/CtrlCore.upp @@ -8,10 +8,6 @@ uses library(WIN32 !MSC8ARM) "advapi32 comdlg32 comctl32"; -library((LINUX | BSD) & !NOGTK & !RAINBOW & !GTK3 & GUI & !OSX) "gtk-x11-2.0 gdk-x11-2.0 atk-1.0 gdk_pixbuf-2.0 m pangocairo-1.0 fontconfig Xext Xrender Xinerama Xi Xrandr Xcursor Xfixes pango-1.0 cairo X11 gobject-2.0 gmodule-2.0 glib-2.0"; - -library((LINUX | BSD) & GTK3) "gtk-3.0 gdk-3.0 atk-1.0 gdk_3.0 m pangocairo-1.0 fontconfig Xext Xrender Xinerama Xi Xrandr Xcursor Xfixes pango-1.0 cairo X11 gobject-2.0 gmodule-2.0 glib-2.0"; - library(WIN32 !MSC8ARM) "user32 gdi32"; library(LINUX !RAINBOW GUI) "X11 Xrender Xinerama"; @@ -34,6 +30,8 @@ library(DRAGONFLY) "Xext Xinerama"; link(OSX !X11) "-framework Foundation -framework Cocoa -framework Carbon"; +pkg_config(POSIX !X11) gtk+-3.0; + file Core readonly separator, CtrlCore.h options(BUILDER_OPTION) PCH, @@ -102,6 +100,7 @@ file X11DHCtrl.cpp, X11Event.i, Gtk readonly separator, + gtk3-todo.txt, Gtk.h, GtkAfter.h, GtkKeys.h, diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index 94bc824ac..36718dc61 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -353,6 +353,7 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { GuiLock __; LEVELCHECK(w, this); LTIMING("CtrlPaint"); + LLOG("=== CtrlPaint " << UPP::Name(this) << ", clip: " << clip << ", rect: " << GetRect() << ", view: " << GetView()); Rect rect = GetRect().GetSize(); Rect orect = rect.Inflated(overpaint); if(!IsShown() || orect.IsEmpty() || clip.IsEmpty() || !clip.Intersects(orect)) @@ -417,7 +418,7 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) { Rect ocl = cl - off; if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) { w.Offset(off); - q->CtrlPaint(w, cl - off); + q->CtrlPaint(w, ocl); w.End(); } } @@ -596,7 +597,7 @@ void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint) { GuiLock __; LTIMING("UpdateArea"); - LLOG("========== UPDATE AREA " << UPP::Name(this) << " " << clip << " =========="); + LLOG("========== UPDATE AREA " << UPP::Name(this) << ", clip: " << clip << " =========="); ExcludeDHCtrls(draw, GetRect().GetSize(), clip); if(globalbackbuffer) { CtrlPaint(draw, clip); diff --git a/uppsrc/CtrlCore/Gtk.h b/uppsrc/CtrlCore/Gtk.h index 7dcc362b9..7ad2b125f 100644 --- a/uppsrc/CtrlCore/Gtk.h +++ b/uppsrc/CtrlCore/Gtk.h @@ -2,29 +2,16 @@ #define PLATFORM_X11 // To keep legacy code happy -#ifdef GDK_KEY_Delete #define GDKEY(x) GDK_KEY_##x -#else -#define GDKEY(x) GDK_##x -#endif #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated" #endif -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - #include #include -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -69,10 +56,9 @@ private: void Pop(); Vector offset; Vector clip; + Vector invalid; // for IsPainting checks, if empty, only clip extents is checked cairo_t *cr; - GdkDrawable *drawable; - GdkRegion *invalid; struct TextGlyph : Moveable { int x; @@ -100,12 +86,13 @@ public: void SetColor(Color c); operator cairo_t*() { return cr; } - void SetInvalid(GdkRegion *r) { invalid = r; } + void PickInvalid(Vector&& inv) { invalid = pick(inv); } Point GetOffset() const; bool CanSetSurface() { return true; } static void Flush() {} // TODO? - SystemDraw(cairo_t *cr, GdkDrawable *dw/* = NULL*/) : cr(cr), drawable(dw) { (void)drawable; invalid = NULL; } +// SystemDraw(cairo_t *cr, GdkDrawable *dw/* = NULL*/) : cr(cr), drawable(dw) { (void)drawable; invalid = NULL; } + SystemDraw(cairo_t *cr) : cr(cr) {} ~SystemDraw(); }; diff --git a/uppsrc/CtrlCore/GtkApp.cpp b/uppsrc/CtrlCore/GtkApp.cpp index 70ea37cfe..ef69717f3 100644 --- a/uppsrc/CtrlCore/GtkApp.cpp +++ b/uppsrc/CtrlCore/GtkApp.cpp @@ -57,11 +57,13 @@ void Ctrl::PanicMsgBox(const char *title, const char *text) __BREAK__; } +int Ctrl::scale; + void InitGtkApp(int argc, char **argv, const char **envptr) { LLOG(rmsecs() << " InitGtkApp"); #ifdef _MULTITHREADED -#if !GLIB_CHECK_VERSION(2, 32, 0) +#if !GTK_CHECK_VERSION(2, 32, 0) if(!g_thread_supported()) g_thread_init(NULL); #endif @@ -70,6 +72,14 @@ void InitGtkApp(int argc, char **argv, const char **envptr) EnterGuiMutex(); #endif gtk_init(&argc, &argv); + + Ctrl::SetUHDEnabled(true); + + Ctrl::scale = 1; +#if GTK_CHECK_VERSION(3, 10, 0) + Ctrl::scale = gdk_window_get_scale_factor(gdk_screen_get_root_window(gdk_screen_get_default())); +#endif + Ctrl::GlobalBackBuffer(); Ctrl::ReSkin(); g_timeout_add(20, (GSourceFunc) Ctrl::TimeHandler, NULL); diff --git a/uppsrc/CtrlCore/GtkCapture.cpp b/uppsrc/CtrlCore/GtkCapture.cpp index 5ab321e97..24df7e089 100644 --- a/uppsrc/CtrlCore/GtkCapture.cpp +++ b/uppsrc/CtrlCore/GtkCapture.cpp @@ -9,10 +9,51 @@ namespace Upp { Ptr Ctrl::grabwindow; Ptr Ctrl::grabpopup; +#if GTK_CHECK_VERSION(3, 20, 0) +GdkSeat *Ctrl::GetSeat() +{ + return gdk_display_get_default_seat(gdk_display_get_default()); +} +#endif + +GdkDevice *Ctrl::GetMouseDevice() +{ +#if GTK_CHECK_VERSION(3, 20, 0) + return gdk_seat_get_pointer(GetSeat()); +#else + return gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default())); +#endif +} + +bool Ctrl::MouseIsGrabbed() +{ + return gdk_display_device_is_grabbed(gdk_display_get_default(), GetMouseDevice()); +} + +bool Ctrl::GrabMouse() +{ + return +#if GTK_CHECK_VERSION(3, 20, 0) + gdk_seat_grab(GetSeat(), gdk(), GDK_SEAT_CAPABILITY_ALL_POINTING, true, NULL, NULL, NULL, 0) +#else + gdk_device_grab(GetMouseDevice(), gdk(), GDK_OWNERSHIP_APPLICATION, true, (GdkEventMask)0, NULL, GDK_CURRENT_TIME) +#endif + == GDK_GRAB_SUCCESS; +} + +void Ctrl::UngrabMouse() +{ +#if GTK_CHECK_VERSION(3, 20, 0) + gdk_seat_ungrab(GetSeat()); +#else + gdk_device_ungrab(GetMouseDevice(), GDK_CURRENT_TIME); +#endif +} + void Ctrl::StopGrabPopup() { - if(grabpopup && gdk_pointer_is_grabbed()) { - gdk_pointer_ungrab(CurrentTime); + if(grabpopup && MouseIsGrabbed()) { + UngrabMouse(); grabpopup = NULL; } } @@ -23,13 +64,7 @@ void Ctrl::StartGrabPopup() Ctrl *w = activePopup[0]; if(w && w->IsOpen()) { ReleaseWndCapture0(); - static GdkCursor *NormalArrowCursor; - ONCELOCK { - NormalArrowCursor = gdk_cursor_new(GDK_LEFT_PTR); - } - if(gdk_pointer_grab(w->gdk(), FALSE, - GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK), - NULL, NormalArrowCursor, CurrentTime) == GDK_GRAB_SUCCESS) + if(w->GrabMouse()) grabpopup = w; } } @@ -44,9 +79,7 @@ bool Ctrl::SetWndCapture() return false; StopGrabPopup(); ReleaseWndCapture(); - if(gdk_pointer_grab(gdk(), FALSE, - GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK), - NULL, NULL, CurrentTime) == GDK_GRAB_SUCCESS) { + if(GrabMouse()) { grabwindow = this; return true; } @@ -59,7 +92,7 @@ bool Ctrl::ReleaseWndCapture0() ASSERT(IsMainThread()); LLOG("ReleaseWndCapture"); if(grabwindow) { - gdk_pointer_ungrab(CurrentTime); + UngrabMouse(); grabwindow = NULL; StartGrabPopup(); return true; @@ -75,20 +108,15 @@ bool Ctrl::ReleaseWndCapture() bool Ctrl::HasWndCapture() const { GuiLock __; - return this == grabwindow && grabwindow->IsOpen() && gdk_pointer_is_grabbed(); + return this == grabwindow && grabwindow->IsOpen() && MouseIsGrabbed(); } void Ctrl::CaptureSync() { - if(grabwindow && grabwindow->IsOpen() && !gdk_pointer_is_grabbed()) { - if(gdk_pointer_grab(grabwindow->gdk(), FALSE, - GdkEventMask(GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK), - NULL, NULL, CurrentTime) != GDK_GRAB_SUCCESS) { - grabwindow = NULL; - } - } + if(grabwindow && grabwindow->IsOpen() && !MouseIsGrabbed() && !grabwindow->GrabMouse()) + grabwindow = NULL; } -} +}; -#endif +#endif \ No newline at end of file diff --git a/uppsrc/CtrlCore/GtkCreate.cpp b/uppsrc/CtrlCore/GtkCreate.cpp index 0a84cc431..3917232ce 100644 --- a/uppsrc/CtrlCore/GtkCreate.cpp +++ b/uppsrc/CtrlCore/GtkCreate.cpp @@ -26,12 +26,12 @@ void Ctrl::Create(Ctrl *owner, bool popup) w.id = top->id; w.ctrl = this; w.gtk = top->window; - w.gdk = top->window->window; + w.gdk = gtk_widget_get_window(top->window); TopWindow *tw = dynamic_cast(this); if(popup && !owner) { gtk_window_set_decorated(gtk(), FALSE); - gtk_window_set_has_frame(gtk(), FALSE); + // gtk_window_set_has_frame(gtk(), FALSE); gtk_window_set_type_hint(gtk(), GDK_WINDOW_TYPE_HINT_POPUP_MENU); } else @@ -44,18 +44,21 @@ void Ctrl::Create(Ctrl *owner, bool popup) gtk_widget_set_events(top->window, 0xffffffff); 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); 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) tw->SyncSizeHints(); - + Rect r = GetRect(); - gtk_window_move(gtk(), r.left, r.top); - gtk_window_resize(gtk(), r.GetWidth(), r.GetHeight()); + + 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())); gtk_widget_realize(top->window); - if(owner && owner->top) gtk_window_set_transient_for(gtk(), owner->gtk()); gtk_widget_set_app_paintable(top->window, TRUE); @@ -81,9 +84,8 @@ void Ctrl::Create(Ctrl *owner, bool popup) activeCtrl = this; - int mousex, mousey; - gdk_window_get_pointer(gdk(), &mousex, &mousey, NULL); - Point m(mousex, mousey); + GdkModifierType mod; + Point m = GetMouseInfo(gdk(), mod); r = GetWndScreenRect().GetSize(); if(r.Contains(m)) DispatchMouse(MOUSEMOVE, m); diff --git a/uppsrc/CtrlCore/GtkCtrl.cpp b/uppsrc/CtrlCore/GtkCtrl.cpp index e92edd93d..059e39121 100644 --- a/uppsrc/CtrlCore/GtkCtrl.cpp +++ b/uppsrc/CtrlCore/GtkCtrl.cpp @@ -42,7 +42,7 @@ void GuiPlatformGripResize(TopWindow *q) if(q->IsOpen()) { Point p = GetMousePos(); gtk_window_begin_resize_drag(q->gtk(), GDK_WINDOW_EDGE_SOUTH_EAST, - 1, p.x, p.y, Ctrl::CurrentTime); + 1, Ctrl::LSC(p.x), Ctrl::LSC(p.y), Ctrl::CurrentTime); } } diff --git a/uppsrc/CtrlCore/GtkCtrl.h b/uppsrc/CtrlCore/GtkCtrl.h index 5b25e617b..08f8d94d3 100644 --- a/uppsrc/CtrlCore/GtkCtrl.h +++ b/uppsrc/CtrlCore/GtkCtrl.h @@ -26,6 +26,18 @@ _DBG_ static void CaptureSync(); static gboolean GtkEvent(GtkWidget *widget, GdkEvent *key, gpointer user_data); + static gboolean GtkDraw(GtkWidget *widget, cairo_t *cr, gpointer data); + + static Point GetMouseInfo(GdkWindow *win, GdkModifierType& mod); + static GdkDevice *GetMouseDevice(); +#if GTK_CHECK_VERSION(3, 20, 0) + static GdkSeat *GetSeat(); +#endif + static bool MouseIsGrabbed(); + bool GrabMouse(); + static void UngrabMouse(); + + static int scale; // in case GUI is scaling (e.g. in UHD mode) enum { EVENT_NONE = -15321, @@ -65,6 +77,7 @@ _DBG_ void Proc(); bool SweepConfigure(bool wait); bool SweepFocus(bool wait); + void SyncWndRect(const Rect& rect); static BiVector Events; static Vector< Ptr > activePopup; // created with 'activate' flag - usually menu @@ -75,7 +88,7 @@ _DBG_ static Ptr grabwindow; static Ptr grabpopup; static Ptr sel_ctrl; - static Ptr activeCtrl; // this is used to hold focus when popup is destroyed + static Ptr activeCtrl; static int FindId(int id); static int FindCtrl(Ctrl *ctrl); @@ -170,6 +183,10 @@ public: // really private: static Vector keyhot; static Vector modhot; static guint MouseState; + + static int SCL(int x) { return scale * x; } + static Rect SCL(int x, int y, int cx, int cy) { return RectC(SCL(x), SCL(y), SCL(cx), SCL(cy)); } + static double LSC(int x) { return (double)x / scale; } public: static void EndSession() {} @@ -181,7 +198,7 @@ public: static guint32 CurrentTime; static GEvent CurrentEvent; - GdkWindow *gdk() const { return top ? top->window->window : NULL; } + GdkWindow *gdk() const { return top ? gtk_widget_get_window(top->window) : NULL; } GtkWindow *gtk() const { return top ? (GtkWindow *)top->window : NULL; } static GdkFilterReturn RootKeyFilter(GdkXEvent *xevent, GdkEvent *event, gpointer data); diff --git a/uppsrc/CtrlCore/GtkDnD.cpp b/uppsrc/CtrlCore/GtkDnD.cpp index 7e8ac8f09..46351fb53 100644 --- a/uppsrc/CtrlCore/GtkDnD.cpp +++ b/uppsrc/CtrlCore/GtkDnD.cpp @@ -22,7 +22,7 @@ Ctrl *Ctrl::GetDragAndDropSource() void Ctrl::GtkDragBegin(GtkWidget *widget, GdkDragContext *context, gpointer user_data) { if(IsNull(dnd_icon)) - gtk_drag_set_icon_default(context); + gtk_drag_set_icon_default(context); else { ImageGdk m(dnd_icon); gtk_drag_set_icon_pixbuf(context, m, 0, 0); @@ -114,16 +114,16 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, dnd_icon = Null; else { Size sz = sample.GetSize(); - if(sz.cx > 128) - sz.cx = 128; - if(sz.cy > 128) - sz.cy = 128; + int maxsize = DPI(128); + if(sz.cx > maxsize) + sz.cx = maxsize; + if(sz.cy > maxsize) + sz.cy = maxsize; sz += 2; ImageDraw iw(sz); iw.DrawRect(sz, White()); DrawFrame(iw, sz, Black()); iw.DrawImage(1, 1, sz.cx, sz.cy, sample); - ImageBuffer b(128, 128); dnd_icon = iw; } gtk_drag_begin(w->top->window, list, GdkDragAction(gdk_actions), @@ -287,7 +287,7 @@ PasteClip Ctrl::GtkDnd(GtkWidget *widget, GdkDragContext *context, gint x, gint GdkModifierType mod; gdk_window_get_pointer(gdk_get_default_root_window(), &mx, &my, &mod); CurrentState = mod; - CurrentMousePos = Point(x, y) + w->GetScreenRect().TopLeft(); + CurrentMousePos = Point(SCL(x), SCL(y)) + w->GetScreenRect().TopLeft(); w->DnD(CurrentMousePos, clip); } gdk_drag_status(context, clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? GDK_ACTION_MOVE diff --git a/uppsrc/CtrlCore/GtkDrawOp.cpp b/uppsrc/CtrlCore/GtkDrawOp.cpp index 15ed42b81..2f0315e77 100644 --- a/uppsrc/CtrlCore/GtkDrawOp.cpp +++ b/uppsrc/CtrlCore/GtkDrawOp.cpp @@ -119,7 +119,12 @@ bool SystemDraw::IsPaintingOp(const Rect& r) const cr.Intersect(GetClip()); if(cr.IsEmpty()) return false; - return !invalid || gdk_region_rect_in(invalid, GdkRect(cr)) != GDK_OVERLAP_RECTANGLE_OUT; + if(invalid.GetCount() == 0) + return true; + for(const Rect& ir : invalid) + if(cr.Intersects(ir)) + return true; + return false; } Rect SystemDraw::GetPaintRect() const @@ -134,21 +139,10 @@ void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color) FlushText(); cairo_rectangle(cr, x, y, cx, cy); if(color == InvertColor()) { -#if GTK_CHECK_VERSION(2,24,0) && (CAIRO_VERSION_MAJOR > 1 || CAIRO_VERSION_MINOR > 9) SetColor(White()); cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); cairo_fill(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); -#else - if(drawable) { - GdkGC *gc = gdk_gc_new(drawable); - gdk_gc_set_function(gc, GDK_INVERT); - Point o = GetOffset(); - gdk_draw_drawable(drawable, gc, drawable, x + o.x, y + o.y, x + o.x, y + o.y, cx, cy); - gdk_gc_set_function(gc, GDK_COPY); - gdk_gc_destroy(gc); - } -#endif } else { SetColor(color); diff --git a/uppsrc/CtrlCore/GtkEvent.cpp b/uppsrc/CtrlCore/GtkEvent.cpp index ec9bef9f6..96498060d 100644 --- a/uppsrc/CtrlCore/GtkEvent.cpp +++ b/uppsrc/CtrlCore/GtkEvent.cpp @@ -4,8 +4,8 @@ namespace Upp { -#define LLOG(x) // DLOG(rmsecs() << ' ' << x) -//_DBG_ #define LOG_EVENTS +#define LLOG(x) // DLOG(rmsecs() << ' ' << x) +// #define LOG_EVENTS _DBG_ BiVector Ctrl::Events; @@ -28,7 +28,7 @@ Point GetMousePos() { return Ctrl::CurrentMousePos; } Tuple2 xEvent[] = { { GDK_NOTHING, "GDK_NOTHING" }, { GDK_DELETE, "GDK_DELETE" }, - { GDK_DESTROY, "GDK_DESTROY" },id + { GDK_DESTROY, "GDK_DESTROY" }, { GDK_EXPOSE, "GDK_EXPOSE" }, { GDK_MOTION_NOTIFY, "GDK_MOTION_NOTIFY" }, { GDK_BUTTON_PRESS, "GDK_BUTTON_PRESS" }, @@ -57,7 +57,6 @@ Tuple2 xEvent[] = { { GDK_DROP_FINISHED, "GDK_DROP_FINISHED" }, { GDK_CLIENT_EVENT, "GDK_CLIENT_EVENT" }, { GDK_VISIBILITY_NOTIFY, "GDK_VISIBILITY_NOTIFY" }, - { GDK_NO_EXPOSE, "GDK_NO_EXPOSE" }, { GDK_SCROLL, "GDK_SCROLL" }, { GDK_WINDOW_STATE, "GDK_WINDOW_STATE" }, { GDK_SETTING, "GDK_SETTING" }, @@ -79,6 +78,42 @@ Ctrl *Ctrl::GetTopCtrlFromId(int id) return NULL; } +gboolean Ctrl::GtkDraw(GtkWidget *widget, cairo_t *cr, gpointer user_data) +{ + GuiLock __; + Ctrl *p = GetTopCtrlFromId(user_data); + if(p) { + p->fullrefresh = false; + cairo_scale(cr, 1.0 / scale, 1.0 / scale); + p->SyncWndRect(p->GetWndScreenRect()); // avoid black areas when resizing + + SystemDraw w(cr); + painting = true; + double x1, y1, x2, y2; + cairo_clip_extents (cr, &x1, &y1, &x2, &y2); + Rect r = RectC((int)x1, (int)y1, (int)ceil(x2 - x1), (int)ceil(y2 - y1)); + w.Clip(r); // Because of IsPainting + + cairo_rectangle_list_t *list = cairo_copy_clip_rectangle_list(cr); + if(list->status == CAIRO_STATUS_SUCCESS && list->num_rectangles < 10) { + Vector clip; + for(int i = 0; i < list->num_rectangles; i++) { + const cairo_rectangle_t& r = list->rectangles[i]; + clip.Add(Rect((int)r.x, (int)r.y, (int)(r.x + r.width), (int)(r.y + r.height))); + } + w.PickInvalid(pick(clip)); + } + cairo_rectangle_list_destroy(list); + + p->UpdateArea(w, r); + w.End(); + if(p->top->dr) + DrawDragRect(*p, *p->top->dr); + painting = false; + } + return true; +} + gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) { GuiLock __; @@ -96,34 +131,9 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) #endif switch(event->type) { - case GDK_EXPOSE: - case GDK_DAMAGE: - if(p) { -#ifdef LOG_EVENTS - TimeStop tm; -#endif - p->fullrefresh = false; - GdkEventExpose *e = (GdkEventExpose *)event; - SystemDraw w(gdk_cairo_create(p->gdk()), p->gdk()); - painting = true; - Rect r = RectC(e->area.x, e->area.y, e->area.width, e->area.height); - w.SetInvalid(e->region); - w.Clip(r); - p->UpdateArea(w, r); - w.End(); - cairo_destroy(w); - if(p->top->dr) - DrawDragRect(*p, *p->top->dr); - painting = false; -#ifdef LOG_EVENTS - LOG("* " << ev << " elapsed " << tm); -#endif - } - return true; case GDK_DELETE: break; case GDK_FOCUS_CHANGE: - LLOG("Focus Change " << GetSysTime()); if(p) { if(((GdkEventFocus *)event)->in) gtk_im_context_focus_in(p->top->im_context); @@ -152,7 +162,13 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) break; case GDK_SCROLL: { GdkEventScroll *e = (GdkEventScroll *)event; - value = findarg(e->direction, GDK_SCROLL_UP, GDK_SCROLL_LEFT) < 0 ? -120 : 120; + if(findarg(e->direction, GDK_SCROLL_UP, GDK_SCROLL_LEFT) >= 0) + value = 120; + else + if(findarg(e->direction, GDK_SCROLL_DOWN, GDK_SCROLL_RIGHT) >= 0) + value = -120; + else + return false; break; } case GDK_KEY_PRESS: @@ -169,8 +185,7 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) case GDK_CONFIGURE: { retval = false; GdkEventConfigure *e = (GdkEventConfigure *)event; - value = RectC(e->x, e->y, e->width, e->height); - LLOG("GDK_CONFIGURE " << value); + value = SCL(e->x, e->y, e->width, e->height); break; } default: @@ -232,6 +247,21 @@ void Ctrl::GEvent::operator=(const GEvent& e) Set(e); } +Point Ctrl::GetMouseInfo(GdkWindow *win, GdkModifierType& mod) +{ +#if GTK_CHECK_VERSION(3, 20, 0) + GdkDisplay *display = gdk_window_get_display (win); + GdkDevice *pointer = gdk_seat_get_pointer (gdk_display_get_default_seat (display)); + double x, y; + gdk_window_get_device_position_double (win, pointer, &x, &y, &mod); + return Point((int)SCL(x), (int)SCL(y)); +#else + gint x, y; + gdk_window_get_pointer(win, &x, &y, &mod); + return Point(SCL(x), SCL(y)); +#endif +} + void Ctrl::AddEvent(gpointer user_data, int type, const Value& value, GdkEvent *event) { if(Events.GetCount() > 50000) @@ -240,10 +270,8 @@ void Ctrl::AddEvent(gpointer user_data, int type, const Value& value, GdkEvent * e.windowid = (uint32)(uintptr_t)user_data; e.type = type; e.value = value; - gint x, y; GdkModifierType mod; - gdk_window_get_pointer(gdk_get_default_root_window(), &x, &y, &mod); - e.mousepos = Point(x, y); + e.mousepos = GetMouseInfo(gdk_get_default_root_window(), mod); e.state = (mod & ~(GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) | MouseState; e.count = 1; e.event = NULL; @@ -494,7 +522,6 @@ void Ctrl::Proc() break; } case EVENT_FOCUS_CHANGE: - LLOG("FOCUS_CHANGE setting NULL"); activeCtrl = NULL; break; case GDK_DELETE: { @@ -507,16 +534,8 @@ void Ctrl::Proc() } return; } - case GDK_CONFIGURE: { - Rect rect = CurrentEvent.value; - if(GetRect() != rect) - SetWndRect(rect); - { - TopWindow *w = dynamic_cast(this); - if(w && w->state == TopWindow::OVERLAPPED) - w->overlapped = rect; - } - } + case GDK_CONFIGURE: + SyncWndRect(CurrentEvent.value); break; default: return; @@ -525,6 +544,14 @@ void Ctrl::Proc() _this->PostInput(); } +void Ctrl::SyncWndRect(const Rect& rect) +{ + if(GetRect() != rect) + SetWndRect(rect); + TopWindow *w = dynamic_cast(this); + if(w && w->state == TopWindow::OVERLAPPED) + w->overlapped = rect; +} bool Ctrl::ProcessEvent0(bool *quit, bool fetch) { diff --git a/uppsrc/CtrlCore/GtkTop.cpp b/uppsrc/CtrlCore/GtkTop.cpp index 48dcb81ce..9e1c94d5a 100644 --- a/uppsrc/CtrlCore/GtkTop.cpp +++ b/uppsrc/CtrlCore/GtkTop.cpp @@ -21,19 +21,21 @@ void TopWindow::SyncSizeHints() return; GdkGeometry m; Size sz0 = GetRect().GetSize(); + LLOG("SyncSizeHints sz0: " << sz0 << ", sizeable: " << sizeable << ", min: " << GetMinSize() << ", max: " << GetMaxSize()); Size sz = sz0; if(sizeable) sz = GetMinSize(); - m.min_width = sz.cx; - m.min_height = sz.cy; + m.min_width = LSC(sz.cx); + m.min_height = LSC(sz.cy); sz = sz0; if(sizeable) sz = GetMaxSize(); - m.max_width = sz.cx; - m.max_height = sz.cy; + m.max_width = LSC(sz.cx); + m.max_height = LSC(sz.cy); gtk_window_set_resizable(gtk(), sizeable); gtk_window_set_geometry_hints(gtk(), top->window, &m, GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE)); + gtk_widget_set_size_request(top->window, m.min_width, m.min_height); } void TopWindow::SyncTitle() @@ -136,10 +138,10 @@ void TopWindow::Open(Ctrl *owner) GdkRectangle fr; gdk_window_get_frame_extents(gdk(), &fr); Rect r = GetRect(); - frameMargins.left = max(frameMargins.left, minmax(r.left - fr.x, 0, 32)); - frameMargins.right = max(frameMargins.right, minmax(fr.x + fr.width - r.right, 0, 32)); - frameMargins.top = max(frameMargins.top, minmax(r.top - fr.y, 0, 64)); - frameMargins.bottom = max(frameMargins.bottom, minmax(fr.y + fr.height - r.bottom, 0, 48)); + frameMargins.left = max(frameMargins.left, minmax(r.left - SCL(fr.x), 0, 32)); + frameMargins.right = max(frameMargins.right, minmax(SCL(fr.x + fr.width) - r.right, 0, 32)); + frameMargins.top = max(frameMargins.top, minmax(r.top - SCL(fr.y), 0, 64)); + frameMargins.bottom = max(frameMargins.bottom, minmax(SCL(fr.y + fr.height) - r.bottom, 0, 48)); } void TopWindow::Open() @@ -214,7 +216,7 @@ void TopWindow::Overlap(bool effect) TopWindow& TopWindow::TopMost(bool b, bool) { - GuiLock __; + GuiLock __; topmost = b; SyncTopMost(); return *this; @@ -222,7 +224,7 @@ TopWindow& TopWindow::TopMost(bool b, bool) bool TopWindow::IsTopMost() const { - GuiLock __; + GuiLock __; return topmost; } diff --git a/uppsrc/CtrlCore/GtkWnd.cpp b/uppsrc/CtrlCore/GtkWnd.cpp index e82fb188b..7b5b15806 100644 --- a/uppsrc/CtrlCore/GtkWnd.cpp +++ b/uppsrc/CtrlCore/GtkWnd.cpp @@ -56,9 +56,7 @@ bool Ctrl::IsAlphaSupported() bool Ctrl::IsCompositedGui() { - GuiLock __; - static bool b = gdk_display_supports_composite(gdk_display_get_default()); - return b; + return true; // limits some GUI effects that do not play well with advanced desktops } Vector Ctrl::GetTopCtrls() @@ -70,6 +68,8 @@ Vector Ctrl::GetTopCtrls() return h; } +cairo_surface_t *CreateCairoSurface(const Image& img); + void Ctrl::SetMouseCursor(const Image& image) { LLOG("SetMouseCursor"); @@ -88,22 +88,31 @@ void Ctrl::SetMouseCursor(const Image& image) int64 aux = image.GetAuxData(); GdkCursor *c = NULL; if(aux) - c = gdk_cursor_new((GdkCursorType)(aux - 1)); + c = gdk_cursor_new_for_display(gdk_display_get_default(), (GdkCursorType)(aux - 1)); else if(IsNull(image)) - c = gdk_cursor_new(GDK_BLANK_CURSOR); + c = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_BLANK_CURSOR); else { Point p = image.GetHotSpot(); + +#if GTK_CHECK_VERSION(3, 10, 0) + cairo_surface_t *surface = CreateCairoSurface(image); + double scale = SCL(1); + cairo_surface_set_device_scale(surface, scale, scale); + c = gdk_cursor_new_from_surface(gdk_display_get_default(), surface, p.x / scale, p.y / scale); + cairo_surface_destroy(surface); +#else ImageGdk m; m.Set(image); GdkPixbuf *pb = m; if(pb) c = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pb, p.x, p.y); +#endif } if(c && topctrl->IsOpen()) { gdk_window_set_cursor(topctrl->gdk(), c); - gdk_cursor_unref(c); - gdk_flush(); // Make it visible immediately + g_object_unref(c); + gdk_display_flush(gdk_display_get_default()); // Make it visible immediately } } } @@ -191,14 +200,9 @@ Rect Ctrl::GetWndScreenRect() const if(IsOpen()) { gint x, y; gdk_window_get_position(gdk(), &x, &y); - #if GTK_CHECK_VERSION(2, 24, 0) gint width = gdk_window_get_width(gdk()); gint height = gdk_window_get_height(gdk()); - #else - gint width, height; - gdk_drawable_get_size(gdk(), &width, &height); - #endif - return RectC(x, y, width, height); + return SCL(x, y, width, height); } return Null; } @@ -218,7 +222,7 @@ void Ctrl::WndShow(bool b) bool Ctrl::IsWndOpen() const { GuiLock __; - return top && top->window && top->window->window; + return top && top->window && gtk_widget_get_window(top->window); } void Ctrl::SetAlpha(byte alpha) @@ -243,6 +247,17 @@ Rect Ctrl::GetWorkArea() const void Ctrl::GetWorkArea(Array& rc) { GuiLock __; +#if GTK_CHECK_VERSION(3, 22, 0) + GdkDisplay *s = gdk_display_get_default(); + int n = gdk_display_get_n_monitors(s); + rc.Clear(); + Vector netwa; + for(int i = 0; i < n; i++) { + GdkRectangle rr; + gdk_monitor_get_workarea(gdk_display_get_monitor(s, i), &rr); + rc.Add(SCL(rr.x, rr.y, rr.width, rr.height)); + } +#else GdkScreen *s = gdk_screen_get_default(); int n = gdk_screen_get_n_monitors(s); rc.Clear(); @@ -250,22 +265,11 @@ void Ctrl::GetWorkArea(Array& rc) for(int i = 0; i < n; i++) { GdkRectangle rr; Rect r; -#if GTK_CHECK_VERSION (3, 3, 5) // U++ does not work with gtk3 yet, but be prepared gdk_screen_get_monitor_workarea(s, i, &rr); - r = RectC(r.x, r.y, r.width, r.height); -#else - gdk_screen_get_monitor_geometry (s, i, &rr); r = RectC(rr.x, rr.y, rr.width, rr.height); - #ifdef GDK_WINDOWING_X11 - if(i == 0) - netwa = GetPropertyInts(gdk_screen_get_root_window(gdk_screen_get_default()), - "_NET_WORKAREA"); - if(netwa.GetCount()) - r = r & RectC(netwa[0], netwa[1], netwa[2], netwa[3]); - #endif -#endif rc.Add(r); } +#endif } Rect Ctrl::GetVirtualWorkArea() @@ -289,8 +293,8 @@ Rect Ctrl::GetVirtualScreenArea() if(r.right == 0) { gint x, y, width, height; gdk_window_get_geometry(gdk_screen_get_root_window(gdk_screen_get_default()), - &x, &y, &width, &height, NULL); - r = RectC(x, y, width, height); + &x, &y, &width, &height); + r = SCL(x, y, width, height); } return r; } @@ -298,18 +302,20 @@ Rect Ctrl::GetVirtualScreenArea() Rect Ctrl::GetPrimaryWorkArea() { GuiLock __; +#if GTK_CHECK_VERSION(3, 22, 0) + GdkRectangle rr; + gdk_monitor_get_workarea(gdk_display_get_primary_monitor(gdk_display_get_default()), &rr); + return SCL(rr.x, rr.y, rr.width, rr.height); +#else static Rect r; if (r.right == 0) { Array rc; GetWorkArea(rc); -#if GTK_CHECK_VERSION(2, 20, 0) int primary = gdk_screen_get_primary_monitor(gdk_screen_get_default()); -#else - int primary = 0; -#endif primary >= 0 && primary < rc.GetCount() ? r = rc[primary] : r = GetVirtualScreenArea(); } return r; +#endif } Rect Ctrl::GetPrimaryScreenArea() @@ -392,8 +398,17 @@ void Ctrl::WndInvalidateRect(const Rect& r) { GuiLock __; LLOG("WndInvalidateRect " << r); - gdk_window_invalidate_rect(gdk(), GdkRect(r), TRUE); -// gtk_widget_queue_draw_area(top->window, r.left, r.top, r.GetWidth(), r.GetHeight()); + Rect rr; + if(scale > 1) { + rr.left = r.left / 2; + rr.top = r.top / 2; + rr.right = (r.right + 1) / 2; + rr.bottom = (r.bottom + 1) / 2; + } + else + rr = r; + + gdk_window_invalidate_rect(gdk(), GdkRect(rr), TRUE); } void Ctrl::WndScrollView(const Rect& r, int dx, int dy) @@ -432,10 +447,11 @@ void Ctrl::WndSetPos(const Rect& rect) SweepConfigure(false); // Remove any previous GDK_CONFIGURE for this window if(!this_ || !IsOpen()) return; + Rect m(0, 0, 0, 0); if(dynamic_cast(this)) m = GetFrameMargins(); - gdk_window_move_resize(gdk(), rect.left - m.left, rect.top - m.top, rect.GetWidth(), rect.GetHeight()); + gdk_window_move_resize(gdk(), LSC(rect.left - m.left), LSC(rect.top - m.top), LSC(rect.GetWidth()), LSC(rect.GetHeight())); int t0 = msecs(); do { // Wait up to 500ms for corresponding GDK_CONFIGURE to arrive if(SweepConfigure(true)) @@ -465,9 +481,9 @@ void Ctrl::WndUpdate() { GuiLock __; LLOG("WndUpdate0"); - gdk_window_process_updates(gdk(), TRUE); +// gdk_window_process_updates(gdk(), TRUE); // deprecated FetchEvents(FALSE); // Should pickup GDK_EXPOSE and repaint the window - gdk_flush(); + gdk_display_flush(gdk_display_get_default()); } Rect Ctrl::GetDefaultWindowRect() diff --git a/uppsrc/CtrlCore/GtkX11Util.cpp b/uppsrc/CtrlCore/GtkX11Util.cpp index 898b3e424..60c467d78 100644 --- a/uppsrc/CtrlCore/GtkX11Util.cpp +++ b/uppsrc/CtrlCore/GtkX11Util.cpp @@ -27,7 +27,7 @@ XDisplay *Xdisplay() Window Xroot() { - return GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(gdk_screen_get_default())); + return GDK_WINDOW_XID(gdk_screen_get_root_window(gdk_screen_get_default())); } String GetProperty(Window w, Atom property, Atom rtype) @@ -67,7 +67,7 @@ Atom XAtomRaw(const char *name) Atom XAtom(const char *name) { - GuiLock __; + GuiLock __; Atom x; INTERLOCKED { static VectorMap atoms; @@ -83,9 +83,9 @@ Atom XAtom(const char *name) Vector GetPropertyInts(GdkWindow *w, const char *property) { - GuiLock __; + GuiLock __; Vector result; - String p = GetProperty(GDK_WINDOW_XWINDOW(w), XAtom(property), AnyPropertyType); + String p = GetProperty(GDK_WINDOW_XID(w), XAtom(property), AnyPropertyType); const long int *ptr = (const long int *)~p; const long int *lim = ptr + p.GetLength() / sizeof(long int); result.Reserve(p.GetLength() / sizeof(long int)); @@ -106,11 +106,13 @@ dword X11mods(dword key) return mod; } +#if 0 // retained for 3.8 compatibility + int Ctrl::RegisterSystemHotKey(dword key, Function cb) { GuiLock __; ASSERT(key >= K_DELTA); - gdk_error_trap_push(); + gdk_x11_display_error_trap_push(gdk_display_get_default()); KeyCode k = XKeysymToKeycode(Xdisplay(), key & 0xffff); dword mod = X11mods(key); bool r = false; @@ -120,7 +122,7 @@ int Ctrl::RegisterSystemHotKey(dword key, Function cb) r = XGrabKey(Xdisplay(), k, mod | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask), Xroot(), true, GrabModeAsync, GrabModeAsync) || r; - gdk_error_trap_pop(); + gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default()); if(!r) return -1; int q = hotkey.GetCount(); for(int i = 0; i < hotkey.GetCount(); i++) @@ -138,18 +140,20 @@ void Ctrl::UnregisterSystemHotKey(int id) { GuiLock __; if(id >= 0 && id < hotkey.GetCount() && hotkey[id]) { - gdk_error_trap_push(); + gdk_x11_display_error_trap_push(gdk_display_get_default()); for(dword nlock = 0; nlock < 2; nlock++) for(dword clock = 0; clock < 2; clock++) for(dword slock = 0; slock < 2; slock++) XUngrabKey(Xdisplay(), keyhot[id], modhot[id] | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask), Xroot()); - gdk_error_trap_pop(); + gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default()); hotkey[id].Clear(); } } +#endif + GdkFilterReturn Ctrl::RootKeyFilter(GdkXEvent *xevent, GdkEvent *Xevent, gpointer data) { XEvent *event = (XEvent *)xevent; diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index 7cacedd11..ea2e68fc6 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -317,7 +317,6 @@ void Ctrl::InitWin32(HINSTANCE hInstance) ReSkin(); OleInitialize(NULL); - CoInitialize(NULL); /* TRC 05/11/14: moved to GuiSleep to avoid thread creation in OCX DllMain DWORD dummy; diff --git a/uppsrc/CtrlCore/gtk3-todo.txt b/uppsrc/CtrlCore/gtk3-todo.txt new file mode 100644 index 000000000..7571343ec --- /dev/null +++ b/uppsrc/CtrlCore/gtk3-todo.txt @@ -0,0 +1,56 @@ +- Issue with editfield text clipping in the right +- Remove warnings +- Test dark theme +- Test rect theme +- Blue Menta ugly scrollbars (round) +- TraditionalOk ugly scrollbars (centre image) +- DropChoice STDSIZE (.TopPosZ(10)) +- LeftRoundness with DropChoice (DropChoiceRdO) +- 3.8 theme +- CleanTheme for X11 +- libgtk-3-dev to buildrequires +- test DateTimeCtrl in dark mode +- check CtrlCore/Ctrl.tpp +- Check FileSel + +NTH: +- spinbutton cosmetics + +PROBABLY DONE: +- Problem with hot3 in scrollbar horizontal (check in SD) + +DONE: + +- Resizing delay +- Refresh issue +- Test & Fix filesel & fileselector +- Combobox push is weird +- right scrollbar +- Test grip resize +- toolbar button highlight +- correct checks in menu +- uword cannot be resized smaller +- Scrollbar margins (better fit for slider) +- Scrollbar Correct minsize, barsize... +- FileSelector +- Mint-Y disabled color is wrong +- Mint-Y tooltip color is wrong +- .iml cursors in UHD are wrong (e.g. header <-|->) +- cxZ Uword - wrong caret +- Combobox appearance issues (minor, round corners broken on the left) +- spinbuttons in UWord +- read-only dropchoice left color +- ColorPopup background +- Fix IsPainting +- Header synthetise +- Resizing fix black +- Slider thumb +- Remove DDUMPs +- TabBar synthetise +- Problem with theide menu +- LabelBox +- GtkStyleBool("has-backward-stepper") +- DropChoice read only active edge +- Scale must not be same as UHD +- makefile pkg-config support +- Test with 3.8 diff --git a/uppsrc/CtrlLib/Bar.h b/uppsrc/CtrlLib/Bar.h index 59da3de5e..03b3345ac 100644 --- a/uppsrc/CtrlLib/Bar.h +++ b/uppsrc/CtrlLib/Bar.h @@ -306,16 +306,25 @@ protected: public: struct Style : ChStyle