To: vim_dev@googlegroups.com Subject: Patch 8.2.4159 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4159 Problem: MS-Windows: _WndProc() is very long. Solution: Move code to separate functions. (Ken Takata, closes #9573) Files: src/gui_w32.c *** ../vim-8.2.4158/src/gui_w32.c 2022-01-20 15:05:19.023177158 +0000 --- src/gui_w32.c 2022-01-20 15:08:44.783156449 +0000 *************** *** 4580,4585 **** --- 4580,4816 ---- return TRUE; } + #ifdef FEAT_GUI_TABLINE + static void + _OnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags) + { + if (gui_mch_showing_tabline()) + { + POINT pt; + RECT rect; + + /* + * If the cursor is on the tabline, display the tab menu + */ + GetCursorPos(&pt); + GetWindowRect(s_textArea, &rect); + if (pt.y < rect.top) + { + show_tabline_popup_menu(); + return; + } + } + FORWARD_WM_RBUTTONUP(hwnd, x, y, keyFlags, DefWindowProcW); + } + + static void + _OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) + { + /* + * If the user double clicked the tabline, create a new tab + */ + if (gui_mch_showing_tabline()) + { + POINT pt; + RECT rect; + + GetCursorPos(&pt); + GetWindowRect(s_textArea, &rect); + if (pt.y < rect.top) + send_tabline_menu_event(0, TABLINE_MENU_NEW); + } + FORWARD_WM_LBUTTONDOWN(hwnd, fDoubleClick, x, y, keyFlags, DefWindowProcW); + } + #endif + + static UINT + _OnNCHitTest(HWND hwnd, int xPos, int yPos) + { + UINT result; + int x, y; + + result = FORWARD_WM_NCHITTEST(hwnd, xPos, yPos, DefWindowProcW); + if (result != HTCLIENT) + return result; + + #ifdef FEAT_GUI_TABLINE + if (gui_mch_showing_tabline()) + { + RECT rct; + + // If the cursor is on the GUI tabline, don't process this event + GetWindowRect(s_textArea, &rct); + if (yPos < rct.top) + return result; + } + #endif + (void)gui_mch_get_winpos(&x, &y); + xPos -= x; + + if (xPos < 48) // TODO should use system metric? + return HTBOTTOMLEFT; + else + return HTBOTTOMRIGHT; + } + + #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) + static LRESULT + _OnNotify(HWND hwnd, UINT id, NMHDR *hdr) + { + switch (hdr->code) + { + case TTN_GETDISPINFOW: + case TTN_GETDISPINFO: + { + char_u *str = NULL; + static void *tt_text = NULL; + + VIM_CLEAR(tt_text); + + # ifdef FEAT_GUI_TABLINE + if (gui_mch_showing_tabline() + && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd)) + { + POINT pt; + /* + * Mouse is over the GUI tabline. Display the + * tooltip for the tab under the cursor + * + * Get the cursor position within the tab control + */ + GetCursorPos(&pt); + if (ScreenToClient(s_tabhwnd, &pt) != 0) + { + TCHITTESTINFO htinfo; + int idx; + + /* + * Get the tab under the cursor + */ + htinfo.pt.x = pt.x; + htinfo.pt.y = pt.y; + idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); + if (idx != -1) + { + tabpage_T *tp; + + tp = find_tabpage(idx + 1); + if (tp != NULL) + { + get_tabline_label(tp, TRUE); + str = NameBuff; + } + } + } + } + # endif + # ifdef FEAT_TOOLBAR + # ifdef FEAT_GUI_TABLINE + else + # endif + { + UINT idButton; + vimmenu_T *pMenu; + + idButton = (UINT) hdr->idFrom; + pMenu = gui_mswin_find_menu(root_menu, idButton); + if (pMenu) + str = pMenu->strings[MENU_INDEX_TIP]; + } + # endif + if (str == NULL) + break; + + // Set the maximum width, this also enables using \n for + // line break. + SendMessage(hdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500); + + if (hdr->code == TTN_GETDISPINFOW) + { + LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)hdr; + + tt_text = enc_to_utf16(str, NULL); + lpdi->lpszText = tt_text; + // can't show tooltip if failed + } + else + { + LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)hdr; + + if (STRLEN(str) < sizeof(lpdi->szText) + || ((tt_text = vim_strsave(str)) == NULL)) + vim_strncpy((char_u *)lpdi->szText, str, + sizeof(lpdi->szText) - 1); + else + lpdi->lpszText = tt_text; + } + } + break; + + # ifdef FEAT_GUI_TABLINE + case TCN_SELCHANGE: + if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd)) + { + send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1); + return 0L; + } + break; + + case NM_RCLICK: + if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd)) + { + show_tabline_popup_menu(); + return 0L; + } + break; + # endif + + default: + break; + } + return DefWindowProcW(hwnd, WM_NOTIFY, (WPARAM)id, (LPARAM)hdr); + } + #endif + + #if defined(MENUHINTS) && defined(FEAT_MENU) + static LRESULT + _OnMenuSelect(HWND hwnd, WPARAM wParam, LPARAM lParam) + { + if (((UINT) HIWORD(wParam) + & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP))) + == MF_HILITE + && (State & CMDLINE) == 0) + { + UINT idButton; + vimmenu_T *pMenu; + static int did_menu_tip = FALSE; + + if (did_menu_tip) + { + msg_clr_cmdline(); + setcursor(); + out_flush(); + did_menu_tip = FALSE; + } + + idButton = (UINT)LOWORD(wParam); + pMenu = gui_mswin_find_menu(root_menu, idButton); + if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0 + && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1) + { + ++msg_hist_off; + msg((char *)pMenu->strings[MENU_INDEX_TIP]); + --msg_hist_off; + setcursor(); + out_flush(); + did_menu_tip = TRUE; + } + return 0L; + } + return DefWindowProcW(hwnd, WM_MENUSELECT, wParam, lParam); + } + #endif + static LRESULT _OnDpiChanged(HWND hwnd, UINT xdpi, UINT ydpi, RECT *rc) { *************** *** 4648,4693 **** #ifdef FEAT_NETBEANS_INTG HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, _OnWindowPosChanged); #endif - #ifdef FEAT_GUI_TABLINE ! case WM_RBUTTONUP: ! { ! if (gui_mch_showing_tabline()) ! { ! POINT pt; ! RECT rect; ! ! /* ! * If the cursor is on the tabline, display the tab menu ! */ ! GetCursorPos((LPPOINT)&pt); ! GetWindowRect(s_textArea, &rect); ! if (pt.y < rect.top) ! { ! show_tabline_popup_menu(); ! return 0L; ! } ! } ! return DefWindowProcW(hwnd, uMsg, wParam, lParam); ! } ! case WM_LBUTTONDBLCLK: ! { ! /* ! * If the user double clicked the tabline, create a new tab ! */ ! if (gui_mch_showing_tabline()) ! { ! POINT pt; ! RECT rect; ! ! GetCursorPos((LPPOINT)&pt); ! GetWindowRect(s_textArea, &rect); ! if (pt.y < rect.top) ! send_tabline_menu_event(0, TABLINE_MENU_NEW); ! } ! return DefWindowProcW(hwnd, uMsg, wParam, lParam); ! } #endif case WM_QUERYENDSESSION: // System wants to go down. gui_shell_closed(); // Will exit when no changed buffers. --- 4879,4889 ---- #ifdef FEAT_NETBEANS_INTG HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, _OnWindowPosChanged); #endif #ifdef FEAT_GUI_TABLINE ! HANDLE_MSG(hwnd, WM_RBUTTONUP, _OnRButtonUp); ! HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, _OnLButtonDown); #endif + HANDLE_MSG(hwnd, WM_NCHITTEST, _OnNCHitTest); case WM_QUERYENDSESSION: // System wants to go down. gui_shell_closed(); // Will exit when no changed buffers. *************** *** 4756,4955 **** #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) case WM_NOTIFY: ! switch (((LPNMHDR) lParam)->code) ! { ! case TTN_GETDISPINFOW: ! case TTN_GETDISPINFO: ! { ! LPNMHDR hdr = (LPNMHDR)lParam; ! char_u *str = NULL; ! static void *tt_text = NULL; ! ! VIM_CLEAR(tt_text); ! ! # ifdef FEAT_GUI_TABLINE ! if (gui_mch_showing_tabline() ! && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd)) ! { ! POINT pt; ! /* ! * Mouse is over the GUI tabline. Display the ! * tooltip for the tab under the cursor ! * ! * Get the cursor position within the tab control ! */ ! GetCursorPos(&pt); ! if (ScreenToClient(s_tabhwnd, &pt) != 0) ! { ! TCHITTESTINFO htinfo; ! int idx; ! ! /* ! * Get the tab under the cursor ! */ ! htinfo.pt.x = pt.x; ! htinfo.pt.y = pt.y; ! idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); ! if (idx != -1) ! { ! tabpage_T *tp; ! ! tp = find_tabpage(idx + 1); ! if (tp != NULL) ! { ! get_tabline_label(tp, TRUE); ! str = NameBuff; ! } ! } ! } ! } ! # endif ! # ifdef FEAT_TOOLBAR ! # ifdef FEAT_GUI_TABLINE ! else ! # endif ! { ! UINT idButton; ! vimmenu_T *pMenu; ! ! idButton = (UINT) hdr->idFrom; ! pMenu = gui_mswin_find_menu(root_menu, idButton); ! if (pMenu) ! str = pMenu->strings[MENU_INDEX_TIP]; ! } ! # endif ! if (str != NULL) ! { ! if (hdr->code == TTN_GETDISPINFOW) ! { ! LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam; ! ! // Set the maximum width, this also enables using ! // \n for line break. ! SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, ! 0, 500); ! ! tt_text = enc_to_utf16(str, NULL); ! lpdi->lpszText = tt_text; ! // can't show tooltip if failed ! } ! else ! { ! LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)lParam; ! ! // Set the maximum width, this also enables using ! // \n for line break. ! SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, ! 0, 500); ! ! if (STRLEN(str) < sizeof(lpdi->szText) ! || ((tt_text = vim_strsave(str)) == NULL)) ! vim_strncpy((char_u *)lpdi->szText, str, ! sizeof(lpdi->szText) - 1); ! else ! lpdi->lpszText = tt_text; ! } ! } ! } ! break; ! # ifdef FEAT_GUI_TABLINE ! case TCN_SELCHANGE: ! if (gui_mch_showing_tabline() ! && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) ! { ! send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1); ! return 0L; ! } ! break; ! ! case NM_RCLICK: ! if (gui_mch_showing_tabline() ! && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) ! { ! show_tabline_popup_menu(); ! return 0L; ! } ! break; ! # endif ! default: ! # ifdef FEAT_GUI_TABLINE ! if (gui_mch_showing_tabline() ! && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) ! return DefWindowProcW(hwnd, uMsg, wParam, lParam); ! # endif ! break; ! } ! break; #endif #if defined(MENUHINTS) && defined(FEAT_MENU) case WM_MENUSELECT: ! if (((UINT) HIWORD(wParam) ! & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP))) ! == MF_HILITE ! && (State & CMDLINE) == 0) ! { ! UINT idButton; ! vimmenu_T *pMenu; ! static int did_menu_tip = FALSE; ! ! if (did_menu_tip) ! { ! msg_clr_cmdline(); ! setcursor(); ! out_flush(); ! did_menu_tip = FALSE; ! } ! ! idButton = (UINT)LOWORD(wParam); ! pMenu = gui_mswin_find_menu(root_menu, idButton); ! if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0 ! && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1) ! { ! ++msg_hist_off; ! msg((char *)pMenu->strings[MENU_INDEX_TIP]); ! --msg_hist_off; ! setcursor(); ! out_flush(); ! did_menu_tip = TRUE; ! } ! return 0L; ! } ! break; #endif - case WM_NCHITTEST: - { - LRESULT result; - int x, y; - int xPos = GET_X_LPARAM(lParam); - - result = DefWindowProcW(hwnd, uMsg, wParam, lParam); - if (result == HTCLIENT) - { - #ifdef FEAT_GUI_TABLINE - if (gui_mch_showing_tabline()) - { - int yPos = GET_Y_LPARAM(lParam); - RECT rct; - - // If the cursor is on the GUI tabline, don't process this - // event - GetWindowRect(s_textArea, &rct); - if (yPos < rct.top) - return result; - } - #endif - (void)gui_mch_get_winpos(&x, &y); - xPos -= x; - - if (xPos < 48) // TODO should use system metric? - return HTBOTTOMLEFT; - else - return HTBOTTOMRIGHT; - } - else - return result; - } - // break; notreached #ifdef FEAT_MBYTE_IME case WM_IME_NOTIFY: --- 4952,4964 ---- #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) case WM_NOTIFY: ! return _OnNotify(hwnd, (UINT)wParam, (NMHDR*)lParam); #endif + #if defined(MENUHINTS) && defined(FEAT_MENU) case WM_MENUSELECT: ! return _OnMenuSelect(hwnd, wParam, lParam); #endif #ifdef FEAT_MBYTE_IME case WM_IME_NOTIFY: *************** *** 4971,4977 **** if (uMsg == s_findrep_msg && s_findrep_msg != 0) _OnFindRepl(); #endif ! return DefWindowProcW(hwnd, uMsg, wParam, lParam); } return DefWindowProcW(hwnd, uMsg, wParam, lParam); --- 4980,4986 ---- if (uMsg == s_findrep_msg && s_findrep_msg != 0) _OnFindRepl(); #endif ! break; } return DefWindowProcW(hwnd, uMsg, wParam, lParam); *** ../vim-8.2.4158/src/version.c 2022-01-20 15:05:19.027177080 +0000 --- src/version.c 2022-01-20 15:09:36.650053749 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4159, /**/ -- Michael: There is no such thing as a dump question. Bernard: Sure there is. For example "what is a core dump?" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///