aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ui.c')
-rw-r--r--src/nvim/ui.c111
1 files changed, 61 insertions, 50 deletions
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 96232ab223..16370f2d10 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -33,6 +33,7 @@
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
#include "nvim/highlight.h"
+#include "nvim/ui_compositor.h"
#include "nvim/window.h"
#include "nvim/cursor_shape.h"
#ifdef FEAT_TUI
@@ -60,11 +61,11 @@ static bool pending_mode_update = false;
static handle_T cursor_grid_handle = DEFAULT_GRID_HANDLE;
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
-# define UI_LOG(funname, ...)
+# define UI_LOG(funname)
#else
static size_t uilog_seen = 0;
static char uilog_last_event[1024] = { 0 };
-# define UI_LOG(funname, ...) \
+# define UI_LOG(funname) \
do { \
if (strequal(uilog_last_event, STR(funname))) { \
uilog_seen++; \
@@ -80,42 +81,34 @@ static char uilog_last_event[1024] = { 0 };
} while (0)
#endif
-// UI_CALL invokes a function on all registered UI instances. The functions can
-// have 0-10 arguments (configurable by SELECT_NTH).
-//
-// See http://stackoverflow.com/a/11172679 for how it works.
-#ifdef _MSC_VER
-# define UI_CALL(funname, ...) \
- do { \
- UI_LOG(funname, 0); \
- for (size_t i = 0; i < ui_count; i++) { \
- UI *ui = uis[i]; \
- UI_CALL_MORE(funname, __VA_ARGS__); \
- } \
- } while (0)
-#else
-# define UI_CALL(...) \
- do { \
- UI_LOG(__VA_ARGS__, 0); \
- for (size_t i = 0; i < ui_count; i++) { \
- UI *ui = uis[i]; \
- UI_CALL_HELPER(CNT(__VA_ARGS__), __VA_ARGS__); \
+// UI_CALL invokes a function on all registered UI instances.
+// This is called by code generated by generators/gen_api_ui_events.lua
+// C code should use ui_call_{funname} instead.
+# define UI_CALL(cond, funname, ...) \
+ do { \
+ bool any_call = false; \
+ for (size_t i = 0; i < ui_count; i++) { \
+ UI *ui = uis[i]; \
+ if (ui->funname && (cond)) { \
+ ui->funname(__VA_ARGS__); \
+ any_call = true; \
} \
- } while (0)
-#endif
-#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, MORE, \
- MORE, MORE, MORE, MORE, ZERO, ignore)
-#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11
-#define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__)
-// Resolves to UI_CALL_MORE or UI_CALL_ZERO.
-#define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__)
-#define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__)
-#define UI_CALL_ZERO(method) if (ui->method) ui->method(ui)
+ } \
+ if (any_call) { \
+ UI_LOG(funname); \
+ } \
+ } while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_events_call.generated.h"
#endif
+void ui_init(void)
+{
+ default_grid.handle = 1;
+ ui_comp_init();
+}
+
void ui_builtin_start(void)
{
#ifdef FEAT_TUI
@@ -135,17 +128,12 @@ void ui_builtin_start(void)
#endif
}
-void ui_builtin_stop(void)
-{
- UI_CALL(stop);
-}
-
bool ui_rgb_attached(void)
{
if (!headless_mode && p_tgc) {
return true;
}
- for (size_t i = 0; i < ui_count; i++) {
+ for (size_t i = 1; i < ui_count; i++) {
if (uis[i]->rgb) {
return true;
}
@@ -155,13 +143,13 @@ bool ui_rgb_attached(void)
bool ui_active(void)
{
- return ui_count != 0;
+ return ui_count > 1;
}
void ui_event(char *name, Array args)
{
bool args_consumed = false;
- UI_CALL(event, name, args, &args_consumed);
+ ui_call_event(name, args, &args_consumed);
if (!args_consumed) {
api_free_array(args);
}
@@ -212,6 +200,10 @@ void ui_refresh(void)
screen_resize(width, height);
p_lz = save_p_lz;
+ if (ext_widgets[kUIMessages]) {
+ p_ch = 0;
+ command_height();
+ }
ui_mode_info_set();
pending_mode_update = true;
ui_cursor_shape();
@@ -257,6 +249,9 @@ void ui_attach_impl(UI *ui)
if (ui_count == MAX_UI_COUNT) {
abort();
}
+ if (!ui->ui_ext[kUIMultigrid]) {
+ ui_comp_attach(ui);
+ }
uis[ui_count++] = ui;
ui_refresh_options();
@@ -303,6 +298,10 @@ void ui_detach_impl(UI *ui)
&& !exiting) {
ui_schedule_refresh();
}
+
+ if (!ui->ui_ext[kUIMultigrid]) {
+ ui_comp_detach(ui);
+ }
}
void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
@@ -315,16 +314,25 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
ui->option_set(ui, cstr_as_string((char *)ui_ext_names[ext]),
BOOLEAN_OBJ(active));
}
+ if (ext == kUITermColors) {
+ ui_default_colors_set();
+ }
}
void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
int clearattr, bool wrap)
{
+ LineFlags flags = wrap ? kLineFlagWrap : 0;
+ if (startcol == -1) {
+ startcol = 0;
+ flags |= kLineFlagInvalid;
+ }
+
size_t off = grid->line_offset[row] + (size_t)startcol;
- UI_CALL(raw_line, grid->handle, row, startcol, endcol, clearcol, clearattr,
- wrap, (const schar_T *)grid->chars + off,
- (const sattr_T *)grid->attrs + off);
+ ui_call_raw_line(grid->handle, row, startcol, endcol, clearcol, clearattr,
+ flags, (const schar_T *)grid->chars + off,
+ (const sattr_T *)grid->attrs + off);
if (p_wd) { // 'writedelay': flush & delay each time.
int old_row = cursor_row, old_col = cursor_col;
@@ -376,6 +384,8 @@ void ui_flush(void)
{
cmdline_ui_flush();
win_ui_flush();
+ msg_ext_ui_flush();
+
if (pending_cursor_update) {
ui_call_grid_cursor_goto(cursor_grid_handle, cursor_row, cursor_col);
pending_cursor_update = false;
@@ -412,16 +422,16 @@ void ui_cursor_shape(void)
conceal_check_cursor_line();
}
-/// Returns true if `widget` is externalized.
-bool ui_is_external(UIExtension widget)
+/// Returns true if the given UI extension is enabled.
+bool ui_has(UIExtension ext)
{
- return ui_ext[widget];
+ return ui_ext[ext];
}
Array ui_array(void)
{
Array all_uis = ARRAY_DICT_INIT;
- for (size_t i = 0; i < ui_count; i++) {
+ for (size_t i = 1; i < ui_count; i++) {
UI *ui = uis[i];
Dictionary info = ARRAY_DICT_INIT;
PUT(info, "width", INTEGER_OBJ(ui->width));
@@ -452,7 +462,8 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error)
return;
}
- wp->w_grid.requested_rows = (int)height;
- wp->w_grid.requested_cols = (int)width;
- redraw_win_later(wp, SOME_VALID);
+ // non-positive indicates no request
+ wp->w_height_request = (int)MAX(height, 0);
+ wp->w_width_request = (int)MAX(width, 0);
+ win_set_inner_size(wp);
}