Skip to content

Instantly share code, notes, and snippets.

@ma8ma
Last active October 17, 2018 14:14
Show Gist options
  • Save ma8ma/04b4c601a04be901a928df22faca354c to your computer and use it in GitHub Desktop.
Save ma8ma/04b4c601a04be901a928df22faca354c to your computer and use it in GitHub Desktop.
[FAIL] jd-gtk3 feature-r2 tabnote patch
diff --git a/src/skeleton/tabnote.cpp b/src/skeleton/tabnote.cpp
index 2474c07..439eec8 100644
--- a/src/skeleton/tabnote.cpp
+++ b/src/skeleton/tabnote.cpp
@@ -1,6 +1,6 @@
// ライセンス: GPL2
-//#define _DEBUG
+#define _DEBUG
//#define _DEBUG_RESIZE_TAB
#include "jddebug.h"
@@ -18,7 +18,171 @@
using namespace SKELETON;
-#if !GTKMM_CHECK_VERSION(3,0,0)
+#if GTK_CHECK_VERSION(3,0,0)
+
+// 関数プロトタイプの引用
+//
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-20/gtk/gtkcssgadgetprivate.h
+
+#if GTKMM_CHECK_VERSION(3,20,0)
+extern "C" {
+ typedef struct _GtkCssGadget GtkCssGadget;
+ void gtk_css_gadget_get_border_allocation( GtkCssGadget* gadget, GtkAllocation* allocation, int* baseline );
+}
+#endif
+
+// 構造体定義の引用
+// ブランチのヘッドを参照したのでプレリリースの変更までは追跡していない
+//
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-0/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-2/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-4/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-8/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-12/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-14/gtk/gtknotebook.c
+// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-20/gtk/gtknotebook.c
+
+// switch-pageシグナルにGtkNotebookPageを使用しているのでアンダースコア付きを使う
+struct _GtkNotebookPage;
+
+typedef enum
+{
+ DRAG_OPERATION_NONE,
+ DRAG_OPERATION_REORDER,
+ DRAG_OPERATION_DETACH
+} GtkNotebookDragOperation;
+
+enum {
+ ACTION_WIDGET_START,
+ ACTION_WIDGET_END,
+ N_ACTION_WIDGETS
+};
+
+struct _GtkNotebookPrivate
+{
+ GtkNotebookDragOperation operation;
+ _GtkNotebookPage *cur_page;
+ _GtkNotebookPage *detached_tab;
+#if GTK_CHECK_VERSION(3,12,0)
+ _GtkNotebookPage *prelight_tab;
+#endif
+ GtkTargetList *source_targets;
+ GtkWidget *action_widget[N_ACTION_WIDGETS];
+ GtkWidget *dnd_window;
+ GtkWidget *menu;
+
+ GdkWindow *drag_window;
+ GdkWindow *event_window;
+
+#if GTK_CHECK_VERSION(3,20,0)
+ GtkCssGadget *gadget;
+ GtkCssGadget *stack_gadget;
+ GtkCssGadget *header_gadget;
+ GtkCssGadget *tabs_gadget;
+ GtkCssGadget *arrow_gadget[4];
+
+#endif
+ GList *children;
+ GList *first_tab; /* The first tab visible (for scrolling notebooks) */
+ GList *focus_tab;
+
+ gint drag_begin_x;
+ gint drag_begin_y;
+ gint drag_offset_x;
+ gint drag_offset_y;
+ gint drag_window_x;
+ gint drag_window_y;
+ gint mouse_x;
+ gint mouse_y;
+ gint pressed_button;
+
+ GQuark group;
+
+ guint dnd_timer;
+ guint switch_tab_timer;
+#if GTK_CHECK_VERSION(3,8,0)
+ GList *switch_tab;
+#endif
+
+#if !GTK_CHECK_VERSION(3,4,0)
+ guint16 tab_hborder;
+ guint16 tab_vborder;
+
+#endif
+ guint32 timer;
+#if !GTK_CHECK_VERSION(3,20,0)
+ guint32 timestamp;
+
+ guint button : 2;
+#endif
+ guint child_has_focus : 1;
+ guint click_child : 3;
+#if !GTK_CHECK_VERSION(3,20,0)
+ guint during_detach : 1;
+ guint during_reorder : 1;
+#endif
+#if GTK_CHECK_VERSION(3,14,0)
+ guint remove_in_detach : 1;
+#endif
+ guint focus_out : 1; /* Flag used by ::move-focus-out implementation */
+ guint has_scrolled : 1;
+#if !GTK_CHECK_VERSION(3,2,0)
+ guint have_visible_child : 1;
+ guint homogeneous : 1;
+#endif
+ guint in_child : 3;
+ guint need_timer : 1;
+ guint show_border : 1;
+ guint show_tabs : 1;
+ guint scrollable : 1;
+ guint tab_pos : 2;
+#if GTK_CHECK_VERSION(3,20,0)
+ guint tabs_reversed : 1;
+ guint rootwindow_drop : 1;
+#else
+
+ guint has_before_previous : 1;
+ guint has_before_next : 1;
+ guint has_after_previous : 1;
+ guint has_after_next : 1;
+#endif
+};
+
+struct _GtkNotebookPage
+{
+ GtkWidget *child;
+ GtkWidget *tab_label;
+ GtkWidget *menu_label;
+ GtkWidget *last_focus_child; /* Last descendant of the page that had focus */
+
+#if GTK_CHECK_VERSION(3,20,0)
+ GtkCssGadget *gadget; /* gadget used for the tab itself */
+
+#endif
+ guint default_menu : 1; /* If true, we create the menu label ourself */
+ guint default_tab : 1; /* If true, we create the tab label ourself */
+ guint expand : 1;
+ guint fill : 1;
+ guint reorderable : 1;
+ guint detachable : 1;
+
+#if !GTK_CHECK_VERSION(3,20,0)
+ /* if true, the tab label was visible on last allocation; we track this so
+ * that we know to redraw the tab area if a tab label was hidden then shown
+ * without changing position */
+ guint tab_allocated_visible : 1;
+
+#endif
+ GtkRequisition requisition;
+#if !GTK_CHECK_VERSION(3,20,0)
+ GtkAllocation allocation;
+#endif
+
+ gulong mnemonic_activate_signal;
+ gulong notify_visible_handler;
+};
+
+#else // !GTKMM_CHECK_VERSION(3,0,0)
//////////////////////////////////////////
//
@@ -630,67 +794,17 @@ void TabNotebook::calc_tabsize()
std::cout << "TabNotebook::calc_tabsize\n";
#endif
+ const GtkNotebook* const notebook = gobj();
#if GTKMM_CHECK_VERSION(3,0,0)
- // gtk3は実装の詳細がバージョンによって異なるためタブの代わりにラベルの領域を取得する
- const int n_pages = get_n_pages();
- // ラベルの領域とタブの領域のオフセットを概算する
- // GTKテーマが変更されるとオフセットが変わる可能性があるので毎回計算する
- // XXX: この修正はラベルの左右の余白の大きさが同じであることを前提とする
- int offset = 0;
-
- if( n_pages > 1 ) {
- const auto* tab1 = get_tablabel( 0 );
- for( int i = 1; i < n_pages; ++i ) {
- const auto* const tab2 = get_tablabel( i );
- if( tab1 && tab2 && tab1->get_mapped() && tab2->get_mapped() ) {
- const auto alloc1 = tab1->get_allocation();
- const auto alloc2 = tab2->get_allocation();
- offset = alloc2.get_x() - ( alloc1.get_x() + alloc1.get_width() );
-#ifdef _DEBUG
- std::cout << "computed offset = " << offset << std::endl;
-#endif
- break;
- }
- tab1 = tab2;
- }
- }
-
- for( int i = 0; i < n_pages; ++i ) {
- auto* const tab_label = get_tablabel( i );
- if( tab_label ) {
- int tab_x = -1;
- int tab_y = -1;
- int tab_w = -1;
- int tab_h = -1;
-
- if( tab_label->get_mapped() ) {
- Gdk::Rectangle rect = tab_label->get_allocation();
-
- tab_x = rect.get_x() - ( offset / 2 );
- tab_y = rect.get_y();
- tab_w = rect.get_width() + offset;
- tab_h = rect.get_height();
-
- m_tab_mrg = 0;
- }
-
-#ifdef _DEBUG
- std::cout << "page = " << i << " x = " << tab_x << " w = " << tab_w << " mrg = " << m_tab_mrg << std::endl;
+ GList* children = notebook->priv->children;
+#else
+ GList* children = notebook->children;
#endif
- tab_label->set_tab_x( tab_x );
- tab_label->set_tab_y( tab_y );
- tab_label->set_tab_width( tab_w );
- tab_label->set_tab_height( tab_h );
- }
- }
-#else // !GTKMM_CHECK_VERSION(3,0,0)
- GtkNotebook *notebook = gobj();
- GList * children = notebook->children;
for( int i = 0; children ; ++i, children = children->next ){
- GtkNotebookPage* page = ( GtkNotebookPage* ) children->data;
- SKELETON::TabLabel* tab = get_tablabel( i );
+ const auto page = static_cast< _GtkNotebookPage* >( children->data );
+ SKELETON::TabLabel* const tab = get_tablabel( i );
if( tab ){
int tab_x = -1;
@@ -705,10 +819,19 @@ void TabNotebook::calc_tabsize()
#endif
if( mapped && page ) {
+#if GTKMM_CHECK_VERSION(3,20,0)
+ GtkAllocation allocation;
+ gtk_css_gadget_get_border_allocation( page->gadget, &allocation, NULL );
+ tab_x = allocation.x;
+ tab_y = allocation.y;
+ tab_w = allocation.width;
+ tab_h = allocation.height;
+#else
tab_x = page->allocation.x;
tab_y = page->allocation.y;
tab_w = page->allocation.width;
tab_h = page->allocation.height;
+#endif
Gdk::Rectangle rect = tab->get_allocation();
m_tab_mrg = tab_w - rect.get_width();
@@ -723,7 +846,6 @@ void TabNotebook::calc_tabsize()
tab->set_tab_height( tab_h );
}
}
-#endif // GTKMM_CHECK_VERSION(3,0,0)
}
@ma8ma
Copy link
Author

ma8ma commented Oct 17, 2018

これは ma8ma/JDim#3 を修正するパッチです。
パッチを適用するとタブの割り当てられた領域を概算する代わりに実装の詳細から取得します。
gtk 3.20以上の環境ではgtk_css_gadget_get_border_allocation()のシンボルがundefined referenceになるのでコンパイルエラーになります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment