X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=win32ss%2Fuser%2Fwinsrv%2Fconsrv%2Ffrontends%2Fgui%2Fconwnd.c;h=c92593d075ab1db2293b4933109df80d920f459d;hp=35942be114f002e5526eada025ac33d2ae9e3aa5;hb=ac51557c0ab123c1fb222f6514179fcc913ac8c9;hpb=dc4ef8e972b71411b398a1a1b262094ac9f8ee33 diff --git a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index 35942be114f..c92593d075a 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -12,7 +12,7 @@ /* INCLUDES *******************************************************************/ #include - +#include #include #define NDEBUG @@ -250,12 +250,32 @@ AppendMenuItems(HMENU hMenu, } while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } -static VOID +//static +VOID CreateSysMenu(HWND hWnd) { + MENUITEMINFOW mii; + WCHAR szMenuStringBack[255]; + WCHAR *ptrTab; HMENU hMenu = GetSystemMenu(hWnd, FALSE); if (hMenu != NULL) { + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING; + mii.dwTypeData = szMenuStringBack; + mii.cch = sizeof(szMenuStringBack)/sizeof(WCHAR); + + GetMenuItemInfoW(hMenu, SC_CLOSE, FALSE, &mii); + + ptrTab = wcschr(szMenuStringBack, '\t'); + if (ptrTab) + { + *ptrTab = '\0'; + mii.cch = wcslen(szMenuStringBack); + + SetMenuItemInfoW(hMenu, SC_CLOSE, FALSE, &mii); + } + AppendMenuItems(hMenu, GuiConsoleMainMenuItems); DrawMenuBar(hWnd); } @@ -282,7 +302,9 @@ Copy(PGUI_CONSOLE_DATA GuiData); static VOID Paste(PGUI_CONSOLE_DATA GuiData); static VOID -UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord); +UpdateSelection(PGUI_CONSOLE_DATA GuiData, + PCOORD SelectionAnchor OPTIONAL, + PCOORD coord); static VOID Mark(PGUI_CONSOLE_DATA GuiData) @@ -290,30 +312,28 @@ Mark(PGUI_CONSOLE_DATA GuiData) PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; /* Clear the old selection */ - // UpdateSelection(GuiData, NULL); GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION; /* Restart a new selection */ - GuiData->dwSelectionCursor.X = ActiveBuffer->ViewOrigin.X; - GuiData->dwSelectionCursor.Y = ActiveBuffer->ViewOrigin.Y; - GuiData->Selection.dwSelectionAnchor = GuiData->dwSelectionCursor; - UpdateSelection(GuiData, &GuiData->Selection.dwSelectionAnchor); + GuiData->dwSelectionCursor = ActiveBuffer->ViewOrigin; + UpdateSelection(GuiData, + &GuiData->dwSelectionCursor, + &GuiData->dwSelectionCursor); } static VOID SelectAll(PGUI_CONSOLE_DATA GuiData) { PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; + COORD SelectionAnchor; /* Clear the old selection */ - // UpdateSelection(GuiData, NULL); GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION; /* * The selection area extends to the whole screen buffer's width. */ - GuiData->Selection.dwSelectionAnchor.X = 0; - GuiData->Selection.dwSelectionAnchor.Y = 0; + SelectionAnchor.X = SelectionAnchor.Y = 0; GuiData->dwSelectionCursor.X = ActiveBuffer->ScreenBufferSize.X - 1; /* @@ -339,7 +359,7 @@ SelectAll(PGUI_CONSOLE_DATA GuiData) /* Restart a new selection */ GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION; - UpdateSelection(GuiData, &GuiData->dwSelectionCursor); + UpdateSelection(GuiData, &SelectionAnchor, &GuiData->dwSelectionCursor); } static LRESULT @@ -568,7 +588,8 @@ OnNcCreate(HWND hWnd, LPCREATESTRUCTW Create) SetWindowLongPtrW(GuiData->hWindow, GWLP_USERDATA, (DWORD_PTR)GuiData); SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); - CreateSysMenu(GuiData->hWindow); + // FIXME: HACK: Potential HACK for CORE-8129; see revision 63595. + //CreateSysMenu(GuiData->hWindow); DPRINT("OnNcCreate - setting start event\n"); SetEvent(GuiData->hGuiInitEvent); @@ -589,7 +610,6 @@ GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData); static VOID OnActivate(PGUI_CONSOLE_DATA GuiData, WPARAM wParam) { - PCONSOLE Console = GuiData->Console; WORD ActivationState = LOWORD(wParam); DPRINT1("WM_ACTIVATE - ActivationState = %d\n"); @@ -616,12 +636,11 @@ OnActivate(PGUI_CONSOLE_DATA GuiData, WPARAM wParam) } /* - * When we are in QuickEdit mode, ignore the next mouse signal - * when we are going to be enabled again via the mouse, in order - * to prevent e.g. an erroneous right-click from the user which - * would have as an effect to paste some unwanted text... + * Ignore the next mouse signal when we are going to be enabled again via + * the mouse, in order to prevent, e.g. when we are in Edit mode, erroneous + * mouse actions from the user that could spoil text selection or copy/pastes. */ - if (Console->QuickEdit && (ActivationState == WA_CLICKACTIVE)) + if (ActivationState == WA_CLICKACTIVE) GuiData->IgnoreNextMouseSignal = TRUE; } @@ -659,18 +678,162 @@ SmallRectToRect(PGUI_CONSOLE_DATA GuiData, PRECT Rect, PSMALL_RECT SmallRect) Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ViewOrigin.Y) * HeightUnit; } +VOID +GetSelectionBeginEnd(PCOORD Begin, PCOORD End, + PCOORD SelectionAnchor, + PSMALL_RECT SmallRect) +{ + if (Begin == NULL || End == NULL) return; + + *Begin = *SelectionAnchor; + End->X = (SelectionAnchor->X == SmallRect->Left) ? SmallRect->Right + /* Case X != Left, must be == Right */ : SmallRect->Left; + End->Y = (SelectionAnchor->Y == SmallRect->Top ) ? SmallRect->Bottom + /* Case Y != Top, must be == Bottom */ : SmallRect->Top; + + /* Exchange Begin / End if Begin > End lexicographically */ + if (Begin->Y > End->Y || (Begin->Y == End->Y && Begin->X > End->X)) + { + End->X = _InterlockedExchange16(&Begin->X, End->X); + End->Y = _InterlockedExchange16(&Begin->Y, End->Y); + } +} + +static HRGN +CreateSelectionRgn(PGUI_CONSOLE_DATA GuiData, + BOOL LineSelection, + PCOORD SelectionAnchor, + PSMALL_RECT SmallRect) +{ + if (!LineSelection) + { + RECT rect; + SmallRectToRect(GuiData, &rect, SmallRect); + return CreateRectRgnIndirect(&rect); + } + else + { + HRGN SelRgn; + COORD Begin, End; + + GetSelectionBeginEnd(&Begin, &End, SelectionAnchor, SmallRect); + + if (Begin.Y == End.Y) + { + SMALL_RECT sr; + RECT r ; + + sr.Left = Begin.X; + sr.Top = Begin.Y; + sr.Right = End.X; + sr.Bottom = End.Y; + + // Debug thingie to see whether I can put this corner case + // together with the previous one. + if (SmallRect->Left != sr.Left || + SmallRect->Top != sr.Top || + SmallRect->Right != sr.Right || + SmallRect->Bottom != sr.Bottom) + { + DPRINT1("\n" + "SmallRect = (%d, %d, %d, %d)\n" + "sr = (%d, %d, %d, %d)\n" + "\n", + SmallRect->Left, SmallRect->Top, SmallRect->Right, SmallRect->Bottom, + sr.Left, sr.Top, sr.Right, sr.Bottom); + } + + SmallRectToRect(GuiData, &r, &sr); + SelRgn = CreateRectRgnIndirect(&r); + } + else + { + PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; + + HRGN rg1, rg2, rg3; + SMALL_RECT sr1, sr2, sr3; + RECT r1 , r2 , r3 ; + + sr1.Left = Begin.X; + sr1.Top = Begin.Y; + sr1.Right = ActiveBuffer->ScreenBufferSize.X - 1; + sr1.Bottom = Begin.Y; + + sr2.Left = 0; + sr2.Top = Begin.Y + 1; + sr2.Right = ActiveBuffer->ScreenBufferSize.X - 1; + sr2.Bottom = End.Y - 1; + + sr3.Left = 0; + sr3.Top = End.Y; + sr3.Right = End.X; + sr3.Bottom = End.Y; + + SmallRectToRect(GuiData, &r1, &sr1); + SmallRectToRect(GuiData, &r2, &sr2); + SmallRectToRect(GuiData, &r3, &sr3); + + rg1 = CreateRectRgnIndirect(&r1); + rg2 = CreateRectRgnIndirect(&r2); + rg3 = CreateRectRgnIndirect(&r3); + + CombineRgn(rg1, rg1, rg2, RGN_XOR); + CombineRgn(rg1, rg1, rg3, RGN_XOR); + DeleteObject(rg3); + DeleteObject(rg2); + + SelRgn = rg1; + } + + return SelRgn; + } +} + +static VOID +PaintSelectionRect(PGUI_CONSOLE_DATA GuiData, PPAINTSTRUCT pps) +{ + HRGN rgnPaint = CreateRectRgnIndirect(&pps->rcPaint); + HRGN rgnSel = CreateSelectionRgn(GuiData, GuiData->LineSelection, + &GuiData->Selection.dwSelectionAnchor, + &GuiData->Selection.srSelection); + + /* Invert the selection */ + + int ErrorCode = CombineRgn(rgnPaint, rgnPaint, rgnSel, RGN_AND); + if (ErrorCode != ERROR && ErrorCode != NULLREGION) + { + InvertRgn(pps->hdc, rgnPaint); + } + + DeleteObject(rgnSel); + DeleteObject(rgnPaint); +} + static VOID -UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord) +UpdateSelection(PGUI_CONSOLE_DATA GuiData, + PCOORD SelectionAnchor OPTIONAL, + PCOORD coord) { PCONSOLE Console = GuiData->Console; - RECT oldRect; + HRGN oldRgn = CreateSelectionRgn(GuiData, GuiData->LineSelection, + &GuiData->Selection.dwSelectionAnchor, + &GuiData->Selection.srSelection); - SmallRectToRect(GuiData, &oldRect, &GuiData->Selection.srSelection); + /* Update the anchor if needed (use the old one if NULL) */ + if (SelectionAnchor) + GuiData->Selection.dwSelectionAnchor = *SelectionAnchor; if (coord != NULL) { - RECT newRect; SMALL_RECT rc; + HRGN newRgn; + + /* + * Pressing the Control key while selecting text, allows us to enter + * into line-selection mode, the selection mode of *nix terminals. + */ + BOOL OldLineSel = GuiData->LineSelection; + GuiData->LineSelection = !!(GetKeyState(VK_CONTROL) & 0x8000); /* Exchange left/top with right/bottom if required */ rc.Left = min(GuiData->Selection.dwSelectionAnchor.X, coord->X); @@ -678,64 +841,72 @@ UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord) rc.Right = max(GuiData->Selection.dwSelectionAnchor.X, coord->X); rc.Bottom = max(GuiData->Selection.dwSelectionAnchor.Y, coord->Y); - SmallRectToRect(GuiData, &newRect, &rc); + newRgn = CreateSelectionRgn(GuiData, GuiData->LineSelection, + &GuiData->Selection.dwSelectionAnchor, + &rc); if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - if (memcmp(&rc, &GuiData->Selection.srSelection, sizeof(SMALL_RECT)) != 0) + if (OldLineSel != GuiData->LineSelection || + memcmp(&rc, &GuiData->Selection.srSelection, sizeof(SMALL_RECT)) != 0) { - HRGN rgn1, rgn2; - /* Calculate the region that needs to be updated */ - if ((rgn1 = CreateRectRgnIndirect(&oldRect))) + if (oldRgn && newRgn && CombineRgn(newRgn, newRgn, oldRgn, RGN_XOR) != ERROR) { - if ((rgn2 = CreateRectRgnIndirect(&newRect))) - { - if (CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) - { - InvalidateRgn(GuiData->hWindow, rgn1, FALSE); - } - DeleteObject(rgn2); - } - DeleteObject(rgn1); + InvalidateRgn(GuiData->hWindow, newRgn, FALSE); } } } else { - InvalidateRect(GuiData->hWindow, &newRect, FALSE); + InvalidateRgn(GuiData->hWindow, newRgn, FALSE); } + DeleteObject(newRgn); + GuiData->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; GuiData->Selection.srSelection = rc; GuiData->dwSelectionCursor = *coord; if ((GuiData->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0) { - LPWSTR SelectionType, WindowTitle = NULL; - SIZE_T Length = 0; + LPWSTR SelTypeStr = NULL , WindowTitle = NULL; + SIZE_T SelTypeStrLength = 0, Length = 0; /* Clear the old selection */ if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - InvalidateRect(GuiData->hWindow, &oldRect, FALSE); + InvalidateRgn(GuiData->hWindow, oldRgn, FALSE); } - if (GuiData->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) - { - SelectionType = L"Selection - "; - } - else + /* + * When passing a zero-length buffer size, LoadString(...) returns + * a read-only pointer buffer to the program's resource string. + */ + SelTypeStrLength = + LoadStringW(ConSrvDllInstance, + (GuiData->Selection.dwFlags & CONSOLE_MOUSE_SELECTION) + ? IDS_SELECT_TITLE : IDS_MARK_TITLE, + (LPWSTR)&SelTypeStr, 0); + + /* + * Prepend the selection type string to the current console title + * if we succeeded in retrieving a valid localized string. + */ + if (SelTypeStr) { - SelectionType = L"Mark - "; - } + // 3 for " - " and 1 for NULL + Length = Console->Title.Length + (SelTypeStrLength + 3 + 1) * sizeof(WCHAR); + WindowTitle = ConsoleAllocHeap(0, Length); + + wcsncpy(WindowTitle, SelTypeStr, SelTypeStrLength); + WindowTitle[SelTypeStrLength] = L'\0'; + wcscat(WindowTitle, L" - "); + wcscat(WindowTitle, Console->Title.Buffer); - Length = Console->Title.Length + wcslen(SelectionType) + 1; - WindowTitle = ConsoleAllocHeap(0, Length * sizeof(WCHAR)); - wcscpy(WindowTitle, SelectionType); - wcscat(WindowTitle, Console->Title.Buffer); - SetWindowText(GuiData->hWindow, WindowTitle); - ConsoleFreeHeap(WindowTitle); + SetWindowText(GuiData->hWindow, WindowTitle); + ConsoleFreeHeap(WindowTitle); + } GuiData->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS; ConioPause(Console, PAUSED_FROM_SELECTION); @@ -746,14 +917,17 @@ UpdateSelection(PGUI_CONSOLE_DATA GuiData, PCOORD coord) /* Clear the selection */ if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - InvalidateRect(GuiData->hWindow, &oldRect, FALSE); + InvalidateRgn(GuiData->hWindow, oldRgn, FALSE); } GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION; ConioUnpause(Console, PAUSED_FROM_SELECTION); + /* Restore the console title */ SetWindowText(GuiData->hWindow, Console->Title.Buffer); } + + DeleteObject(oldRgn); } @@ -807,15 +981,10 @@ OnPaint(PGUI_CONSOLE_DATA GuiData) rcPaint.top, SRCCOPY); + /* Draw the selection region if needed */ if (GuiData->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - SmallRectToRect(GuiData, &rcPaint, &GuiData->Selection.srSelection); - - /* Invert the selection */ - if (IntersectRect(&rcPaint, &ps.rcPaint, &rcPaint)) - { - InvertRect(ps.hdc, &rcPaint); - } + PaintSelectionRect(GuiData, &ps); } LeaveCriticalSection(&GuiData->Lock); @@ -892,10 +1061,10 @@ OnKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) goto Quit; } else if ( VirtualKeyCode == VK_ESCAPE || - (VirtualKeyCode == 'C' && GetKeyState(VK_CONTROL) & 0x8000) ) + (VirtualKeyCode == 'C' && (GetKeyState(VK_CONTROL) & 0x8000)) ) { /* Cancel selection if ESC or Ctrl-C are pressed */ - UpdateSelection(GuiData, NULL); + UpdateSelection(GuiData, NULL, NULL); goto Quit; } @@ -903,7 +1072,7 @@ OnKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) { /* Keyboard selection mode */ BOOL Interpreted = FALSE; - BOOL MajPressed = (GetKeyState(VK_SHIFT) & 0x8000); + BOOL MajPressed = !!(GetKeyState(VK_SHIFT) & 0x8000); switch (VirtualKeyCode) { @@ -984,10 +1153,9 @@ OnKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) if (Interpreted) { - if (!MajPressed) - GuiData->Selection.dwSelectionAnchor = GuiData->dwSelectionCursor; - - UpdateSelection(GuiData, &GuiData->dwSelectionCursor); + UpdateSelection(GuiData, + !MajPressed ? &GuiData->dwSelectionCursor : NULL, + &GuiData->dwSelectionCursor); } else if (!IsSystemKey(VirtualKeyCode)) { @@ -1004,7 +1172,7 @@ OnKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) if (!IsSystemKey(VirtualKeyCode)) { /* Clear the selection and send the key into the input buffer */ - UpdateSelection(GuiData, NULL); + UpdateSelection(GuiData, NULL, NULL); } else { @@ -1216,15 +1384,18 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) BOOL Err = FALSE; PCONSOLE Console = GuiData->Console; + // FIXME: It's here that we need to check whether we has focus or not + // and whether we are in edit mode or not, to know if we need to deal + // with the mouse, or not. + if (GuiData->IgnoreNextMouseSignal) { if (msg != WM_LBUTTONDOWN && msg != WM_MBUTTONDOWN && - msg != WM_RBUTTONDOWN && - msg != WM_MOUSEMOVE) + msg != WM_RBUTTONDOWN) { /* - * If this mouse signal is not a button-down action or a move, + * If this mouse signal is not a button-down action * then it is the last signal being ignored. */ GuiData->IgnoreNextMouseSignal = FALSE; @@ -1232,7 +1403,7 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) else { /* - * This mouse signal is a button-down action or a move. + * This mouse signal is a button-down action. * Ignore it and perform default action. */ Err = TRUE; @@ -1254,27 +1425,26 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) case WM_LBUTTONDOWN: { /* Clear the old selection */ - // UpdateSelection(GuiData, NULL); GuiData->Selection.dwFlags = CONSOLE_NO_SELECTION; /* Restart a new selection */ - GuiData->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam); + GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam); SetCapture(GuiData->hWindow); GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - UpdateSelection(GuiData, &GuiData->Selection.dwSelectionAnchor); + UpdateSelection(GuiData, + &GuiData->dwSelectionCursor, + &GuiData->dwSelectionCursor); break; } case WM_LBUTTONUP: { - // COORD c; - if (!(GuiData->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break; - // c = PointToCoord(GuiData, lParam); + // GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam); GuiData->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; - // UpdateSelection(GuiData, &c); + // UpdateSelection(GuiData, NULL, &GuiData->dwSelectionCursor); ReleaseCapture(); break; @@ -1286,10 +1456,7 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) if (GetType(Buffer) == TEXTMODE_BUFFER) { -#ifdef IS_WHITESPACE -#undef IS_WHITESPACE -#endif -#define IS_WHITESPACE(c) \ +#define IS_WORD_SEP(c) \ ((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n') PTEXTMODE_SCREEN_BUFFER TextBuffer = (PTEXTMODE_SCREEN_BUFFER)Buffer; @@ -1301,15 +1468,15 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) ptrL = ptrR = ConioCoordToPointer(TextBuffer, cL.X, cL.Y); /* Enlarge the selection by checking for whitespace */ - while ((0 < cL.X) && !IS_WHITESPACE(ptrL->Char.UnicodeChar) - && !IS_WHITESPACE((ptrL-1)->Char.UnicodeChar)) + while ((0 < cL.X) && !IS_WORD_SEP(ptrL->Char.UnicodeChar) + && !IS_WORD_SEP((ptrL-1)->Char.UnicodeChar)) { --cL.X; --ptrL; } while ((cR.X < TextBuffer->ScreenBufferSize.X - 1) && - !IS_WHITESPACE(ptrR->Char.UnicodeChar) && - !IS_WHITESPACE((ptrR+1)->Char.UnicodeChar)) + !IS_WORD_SEP(ptrR->Char.UnicodeChar) && + !IS_WORD_SEP((ptrR+1)->Char.UnicodeChar)) { ++cR.X; ++ptrR; @@ -1319,11 +1486,8 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) * Update the selection started with the single * left-click that preceded this double-click. */ - GuiData->Selection.dwSelectionAnchor = cL; - GuiData->dwSelectionCursor = cR; - GuiData->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; - UpdateSelection(GuiData, &GuiData->dwSelectionCursor); + UpdateSelection(GuiData, &cL, &cR); /* Ignore the next mouse move signal */ GuiData->IgnoreNextMouseSignal = TRUE; @@ -1351,13 +1515,12 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) case WM_MOUSEMOVE: { - COORD c; - if (!(wParam & MK_LBUTTON)) break; if (!(GuiData->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break; - c = PointToCoord(GuiData, lParam); /* TODO: Scroll buffer to bring c into view */ - UpdateSelection(GuiData, &c); + // TODO: Scroll buffer to bring SelectionCursor into view + GuiData->dwSelectionCursor = PointToCoord(GuiData, lParam); + UpdateSelection(GuiData, NULL, &GuiData->dwSelectionCursor); break; } @@ -1448,6 +1611,20 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) break; } + /* + * HACK FOR CORE-8394: Ignore the next mouse move signal + * just after mouse down click actions. + */ + switch (msg) + { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + GuiData->IgnoreNextMouseSignal = TRUE; + default: + break; + } + if (!Err) { if (wKeyState & MK_LBUTTON) @@ -1527,7 +1704,7 @@ Copy(PGUI_CONSOLE_DATA GuiData) } /* Clear the selection */ - UpdateSelection(GuiData, NULL); + UpdateSelection(GuiData, NULL, NULL); } VOID @@ -1905,6 +2082,11 @@ ConWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) break; } + /* Detect Alt-Esc/Space/Tab presses defer to DefWindowProc */ + if ( (HIWORD(lParam) & KF_ALTDOWN) && (wParam == VK_ESCAPE || wParam == VK_SPACE || wParam == VK_TAB)) + { + return DefWindowProcW(hWnd, msg, wParam, lParam); + } OnKey(GuiData, msg, wParam, lParam); break;