Skip to content

Commit c36190e

Browse files
committed
Merge #102, deferred initialization
2 parents 7b24b7e + da2a4ba commit c36190e

3 files changed

Lines changed: 238 additions & 174 deletions

File tree

src/main.cpp

Lines changed: 78 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
#include "renderer/renderer.h"
33

44
struct Context {
5-
int start_x, start_y;
6-
GridSize start_grid_size;
75
bool start_maximized;
86
bool start_fullscreen;
97
bool disable_fullscreen;
@@ -46,19 +44,13 @@ void ToggleFullscreen(HWND hwnd, Context *context) {
4644
void ProcessMPackMessage(Context *context, mpack_tree_t *tree) {
4745
MPackMessageResult result = MPackExtractMessageResult(tree);
4846

49-
if (result.type == MPackMessageType::Response) {
47+
switch (result.type) {
48+
case MPackMessageType::Response: {
5049
assert(result.response.msg_id <= context->nvim->next_msg_id);
5150
switch (context->nvim->msg_id_to_method[result.response.msg_id]) {
52-
case NvimRequest::vim_get_api_info: {
53-
mpack_node_t top_level_map = mpack_node_array_at(result.params, 1);
54-
mpack_node_t version_map = mpack_node_map_value_at(top_level_map, 0);
55-
int64_t api_level = mpack_node_map_cstr(version_map, "api_level").data->value.i;
56-
assert(api_level > 6);
57-
} break;
5851
case NvimRequest::nvim_eval: {
5952
Vec<char> guifont_buffer;
6053
NvimParseConfig(context->nvim, result.params, &guifont_buffer);
61-
6254
if (!guifont_buffer.empty()) {
6355
bool updated = RendererUpdateGuiFont(context->renderer, guifont_buffer.data(), strlen(guifont_buffer.data()));
6456
if(!updated) {
@@ -72,45 +64,27 @@ void ProcessMPackMessage(Context *context, mpack_tree_t *tree) {
7264
free(command);
7365
}
7466
}
75-
76-
if (context->start_grid_size.rows != 0 &&
77-
context->start_grid_size.cols != 0) {
78-
PixelSize start_size = RendererGridToPixelSize(context->renderer,
79-
context->start_grid_size.rows, context->start_grid_size.cols);
80-
RECT client_rect;
81-
GetClientRect(context->hwnd, &client_rect);
82-
MoveWindow(context->hwnd, client_rect.left, client_rect.top,
83-
start_size.width, start_size.height, false);
84-
}
85-
86-
// Attach the renderer now that the window size is determined
87-
RendererAttach(context->renderer);
88-
auto [rows, cols] = RendererPixelsToGridSize(context->renderer,
89-
context->renderer->pixel_size.width, context->renderer->pixel_size.height);
90-
NvimSendUIAttach(context->nvim, rows, cols);
91-
92-
if (context->start_x != CW_USEDEFAULT ||
93-
context->start_y != CW_USEDEFAULT) {
94-
SetWindowPos(context->hwnd, NULL,
95-
context->start_x, context->start_y,
96-
0, 0,
97-
SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE |
98-
SWP_NOOWNERZORDER | SWP_NOZORDER);
99-
}
100-
if (context->start_fullscreen) {
101-
ToggleFullscreen(context->hwnd, context);
102-
}
103-
} break;
104-
case NvimRequest::nvim_input:
105-
case NvimRequest::nvim_input_mouse:
106-
case NvimRequest::nvim_command: {
10767
} break;
68+
case NvimRequest::vim_get_api_info:
69+
case NvimRequest::nvim_input:
70+
case NvimRequest::nvim_input_mouse:
71+
case NvimRequest::nvim_command: {
72+
} break;
10873
}
109-
}
110-
else if (result.type == MPackMessageType::Notification) {
74+
} break;
75+
case MPackMessageType::Notification: {
11176
if (MPackMatchString(result.notification.name, "redraw")) {
11277
RendererRedraw(context->renderer, result.params, context->start_maximized);
11378
}
79+
} break;
80+
case MPackMessageType::Request: {
81+
if (MPackMatchString(result.request.method, "vimenter")) {
82+
// nvim has read user init file, we can now request info if we want
83+
// like additional startup settings or something else
84+
NvimSendResponse(context->nvim, result.request.msg_id);
85+
NvimQueryConfig(context->nvim);
86+
}
87+
} break;
11488
}
11589
}
11690

@@ -400,7 +374,7 @@ BOOL ShouldUseDarkMode()
400374
return false;
401375
}
402376

403-
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_line, int n_cmd_show) {
377+
int WINAPI wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR p_cmd_line, _In_ int n_cmd_show) {
404378
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
405379

406380
int n_args;
@@ -410,16 +384,16 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
410384
bool disable_ligatures = false;
411385
bool disable_fullscreen = false;
412386
float linespace_factor = 1.0f;
413-
int64_t rows = 0;
414-
int64_t cols = 0;
415-
int64_t x = CW_USEDEFAULT;
416-
int64_t y = CW_USEDEFAULT;
417-
418-
constexpr int MAX_NVIM_CMD_LINE_SIZE = 32767;
419-
wchar_t nvim_command_line[MAX_NVIM_CMD_LINE_SIZE] = {};
420-
wcscpy_s(nvim_command_line, MAX_NVIM_CMD_LINE_SIZE, L"nvim --embed");
421-
int cmd_line_size_left = MAX_NVIM_CMD_LINE_SIZE - wcslen(L"nvim --embed");
422-
387+
int64_t start_rows = 0;
388+
int64_t start_cols = 0;
389+
int64_t start_pos_x = CW_USEDEFAULT;
390+
int64_t start_pos_y = CW_USEDEFAULT;
391+
392+
struct WArg {
393+
wchar_t *arg;
394+
size_t len;
395+
};
396+
Vec<WArg> nvim_args;
423397

424398
// Skip argv[0]
425399
for(int i = 1; i < n_args; ++i) {
@@ -437,13 +411,13 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
437411
}
438412
else if(!wcsncmp(cmd_line_args[i], L"--geometry=", wcslen(L"--geometry="))) {
439413
wchar_t *end_ptr;
440-
cols = wcstol(&cmd_line_args[i][11], &end_ptr, 10);
441-
rows = wcstol(end_ptr + 1, nullptr, 10);
414+
start_cols = wcstol(&cmd_line_args[i][11], &end_ptr, 10);
415+
start_rows = wcstol(end_ptr + 1, nullptr, 10);
442416
}
443417
else if(!wcsncmp(cmd_line_args[i], L"--position=", wcslen(L"--position="))) {
444418
wchar_t *end_ptr;
445-
x = wcstol(&cmd_line_args[i][11], &end_ptr, 10);
446-
y = wcstol(end_ptr + 1, nullptr, 10);
419+
start_pos_x = wcstol(&cmd_line_args[i][11], &end_ptr, 10);
420+
start_pos_y = wcstol(end_ptr + 1, nullptr, 10);
447421
}
448422
else if(!wcsncmp(cmd_line_args[i], L"--linespace-factor=", wcslen(L"--linespace-factor="))) {
449423
wchar_t *end_ptr;
@@ -454,15 +428,10 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
454428
}
455429
// Otherwise assume the argument is a filename to open
456430
else {
457-
size_t arg_size = wcslen(cmd_line_args[i]);
458-
if(arg_size <= (cmd_line_size_left + 3)) {
459-
wcscat_s(nvim_command_line, cmd_line_size_left, L" \"");
460-
cmd_line_size_left -= 2;
461-
wcscat_s(nvim_command_line, cmd_line_size_left, cmd_line_args[i]);
462-
cmd_line_size_left -= arg_size;
463-
wcscat_s(nvim_command_line, cmd_line_size_left, L"\"");
464-
cmd_line_size_left -= 1;
465-
}
431+
nvim_args.push_back(WArg{
432+
.arg = cmd_line_args[i],
433+
.len = wcslen(cmd_line_args[i])
434+
});
466435
}
467436
}
468437

@@ -473,10 +442,10 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
473442
.style = CS_HREDRAW | CS_VREDRAW,
474443
.lpfnWndProc = WndProc,
475444
.hInstance = instance,
476-
.hIcon = static_cast<HICON>(LoadImage(GetModuleHandle(NULL), L"NVIM_ICON", IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, 0)),
445+
.hIcon = static_cast<HICON>(LoadImage(GetModuleHandle(NULL), L"NVIM_ICON", IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, 0)),
477446
.hCursor = LoadCursor(NULL, IDC_ARROW),
478447
.lpszClassName = window_class_name,
479-
.hIconSm = static_cast<HICON>(LoadImage(GetModuleHandle(NULL), L"NVIM_ICON", IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, 0))
448+
.hIconSm = static_cast<HICON>(LoadImage(GetModuleHandle(NULL), L"NVIM_ICON", IMAGE_ICON, LR_DEFAULTSIZE, LR_DEFAULTSIZE, 0))
480449
};
481450

482451
if (!RegisterClassEx(&window_class)) {
@@ -486,12 +455,6 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
486455
Nvim nvim {};
487456
Renderer renderer {};
488457
Context context {
489-
.start_x = static_cast<int>(x),
490-
.start_y = static_cast<int>(y),
491-
.start_grid_size {
492-
.rows = static_cast<int>(rows),
493-
.cols = static_cast<int>(cols)
494-
},
495458
.start_maximized = start_maximized,
496459
.start_fullscreen = start_fullscreen,
497460
.disable_fullscreen = disable_fullscreen,
@@ -525,10 +488,47 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
525488
BOOL should_use_dark_mode = ShouldUseDarkMode();
526489
DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &should_use_dark_mode, sizeof(BOOL));
527490
RendererInitialize(&renderer, hwnd, disable_ligatures, linespace_factor, context.saved_dpi_scaling);
491+
492+
// Prepare nvim command line
493+
size_t nvim_command_len = wcslen(L"nvim --embed");
494+
for (const auto& nvim_command_arg : nvim_args) {
495+
nvim_command_len += wcslen(L" \"\"") + nvim_command_arg.len;
496+
}
497+
wchar_t *nvim_command_line = static_cast<wchar_t *>(malloc(sizeof(wchar_t) * (nvim_command_len + 1)));
498+
int cur_len = _snwprintf_s(nvim_command_line, nvim_command_len + 1, nvim_command_len, L"nvim --embed");
499+
for (const auto& [arg, len] : nvim_args) {
500+
cur_len += _snwprintf_s(nvim_command_line + cur_len, nvim_command_len + 1 - cur_len, nvim_command_len - cur_len,
501+
L" \"%s\"", arg, static_cast<uint32_t>(len));
502+
}
503+
528504
NvimInitialize(&nvim, nvim_command_line, hwnd);
505+
529506
// Forceably update the window to prevent any frames where the window is blank. Windows API docs
530507
// specify that SetWindowPos should be called with these arguments after SetWindowLong is called.
531-
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
508+
UINT window_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED;
509+
int window_w = 0, window_h = 0;
510+
511+
if (start_rows != 0 && start_cols != 0) {
512+
PixelSize start_size = RendererGridToPixelSize(context.renderer,
513+
start_rows, start_cols);
514+
window_w = start_size.width;
515+
window_h = start_size.height;
516+
window_flags = window_flags & ~SWP_NOSIZE;
517+
}
518+
if (start_pos_x != CW_USEDEFAULT || start_pos_y != CW_USEDEFAULT) {
519+
window_flags = window_flags & ~SWP_NOMOVE;
520+
}
521+
SetWindowPos(hwnd, HWND_TOP, start_pos_x, start_pos_y, window_w, window_h, window_flags);
522+
523+
if (start_fullscreen) {
524+
ToggleFullscreen(context.hwnd, &context);
525+
}
526+
527+
// Attach the renderer now that the window size is determined
528+
RendererAttach(context.renderer);
529+
auto [rows, cols] = RendererPixelsToGridSize(context.renderer,
530+
context.renderer->pixel_size.width, context.renderer->pixel_size.height);
531+
NvimSendUIAttach(context.nvim, rows, cols);
532532

533533
MSG msg;
534534
uint32_t previous_width = 0, previous_height = 0;
@@ -551,6 +551,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, PWSTR p_cmd_lin
551551
NvimShutdown(&nvim);
552552
UnregisterClass(window_class_name, instance);
553553
DestroyWindow(hwnd);
554+
free(nvim_command_line);
554555

555556
return nvim.exit_code;
556557
}

0 commit comments

Comments
 (0)