Skip to content

Instantly share code, notes, and snippets.

@nocd5
Last active May 6, 2016 11:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nocd5/165286495c782b815b94 to your computer and use it in GitHub Desktop.
Save nocd5/165286495c782b815b94 to your computer and use it in GitHub Desktop.
D&D tab reordering 7.4.709 compliance
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 97ad6b0..e03295c 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2946,6 +2946,29 @@ on_select_tab(
}
/*
+ * Handle reordering the tabs (using D&D).
+ */
+ static void
+on_tab_reordered(
+ GtkNotebook *notebook UNUSED,
+ GtkNotebookPage *page UNUSED,
+ gint idx,
+ gpointer data UNUSED)
+{
+ if (!ignore_tabline_evt)
+ {
+ if ((tabpage_index(curtab) - 1) < idx)
+ {
+ tabpage_move(idx + 1);
+ }
+ else
+ {
+ tabpage_move(idx);
+ }
+ }
+}
+
+/*
* Show or hide the tabline.
*/
void
@@ -3020,6 +3043,9 @@ gui_mch_update_tabline(void)
page,
event_box,
nr++);
+ gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(gui.tabline),
+ page,
+ TRUE);
}
event_box = gtk_notebook_get_tab_label(GTK_NOTEBOOK(gui.tabline), page);
@@ -3387,11 +3413,15 @@ gui_mch_init(void)
gtk_misc_set_padding(GTK_MISC(label), 2, 2);
gtk_container_add(GTK_CONTAINER(event_box), label);
gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box);
+ gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(gui.tabline), page, TRUE);
}
gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
GTK_SIGNAL_FUNC(on_select_tab), NULL);
+ gtk_signal_connect(GTK_OBJECT(gui.tabline), "page-reordered",
+ GTK_SIGNAL_FUNC(on_tab_reordered), NULL);
+
/* Create a popup menu for the tab line and connect it. */
tabline_menu = create_tabline_menu();
gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event",
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 4fbf70e..4b8f5c6 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -4427,6 +4427,34 @@ initialise_tabline(void)
# endif
}
+/*
+ * Get tabpage_T from POINT.
+ */
+ static tabpage_T *
+GetTabFromPoint(
+ HWND hWnd,
+ POINT pt)
+{
+ tabpage_T *ptp = NULL;
+
+ if (gui_mch_showing_tabline())
+ {
+ TCHITTESTINFO htinfo;
+ htinfo.pt = pt;
+ /* ignore if a window under cusor is not tabcontrol. */
+ if (s_tabhwnd == hWnd)
+ {
+ int idx = TabCtrl_HitTest(s_tabhwnd, &htinfo);
+ if (idx != -1)
+ ptp = find_tabpage(idx + 1);
+ }
+ }
+ return ptp;
+}
+
+static POINT s_pt = {0, 0};
+static HCURSOR s_hCursor = NULL;
+
static LRESULT CALLBACK
tabline_wndproc(
HWND hwnd,
@@ -4434,7 +4462,73 @@ tabline_wndproc(
WPARAM wParam,
LPARAM lParam)
{
+ POINT pt;
+ tabpage_T *tp;
+ RECT rect;
+ int nCenter;
+ int idx0;
+ int idx1;
+
HandleMouseHide(uMsg, lParam);
+
+ switch (uMsg)
+ {
+ case WM_LBUTTONDOWN:
+ {
+ s_pt.x = GET_X_LPARAM(lParam);
+ s_pt.y = GET_Y_LPARAM(lParam);
+ SetCapture(hwnd);
+ s_hCursor = GetCursor(); /* backup default cursor */
+ break;
+ }
+ case WM_MOUSEMOVE:
+ if (GetCapture() == hwnd
+ && ((wParam & MK_LBUTTON)) != 0)
+ {
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = s_pt.y;
+ if (abs(pt.x - s_pt.x) > GetSystemMetrics(SM_CXDRAG))
+ {
+ SetCursor(LoadCursor(NULL, IDC_SIZEWE));
+
+ tp = GetTabFromPoint(hwnd, pt);
+ if (tp != NULL)
+ {
+ idx0 = tabpage_index(curtab) - 1;
+ idx1 = tabpage_index(tp) - 1;
+
+ TabCtrl_GetItemRect(hwnd, idx1, &rect);
+ nCenter = rect.left + (rect.right - rect.left) / 2;
+
+ /* Check if the mouse cursor goes over the center of
+ * the next tab to prevent "flickering". */
+ if ((idx0 < idx1) && (nCenter < pt.x))
+ {
+ tabpage_move(idx1 + 1);
+ update_screen(0);
+ }
+ else if ((idx1 < idx0) && (pt.x < nCenter))
+ {
+ tabpage_move(idx1);
+ update_screen(0);
+ }
+ }
+ }
+ }
+ break;
+ case WM_LBUTTONUP:
+ {
+ if (GetCapture() == hwnd)
+ {
+ SetCursor(s_hCursor);
+ ReleaseCapture();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
return CallWindowProc(s_tabline_wndproc, hwnd, uMsg, wParam, lParam);
}
#endif
@KamarajuKusumanchi
Copy link

This patch does not seem to apply cleanly. Could you please take a look?

% curl https://gist.githubusercontent.com/nocd5/165286495c782b815b94/raw/05cae8a40fe84f4e139b45467cd0e7d5f692cbd6/tabline-dnd.patch | git apply -v --index
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3927 100 3927 0 0 28267 0 --:--:-- --:--:-- --:--:-- 28456
Checking patch src/gui_gtk_x11.c...
Hunk #1 succeeded at 3535 (offset 589 lines).
Hunk #2 succeeded at 3643 (offset 600 lines).
error: while searching for:
gtk_misc_set_padding(GTK_MISC(label), 2, 2);
gtk_container_add(GTK_CONTAINER(event_box), label);
gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, event_box);
}

gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
                   GTK_SIGNAL_FUNC(on_select_tab), NULL);

/* Create a popup menu for the tab line and connect it. */
tabline_menu = create_tabline_menu();
gtk_signal_connect_object(GTK_OBJECT(gui.tabline), "button_press_event",

error: patch failed: src/gui_gtk_x11.c:3387
error: src/gui_gtk_x11.c: patch does not apply
Checking patch src/gui_w32.c...
Hunk #1 succeeded at 8354 (offset 3927 lines).
Hunk #2 succeeded at 8389 (offset 3927 lines).

I am using

% git log -n 1
commit 827b165b2aebad2cfe98cc6d5804c6c0fe8afd89
Author: Bram Moolenaar Bram@vim.org
Date: Thu May 5 18:14:03 2016 +0200

patch 7.4.1819
Problem:    Compiler warnings when sprintf() is a macro.
Solution:   Don't interrupt sprintf() with an #ifdef. (Michael Jarvis,
            closes #788)

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