- Fix console selection and selection mode text that displays in the console title:
- Correctly set selection flags;
- Ignore the first mouse event when the console is being activated with the mouse, when we are in "QuickEdit" mode (avoids e.g. an erroneous paste if somebody right-clicks on the console); gather the console window position to consistently update GuiData->GuiInfo.WindowOrigin (needed when console properties are displayed).

svn path=/trunk/; revision=62739
This commit is contained in:
Hermès Bélusca-Maïto 2014-04-13 13:21:55 +00:00
parent 4496c7309a
commit 858c7e6474

View file

@ -24,7 +24,7 @@
#include "resource.h" #include "resource.h"
/* GUI Console Window Class name */ /* GUI Console Window Class name */
#define GUI_CONSOLE_WINDOW_CLASS L"ConsoleWindowClass" #define GUI_CONWND_CLASS L"ConsoleWindowClass"
#ifndef WM_APP #ifndef WM_APP
#define WM_APP 0x8000 #define WM_APP 0x8000
@ -277,22 +277,16 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
{ {
case ID_SYSTEM_EDIT_MARK: case ID_SYSTEM_EDIT_MARK:
{ {
LPWSTR WindowTitle = NULL; /* Clear the old selection */
SIZE_T Length = 0; // GuiConsoleUpdateSelection(Console, NULL);
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
/* Restart a new selection */
Console->dwSelectionCursor.X = ActiveBuffer->ViewOrigin.X; Console->dwSelectionCursor.X = ActiveBuffer->ViewOrigin.X;
Console->dwSelectionCursor.Y = ActiveBuffer->ViewOrigin.Y; Console->dwSelectionCursor.Y = ActiveBuffer->ViewOrigin.Y;
Console->Selection.dwSelectionAnchor = Console->dwSelectionCursor; Console->Selection.dwSelectionAnchor = Console->dwSelectionCursor;
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS;
GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
Length = Console->Title.Length + sizeof(L"Mark - ")/sizeof(WCHAR) + 1;
WindowTitle = ConsoleAllocHeap(0, Length * sizeof(WCHAR));
wcscpy(WindowTitle, L"Mark - ");
wcscat(WindowTitle, Console->Title.Buffer);
SetWindowText(GuiData->hWindow, WindowTitle);
ConsoleFreeHeap(WindowTitle);
break; break;
} }
@ -306,8 +300,9 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
case ID_SYSTEM_EDIT_SELECTALL: case ID_SYSTEM_EDIT_SELECTALL:
{ {
LPWSTR WindowTitle = NULL; /* Clear the old selection */
SIZE_T Length = 0; // GuiConsoleUpdateSelection(Console, NULL);
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
/* /*
* The selection area extends to the whole screen buffer's width. * The selection area extends to the whole screen buffer's width.
@ -337,16 +332,10 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM
Console->dwSelectionCursor.Y = ActiveBuffer->ScreenBufferSize.Y - 1; Console->dwSelectionCursor.Y = ActiveBuffer->ScreenBufferSize.Y - 1;
} }
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION; /* Restart a new selection */
Console->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION;
GuiConsoleUpdateSelection(Console, &Console->dwSelectionCursor); GuiConsoleUpdateSelection(Console, &Console->dwSelectionCursor);
Length = Console->Title.Length + sizeof(L"Selection - ")/sizeof(WCHAR) + 1;
WindowTitle = ConsoleAllocHeap(0, Length * sizeof(WCHAR));
wcscpy(WindowTitle, L"Selection - ");
wcscat(WindowTitle, Console->Title.Buffer);
SetWindowText(GuiData->hWindow, WindowTitle);
ConsoleFreeHeap(WindowTitle);
break; break;
} }
@ -579,14 +568,16 @@ static VOID
GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord) GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord)
{ {
PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data;
RECT oldRect, newRect; RECT oldRect;
SmallRectToRect(GuiData, &oldRect, &Console->Selection.srSelection); SmallRectToRect(GuiData, &oldRect, &Console->Selection.srSelection);
if (coord != NULL) if (coord != NULL)
{ {
RECT newRect;
SMALL_RECT rc; SMALL_RECT rc;
/* exchange left/top with right/bottom if required */
/* Exchange left/top with right/bottom if required */
rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X);
rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y);
rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X);
@ -600,7 +591,7 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord)
{ {
HRGN rgn1, rgn2; HRGN rgn1, rgn2;
/* calculate the region that needs to be updated */ /* Calculate the region that needs to be updated */
if ((rgn1 = CreateRectRgnIndirect(&oldRect))) if ((rgn1 = CreateRectRgnIndirect(&oldRect)))
{ {
if ((rgn2 = CreateRectRgnIndirect(&newRect))) if ((rgn2 = CreateRectRgnIndirect(&newRect)))
@ -619,20 +610,54 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord)
{ {
InvalidateRect(GuiData->hWindow, &newRect, FALSE); InvalidateRect(GuiData->hWindow, &newRect, FALSE);
} }
Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
Console->Selection.srSelection = rc; Console->Selection.srSelection = rc;
Console->dwSelectionCursor = *coord; Console->dwSelectionCursor = *coord;
ConioPause(Console, PAUSED_FROM_SELECTION);
if ((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) == 0)
{
LPWSTR SelectionType, WindowTitle = NULL;
SIZE_T Length = 0;
/* Clear the old selection */
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{
InvalidateRect(GuiData->hWindow, &oldRect, FALSE);
}
if (Console->Selection.dwFlags & CONSOLE_MOUSE_SELECTION)
{
SelectionType = L"Selection - ";
}
else
{
SelectionType = L"Mark - ";
}
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);
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS;
ConioPause(Console, PAUSED_FROM_SELECTION);
}
} }
else else
{ {
/* clear the selection */ /* Clear the selection */
if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
{ {
InvalidateRect(GuiData->hWindow, &oldRect, FALSE); InvalidateRect(GuiData->hWindow, &oldRect, FALSE);
} }
Console->Selection.dwFlags = CONSOLE_NO_SELECTION; Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
ConioUnpause(Console, PAUSED_FROM_SELECTION); ConioUnpause(Console, PAUSED_FROM_SELECTION);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
} }
} }
@ -768,8 +793,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
{ {
/* Cancel selection if ESC or Ctrl-C are pressed */ /* Cancel selection if ESC or Ctrl-C are pressed */
GuiConsoleUpdateSelection(Console, NULL); GuiConsoleUpdateSelection(Console, NULL);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
goto Quit; goto Quit;
} }
@ -879,7 +902,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l
{ {
/* Clear the selection and send the key into the input buffer */ /* Clear the selection and send the key into the input buffer */
GuiConsoleUpdateSelection(Console, NULL); GuiConsoleUpdateSelection(Console, NULL);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
} }
else else
{ {
@ -1096,10 +1118,11 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
{ {
if (msg != WM_LBUTTONDOWN && if (msg != WM_LBUTTONDOWN &&
msg != WM_MBUTTONDOWN && msg != WM_MBUTTONDOWN &&
msg != WM_RBUTTONDOWN) msg != WM_RBUTTONDOWN &&
msg != WM_MOUSEMOVE)
{ {
/* /*
* If this mouse signal is not a button-down action, * If this mouse signal is not a button-down action or a move,
* then it is the last signal being ignored. * then it is the last signal being ignored.
*/ */
GuiData->IgnoreNextMouseSignal = FALSE; GuiData->IgnoreNextMouseSignal = FALSE;
@ -1107,7 +1130,7 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
else else
{ {
/* /*
* This mouse signal is a button-down action. * This mouse signal is a button-down action or a move.
* Ignore it and perform default action. * Ignore it and perform default action.
*/ */
Err = TRUE; Err = TRUE;
@ -1128,33 +1151,28 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
{ {
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
{ {
LPWSTR WindowTitle = NULL; /* Clear the old selection */
SIZE_T Length = 0; // GuiConsoleUpdateSelection(Console, NULL);
Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
/* Restart a new selection */
Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam); Console->Selection.dwSelectionAnchor = PointToCoord(GuiData, lParam);
SetCapture(GuiData->hWindow); SetCapture(GuiData->hWindow);
Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; Console->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
Length = Console->Title.Length + sizeof(L"Selection - ")/sizeof(WCHAR) + 1;
WindowTitle = ConsoleAllocHeap(0, Length * sizeof(WCHAR));
wcscpy(WindowTitle, L"Selection - ");
wcscat(WindowTitle, Console->Title.Buffer);
SetWindowText(GuiData->hWindow, WindowTitle);
ConsoleFreeHeap(WindowTitle);
break; break;
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
{ {
COORD c; // COORD c;
if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break; if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) break;
c = PointToCoord(GuiData, lParam); // c = PointToCoord(GuiData, lParam);
Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
GuiConsoleUpdateSelection(Console, &c); // GuiConsoleUpdateSelection(Console, &c);
ReleaseCapture(); ReleaseCapture();
break; break;
@ -1166,6 +1184,9 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
if (GetType(Buffer) == TEXTMODE_BUFFER) if (GetType(Buffer) == TEXTMODE_BUFFER)
{ {
#ifdef IS_WHITESPACE
#undef IS_WHITESPACE
#endif
#define IS_WHITESPACE(c) \ #define IS_WHITESPACE(c) \
((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n') ((c) == L'\0' || (c) == L' ' || (c) == L'\t' || (c) == L'\r' || (c) == L'\n')
@ -1192,10 +1213,19 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
++ptrR; ++ptrR;
} }
/*
* Update the selection started with the single
* left-click that preceded this double-click.
*/
Console->Selection.dwSelectionAnchor = cL; Console->Selection.dwSelectionAnchor = cL;
Console->dwSelectionCursor = cR; Console->dwSelectionCursor = cR;
SetCapture(GuiData->hWindow);
Console->Selection.dwFlags |= CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
GuiConsoleUpdateSelection(Console, &Console->dwSelectionCursor); GuiConsoleUpdateSelection(Console, &Console->dwSelectionCursor);
/* Ignore the next mouse move signal */
GuiData->IgnoreNextMouseSignal = TRUE;
} }
break; break;
@ -1213,6 +1243,7 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM
GuiConsoleCopy(GuiData); GuiConsoleCopy(GuiData);
} }
/* Ignore the next mouse move signal */
GuiData->IgnoreNextMouseSignal = TRUE; GuiData->IgnoreNextMouseSignal = TRUE;
break; break;
} }
@ -1378,9 +1409,10 @@ GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
static VOID static VOID
GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData) GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
{ {
PCONSOLE Console = GuiData->Console;
if (OpenClipboard(GuiData->hWindow) == TRUE) if (OpenClipboard(GuiData->hWindow) == TRUE)
{ {
PCONSOLE Console = GuiData->Console;
PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer;
if (GetType(Buffer) == TEXTMODE_BUFFER) if (GetType(Buffer) == TEXTMODE_BUFFER)
@ -1393,11 +1425,10 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
} }
CloseClipboard(); CloseClipboard();
/* Clear the selection */
GuiConsoleUpdateSelection(Console, NULL);
SetWindowText(GuiData->hWindow, Console->Title.Buffer);
} }
/* Clear the selection */
GuiConsoleUpdateSelection(Console, NULL);
} }
VOID VOID
@ -1739,7 +1770,14 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
} }
if (ActivationState == WA_CLICKACTIVE) GuiData->IgnoreNextMouseSignal = TRUE; /*
* 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...
*/
if (Console->QuickEdit && (ActivationState == WA_CLICKACTIVE))
GuiData->IgnoreNextMouseSignal = TRUE;
break; break;
} }
@ -1752,6 +1790,10 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
GuiConsoleHandlePaint(GuiData); GuiConsoleHandlePaint(GuiData);
break; break;
case WM_TIMER:
GuiConsoleHandleTimer(GuiData);
break;
case WM_PALETTECHANGED: case WM_PALETTECHANGED:
{ {
PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
@ -1815,10 +1857,6 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
break; break;
} }
case WM_TIMER:
GuiConsoleHandleTimer(GuiData);
break;
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
/* /*
@ -2013,6 +2051,25 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam); GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam);
break; break;
case WM_MOVE:
{
if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
// TODO: Simplify the code.
// See: GuiConsoleNotifyWndProc() PM_CREATE_CONSOLE.
RECT rcWnd;
/* Retrieve our real position */
GetWindowRect(GuiData->hWindow, &rcWnd);
GuiData->GuiInfo.WindowOrigin.x = rcWnd.left;
GuiData->GuiInfo.WindowOrigin.y = rcWnd.top;
LeaveCriticalSection(&Console->Lock);
}
break;
}
case WM_SIZE: case WM_SIZE:
GuiConsoleResize(GuiData, wParam, lParam); GuiConsoleResize(GuiData, wParam, lParam);
break; break;
@ -2101,9 +2158,10 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam; PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
PCONSOLE Console = GuiData->Console; PCONSOLE Console = GuiData->Console;
RECT rcWnd;
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
GUI_CONSOLE_WINDOW_CLASS, GUI_CONWND_CLASS,
Console->Title.Buffer, Console->Title.Buffer,
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -2136,6 +2194,11 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
SendMessageW(GuiData->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)GuiData->hIconSm); SendMessageW(GuiData->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)GuiData->hIconSm);
} }
/* Retrieve our real position */
GetWindowRect(GuiData->hWindow, &rcWnd);
GuiData->GuiInfo.WindowOrigin.x = rcWnd.left;
GuiData->GuiInfo.WindowOrigin.y = rcWnd.top;
/* Move and resize the window to the user's values */ /* Move and resize the window to the user's values */
/* CAN WE DEADLOCK ?? */ /* CAN WE DEADLOCK ?? */
GuiConsoleMoveWindow(GuiData); GuiConsoleMoveWindow(GuiData);
@ -2289,7 +2352,7 @@ GuiInit(VOID)
LR_SHARED); LR_SHARED);
ghDefaultCursor = LoadCursorW(NULL, IDC_ARROW); ghDefaultCursor = LoadCursorW(NULL, IDC_ARROW);
wc.cbSize = sizeof(WNDCLASSEXW); wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = GUI_CONSOLE_WINDOW_CLASS; wc.lpszClassName = GUI_CONWND_CLASS;
wc.lpfnWndProc = GuiConsoleWndProc; wc.lpfnWndProc = GuiConsoleWndProc;
wc.style = CS_DBLCLKS /* | CS_HREDRAW | CS_VREDRAW */; wc.style = CS_DBLCLKS /* | CS_HREDRAW | CS_VREDRAW */;
wc.hInstance = ConSrvDllInstance; wc.hInstance = ConSrvDllInstance;