From 62a7627ffa241188e92e8417340fdf8ed5f6be82 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Fri, 19 Feb 2021 21:17:08 +0100 Subject: [PATCH] macos: introduce ugly packing hack to attempt to reduce the size of the residual GL viewport when another tab is expected to be above HACK: The OpenGL viewport is reduced to one line on the bottom of the window when other tabs are displayed, so the rectangle is not drawn over the window but a non-bostructing bottom line instead. --- CMakeLists.txt | 1 + libs/uilib/uilib.cpp | 5 ++ libs/uilib/uilib.h | 6 ++ radiant/groupdialog.cpp | 35 ++++++++--- radiant/texwindow.cpp | 126 +++++++++++++++++++++++++++++++++++----- radiant/texwindow.h | 5 ++ 6 files changed, 153 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ff959dc..94136b8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,6 +245,7 @@ if (BUILD_RADIANT) if (APPLE) if (GTK_TARGET EQUAL 2) add_definitions(-DWORKAROUND_MACOS_GTK2_DESTROY=1) + add_definitions(-DWORKAROUND_MACOS_GTK2_GLWIDGET=1) endif () endif () endif () diff --git a/libs/uilib/uilib.cpp b/libs/uilib/uilib.cpp index 8812911e..5caf150d 100644 --- a/libs/uilib/uilib.cpp +++ b/libs/uilib/uilib.cpp @@ -270,6 +270,11 @@ namespace ui { gtk_box_pack_end(this, child, expand, fill, padding); } + void IBox::set_child_packing(ui::Widget child, bool expand, bool fill, unsigned int padding, ui::Packing packing) + { + gtk_box_set_child_packing(this, child, expand, fill, padding, (GtkPackType) packing); + } + IMPL(VBox, GTK_VBOX); VBox::VBox(bool homogenous, int spacing) : VBox(GTK_VBOX(gtk_vbox_new(homogenous, spacing))) diff --git a/libs/uilib/uilib.h b/libs/uilib/uilib.h index e6c5ff6a..d8f41c85 100644 --- a/libs/uilib/uilib.h +++ b/libs/uilib/uilib.h @@ -103,6 +103,11 @@ namespace ui { NEVER }; + enum class Packing { + START, + END + }; + namespace details { enum class Convert { @@ -376,6 +381,7 @@ namespace ui { , void pack_start(ui::Widget child, bool expand, bool fill, unsigned int padding); void pack_end(ui::Widget child, bool expand, bool fill, unsigned int padding); + void set_child_packing(ui::Widget child, bool expand, bool fill, unsigned int padding, ui::Packing packing); ); WRAP(VBox, Box, _GtkVBox, (), diff --git a/radiant/groupdialog.cpp b/radiant/groupdialog.cpp index f6d9c4be..dbad5b89 100644 --- a/radiant/groupdialog.cpp +++ b/radiant/groupdialog.cpp @@ -41,10 +41,12 @@ #include "multimon.h" #include "console.h" #include "commands.h" - - #include "gtkutil/window.h" +#if defined(WORKAROUND_WINDOWS_GTK2_GLWIDGET) || defined(WORKAROUND_MACOS_GTK2_GLWIDGET) +#include "texwindow.h" +#endif // WORKAROUND_WINDOWS_GTK2_GLWIDGET || WORKAROUND_MACOS_GTK2_GLWIDGET + class GroupDlg { public: @@ -74,16 +76,30 @@ std::size_t g_current_page; std::vector &)>> g_pages; } +static void workaround_macos_show_hide(){ +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET + if ( g_current_page == 2 ) + { + TextureBrowser_showGLWidget(); + } + else + { + TextureBrowser_hideGLWidget(); + } +#endif // WORKAROUND_MACOS_GTK2_GLWIDGET +} + void GroupDialog_updatePageTitle( ui::Window window, std::size_t pageIndex ){ if ( pageIndex < g_pages.size() ) { g_pages[pageIndex]( PointerCaller( window ) ); } + + workaround_macos_show_hide(); } static gboolean switch_page( GtkNotebook *notebook, gpointer page, guint page_num, gpointer data ){ - GroupDialog_updatePageTitle( ui::Window::from(data), page_num ); g_current_page = page_num; - + GroupDialog_updatePageTitle( ui::Window::from(data), page_num ); return FALSE; } @@ -122,7 +138,6 @@ void GroupDlg::Create( ui::Window parent ){ } } - ui::Widget GroupDialog_addPage( const char* tabLabel, ui::Widget widget, const Callback &)>& title ){ ui::Widget w = ui::Label( tabLabel ); w.show(); @@ -132,7 +147,6 @@ ui::Widget GroupDialog_addPage( const char* tabLabel, ui::Widget widget, const C return page; } - bool GroupDialog_isShown(){ return g_GroupDlg.m_window.visible(); } @@ -152,7 +166,6 @@ void GroupDialog_destroyWindow(){ g_GroupDlg.m_window = ui::Window{ui::null}; } - ui::Window GroupDialog_getWindow(){ return ui::Window(g_GroupDlg.m_window); } @@ -161,12 +174,14 @@ void GroupDialog_show(){ } ui::Widget GroupDialog_getPage(){ - return ui::Widget::from(gtk_notebook_get_nth_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) )); + return ui::Widget::from(gtk_notebook_get_nth_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) ) ); } void GroupDialog_setPage( ui::Widget page ){ g_current_page = gtk_notebook_page_num( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), page ); gtk_notebook_set_current_page( GTK_NOTEBOOK( g_GroupDlg.m_pNotebook ), gint( g_current_page ) ); + + workaround_macos_show_hide(); } #ifdef WORKAROUND_WINDOWS_GTK2_GLWIDGET @@ -174,6 +189,7 @@ void GroupDialog_cycle(); #endif // WORKAROUND_WINDOWS_GTK2_GLWIDGET void GroupDialog_showPage( ui::Widget page ){ + if ( GroupDialog_getPage() == page ) { GroupDialog_ToggleShow(); @@ -193,6 +209,8 @@ void GroupDialog_showPage( ui::Widget page ){ g_GroupDlg.m_window.show(); GroupDialog_setPage( page ); } + + workaround_macos_show_hide(); } void GroupDialog_cycle(){ @@ -206,7 +224,6 @@ void GroupDialog_updatePageTitle( ui::Widget page ){ } } - #include "preferencesystem.h" void GroupDialog_Construct(){ diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index 75d3788d..9870d2a0 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -266,6 +266,14 @@ int m_nTotalHeight; CopiedString shader; ui::Window m_parent{ui::null}; +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET +ui::VBox m_vframe{ui::null}; +ui::VBox m_vfiller{ui::null}; +ui::HBox m_hframe{ui::null}; +ui::HBox m_hfiller{ui::null}; +#else // !WORKAROUND_MACOS_GTK2_GLWIDGET +ui::VBox m_frame{ui::null}; +#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET ui::GLArea m_gl_widget{ui::null}; ui::Widget m_texture_scroll{ui::null}; ui::TreeView m_treeViewTree{ui::New}; @@ -1143,6 +1151,7 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ textureBrowser.color_textureback[1], textureBrowser.color_textureback[2], 0 ); + glViewport( 0, 0, textureBrowser.width, textureBrowser.height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); @@ -1519,7 +1528,6 @@ gboolean TextureBrowser_expose( ui::Widget widget, GdkEventExpose* event, Textur return FALSE; } - TextureBrowser g_TextureBrowser; TextureBrowser& GlobalTextureBrowser(){ @@ -2056,12 +2064,42 @@ void TextureBrowser_SetNotex(){ IShader* shadernotex = QERApp_Shader_ForName( DEFAULT_SHADERNOTEX_NAME ); g_notex = notex->getTexture()->name; + g_shadernotex = shadernotex->getTexture()->name; notex->DecRef(); shadernotex->DecRef(); } +static bool isGLWidgetConstructed = false; +static bool isWindowConstructed = false; + +void TextureBrowser_constructGLWidget(){ + g_TextureBrowser.m_gl_widget = glwidget_new( FALSE ); + g_object_ref( g_TextureBrowser.m_gl_widget._handle ); + + gtk_widget_set_events( g_TextureBrowser.m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); + gtk_widget_set_can_focus( g_TextureBrowser.m_gl_widget, true ); + + g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect( "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &g_TextureBrowser ); + g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render( G_CALLBACK( TextureBrowser_expose ), &g_TextureBrowser ); + + g_TextureBrowser.m_gl_widget.connect( "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &g_TextureBrowser ); + g_TextureBrowser.m_gl_widget.connect( "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &g_TextureBrowser ); + g_TextureBrowser.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &g_TextureBrowser ); + g_TextureBrowser.m_gl_widget.connect( "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &g_TextureBrowser ); + +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_hframe.pack_start( g_TextureBrowser.m_gl_widget, TRUE, TRUE, 0 ); +#else // !WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_frame.pack_start( g_TextureBrowser.m_gl_widget, TRUE, TRUE, 0 ); +#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET + + g_TextureBrowser.m_gl_widget.show(); + + isGLWidgetConstructed = true; +} + ui::Widget TextureBrowser_constructWindow( ui::Window toplevel ){ // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't @@ -2123,22 +2161,30 @@ ui::Widget TextureBrowser_constructWindow( ui::Window toplevel ){ g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar); } { // gl_widget - g_TextureBrowser.m_gl_widget = glwidget_new( FALSE ); - g_object_ref( g_TextureBrowser.m_gl_widget._handle ); +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_vframe = ui::VBox( FALSE, 0 ); + table.attach(g_TextureBrowser.m_vframe, {1, 2, 1, 2}); + + g_TextureBrowser.m_vfiller = ui::VBox( FALSE, 0 ); + g_TextureBrowser.m_vframe.pack_start( g_TextureBrowser.m_vfiller, FALSE, FALSE, 0 ); - gtk_widget_set_events( g_TextureBrowser.m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK ); - gtk_widget_set_can_focus( g_TextureBrowser.m_gl_widget, true ); + g_TextureBrowser.m_hframe = ui::HBox( FALSE, 0 ); + g_TextureBrowser.m_vframe.pack_start( g_TextureBrowser.m_hframe, TRUE, TRUE, 0 ); - table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2}); - g_TextureBrowser.m_gl_widget.show(); + g_TextureBrowser.m_hfiller = ui::HBox( FALSE, 0 ); + g_TextureBrowser.m_hframe.pack_start( g_TextureBrowser.m_hfiller, FALSE, FALSE, 0 ); - g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect( "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &g_TextureBrowser ); - g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render( G_CALLBACK( TextureBrowser_expose ), &g_TextureBrowser ); + g_TextureBrowser.m_vframe.show(); + g_TextureBrowser.m_vfiller.show(); + g_TextureBrowser.m_hframe.show(), + g_TextureBrowser.m_hfiller.show(); +#else // !WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_frame = ui::VBox( FALSE, 0 ); + table.attach(g_TextureBrowser.m_frame, {1, 2, 1, 2}); + g_TextureBrowser.m_frame.show(); +#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET - g_TextureBrowser.m_gl_widget.connect( "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &g_TextureBrowser ); - g_TextureBrowser.m_gl_widget.connect( "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &g_TextureBrowser ); - g_TextureBrowser.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &g_TextureBrowser ); - g_TextureBrowser.m_gl_widget.connect( "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &g_TextureBrowser ); + TextureBrowser_constructGLWidget(); } // tag stuff @@ -2291,17 +2337,65 @@ ui::Widget TextureBrowser_constructWindow( ui::Window toplevel ){ // TODO do we need this? //gtk_container_set_focus_chain(GTK_CONTAINER(hbox_table), NULL); + isWindowConstructed = true; + return table; } +void TextureBrowser_destroyGLWidget(){ + if ( isGLWidgetConstructed ) + { + g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_sizeHandler ); + g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_exposeHandler ); + +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_hframe.remove( g_TextureBrowser.m_gl_widget ); +#else // !WORKAROUND_MACOS_GTK2_GLWIDGET + g_TextureBrowser.m_frame.remove( g_TextureBrowser.m_gl_widget ); +#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET + + g_TextureBrowser.m_gl_widget.unref(); + + isGLWidgetConstructed = false; + } +} + void TextureBrowser_destroyWindow(){ GlobalShaderSystem().setActiveShadersChangedNotify( Callback() ); - g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_sizeHandler ); - g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_exposeHandler ); + TextureBrowser_destroyGLWidget(); +} - g_TextureBrowser.m_gl_widget.unref(); +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET +/* workaround for gtkglext on gtk 2 issue: OpenGL texture viewport being drawn over the other pages */ +/* this is very ugly: force the resizing of the viewport to a single bottom line by forcing the + * resizing of the gl widget by expanding some empty boxes, so the widget area size is reduced + * while covered by another page, so the texture viewport is still rendered over the other page + * but does not annoy the user that much because it's just a line on the bottom that may even + * be printed over existing bottom frame or very close to it. */ +void TextureBrowser_showGLWidget(){ + if ( isWindowConstructed && isGLWidgetConstructed ) + { + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_vfiller, FALSE, FALSE, 0, ui::Packing::START ); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_hframe, TRUE, TRUE, 0, ui::Packing::START ); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_hfiller, FALSE, FALSE, 0, ui::Packing::START ); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_gl_widget, TRUE, TRUE, 0, ui::Packing::START ); + GlobalTextureBrowser().m_gl_widget.show(); + } +} + +void TextureBrowser_hideGLWidget(){ + if ( isWindowConstructed && isGLWidgetConstructed ) + { + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_vfiller, TRUE, TRUE, 0, ui::Packing::START); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_hframe, FALSE, FALSE, 0, ui::Packing::END ); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_hfiller, TRUE, TRUE, 0, ui::Packing::START); + GlobalTextureBrowser().m_vframe.set_child_packing( GlobalTextureBrowser().m_gl_widget, FALSE, FALSE, 0, ui::Packing::END ); + GdkEventExpose event = {}; + TextureBrowser_expose( GlobalTextureBrowser().m_gl_widget, &event, &GlobalTextureBrowser() ); + } } +#endif // WORKAROUND_MACOS_GTK2_GLWIDGET const Vector3& TextureBrowser_getBackgroundColour( TextureBrowser& textureBrowser ){ return textureBrowser.color_textureback; diff --git a/radiant/texwindow.h b/radiant/texwindow.h index 80aa5e4d..f17a980d 100644 --- a/radiant/texwindow.h +++ b/radiant/texwindow.h @@ -60,4 +60,9 @@ void TextureBrowser_RefreshShaders(); ui::GLArea TextureBrowser_getGLWidget(); #endif // WORKAROUND_WINDOWS_GTK2_GLWIDGET +#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET +void TextureBrowser_showGLWidget(); +void TextureBrowser_hideGLWidget(); +#endif // WORKAROUND_MACOS_GTK2_GLWIDGET + #endif -- 2.39.2