@@ -7567,6 +7567,26 @@ nCopyAnsiToWideChar(
75677567
75687568
75697569#ifdef FEAT_TEAROFF
7570+ /*
7571+ * Lookup menu handle from "menu_id".
7572+ */
7573+ static HMENU
7574+ tearoff_lookup_menuhandle (
7575+ vimmenu_T * menu ,
7576+ WORD menu_id )
7577+ {
7578+ for ( ; menu != NULL ; menu = menu -> next )
7579+ {
7580+ if (menu -> modes == 0 ) /* this menu has just been deleted */
7581+ continue ;
7582+ if (menu_is_separator (menu -> dname ))
7583+ continue ;
7584+ if ((WORD )((long_u )(menu -> submenu_id ) | (DWORD )0x8000 ) == menu_id )
7585+ return menu -> submenu_id ;
7586+ }
7587+ return NULL ;
7588+ }
7589+
75707590/*
75717591 * The callback function for all the modeless dialogs that make up the
75727592 * "tearoff menus" Very simple - forward button presses (to fool Vim into
@@ -7580,7 +7600,10 @@ tearoff_callback(
75807600 LPARAM lParam )
75817601{
75827602 if (message == WM_INITDIALOG )
7603+ {
7604+ SetWindowLongPtr (hwnd , DWLP_USER , (LONG_PTR )lParam );
75837605 return (TRUE);
7606+ }
75847607
75857608 /* May show the mouse pointer again. */
75867609 HandleMouseHide (message , lParam );
@@ -7594,8 +7617,11 @@ tearoff_callback(
75947617
75957618 if (GetCursorPos (& mp ) && GetWindowRect (hwnd , & rect ))
75967619 {
7620+ vimmenu_T * menu ;
7621+
7622+ menu = (vimmenu_T * )GetWindowLongPtr (hwnd , DWLP_USER );
75977623 (void )TrackPopupMenu (
7598- ( HMENU )( long_u )( LOWORD (wParam ) ^ 0x8000 ),
7624+ tearoff_lookup_menuhandle ( menu , LOWORD (wParam )),
75997625 TPM_LEFTALIGN | TPM_LEFTBUTTON ,
76007626 (int )rect .right - 8 ,
76017627 (int )mp .y ,
@@ -7707,6 +7733,7 @@ gui_mch_tearoff(
77077733 WORD dlgwidth ;
77087734 WORD menuID ;
77097735 vimmenu_T * pmenu ;
7736+ vimmenu_T * top_menu ;
77107737 vimmenu_T * the_menu = menu ;
77117738 HWND hwnd ;
77127739 HDC hdc ;
@@ -7885,6 +7912,7 @@ gui_mch_tearoff(
78857912 menu = menu -> children -> next ;
78867913 else
78877914 menu = menu -> children ;
7915+ top_menu = menu ;
78887916 for ( ; menu != NULL ; menu = menu -> next )
78897917 {
78907918 if (menu -> modes == 0 ) /* this menu has just been deleted */
@@ -7995,11 +8023,12 @@ gui_mch_tearoff(
79958023
79968024
79978025 /* show modelessly */
7998- the_menu -> tearoff_handle = CreateDialogIndirect (
8026+ the_menu -> tearoff_handle = CreateDialogIndirectParam (
79998027 s_hinst ,
80008028 (LPDLGTEMPLATE )pdlgtemplate ,
80018029 s_hwnd ,
8002- (DLGPROC )tearoff_callback );
8030+ (DLGPROC )tearoff_callback ,
8031+ (LPARAM )top_menu );
80038032
80048033 LocalFree (LocalHandle (pdlgtemplate ));
80058034 SelectFont (hdc , oldFont );
@@ -8151,14 +8180,108 @@ initialise_tabline(void)
81518180# endif
81528181}
81538182
8183+ /*
8184+ * Get tabpage_T from POINT.
8185+ */
8186+ static tabpage_T *
8187+ GetTabFromPoint (
8188+ HWND hWnd ,
8189+ POINT pt )
8190+ {
8191+ tabpage_T * ptp = NULL ;
8192+
8193+ if (gui_mch_showing_tabline ())
8194+ {
8195+ TCHITTESTINFO htinfo ;
8196+ htinfo .pt = pt ;
8197+ /* ignore if a window under cusor is not tabcontrol. */
8198+ if (s_tabhwnd == hWnd )
8199+ {
8200+ int idx = TabCtrl_HitTest (s_tabhwnd , & htinfo );
8201+ if (idx != -1 )
8202+ ptp = find_tabpage (idx + 1 );
8203+ }
8204+ }
8205+ return ptp ;
8206+ }
8207+
8208+ static POINT s_pt = {0 , 0 };
8209+ static HCURSOR s_hCursor = NULL ;
8210+
81548211 static LRESULT CALLBACK
81558212tabline_wndproc (
81568213 HWND hwnd ,
81578214 UINT uMsg ,
81588215 WPARAM wParam ,
81598216 LPARAM lParam )
81608217{
8218+ POINT pt ;
8219+ tabpage_T * tp ;
8220+ RECT rect ;
8221+ int nCenter ;
8222+ int idx0 ;
8223+ int idx1 ;
8224+
81618225 HandleMouseHide (uMsg , lParam );
8226+
8227+ switch (uMsg )
8228+ {
8229+ case WM_LBUTTONDOWN :
8230+ {
8231+ s_pt .x = GET_X_LPARAM (lParam );
8232+ s_pt .y = GET_Y_LPARAM (lParam );
8233+ SetCapture (hwnd );
8234+ s_hCursor = GetCursor (); /* backup default cursor */
8235+ break ;
8236+ }
8237+ case WM_MOUSEMOVE :
8238+ if (GetCapture () == hwnd
8239+ && ((wParam & MK_LBUTTON )) != 0 )
8240+ {
8241+ pt .x = GET_X_LPARAM (lParam );
8242+ pt .y = s_pt .y ;
8243+ if (abs (pt .x - s_pt .x ) > GetSystemMetrics (SM_CXDRAG ))
8244+ {
8245+ SetCursor (LoadCursor (NULL , IDC_SIZEWE ));
8246+
8247+ tp = GetTabFromPoint (hwnd , pt );
8248+ if (tp != NULL )
8249+ {
8250+ idx0 = tabpage_index (curtab ) - 1 ;
8251+ idx1 = tabpage_index (tp ) - 1 ;
8252+
8253+ TabCtrl_GetItemRect (hwnd , idx1 , & rect );
8254+ nCenter = rect .left + (rect .right - rect .left ) / 2 ;
8255+
8256+ /* Check if the mouse cursor goes over the center of
8257+ * the next tab to prevent "flickering". */
8258+ if ((idx0 < idx1 ) && (nCenter < pt .x ))
8259+ {
8260+ tabpage_move (idx1 + 1 );
8261+ update_screen (0 );
8262+ }
8263+ else if ((idx1 < idx0 ) && (pt .x < nCenter ))
8264+ {
8265+ tabpage_move (idx1 );
8266+ update_screen (0 );
8267+ }
8268+ }
8269+ }
8270+ }
8271+ break ;
8272+ case WM_LBUTTONUP :
8273+ {
8274+ if (GetCapture () == hwnd )
8275+ {
8276+ SetCursor (s_hCursor );
8277+ ReleaseCapture ();
8278+ }
8279+ break ;
8280+ }
8281+ default :
8282+ break ;
8283+ }
8284+
81628285 return CallWindowProc (s_tabline_wndproc , hwnd , uMsg , wParam , lParam );
81638286}
81648287#endif
0 commit comments