Merge branch 'win32Gui'
This commit is contained in:
commit
8b43cc3697
12 changed files with 2073 additions and 16 deletions
67
build.zig
67
build.zig
|
@ -8,6 +8,7 @@ pub fn build(b: *std.Build) void {
|
|||
const strip = b.option(bool, "strip", "Disable debug information (default: no)");
|
||||
const use_llvm = b.option(bool, "use_llvm", "Enable llvm backend (default: none)");
|
||||
const pie = b.option(bool, "pie", "Produce an executable with position independent code (default: none)");
|
||||
const gui = b.option(bool, "gui", "Standalone GUI mode") orelse false;
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
const check_step = b.step("check", "Check the app");
|
||||
|
@ -25,6 +26,7 @@ pub fn build(b: *std.Build) void {
|
|||
strip,
|
||||
use_llvm,
|
||||
pie,
|
||||
gui,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -39,6 +41,7 @@ fn build_development(
|
|||
strip: ?bool,
|
||||
use_llvm: ?bool,
|
||||
pie: ?bool,
|
||||
gui: bool,
|
||||
) void {
|
||||
const target = b.standardTargetOptions(.{ .default_target = .{ .abi = if (builtin.os.tag == .linux and !tracy_enabled) .musl else null } });
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
@ -57,6 +60,7 @@ fn build_development(
|
|||
strip orelse false,
|
||||
use_llvm,
|
||||
pie,
|
||||
gui,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,6 +75,7 @@ fn build_release(
|
|||
strip: ?bool,
|
||||
use_llvm: ?bool,
|
||||
pie: ?bool,
|
||||
gui: bool,
|
||||
) void {
|
||||
const targets: []const std.Target.Query = &.{
|
||||
.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl },
|
||||
|
@ -112,6 +117,7 @@ fn build_release(
|
|||
strip orelse true,
|
||||
use_llvm,
|
||||
pie,
|
||||
gui,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -130,11 +136,13 @@ pub fn build_exe(
|
|||
strip: bool,
|
||||
use_llvm: ?bool,
|
||||
pie: ?bool,
|
||||
gui: bool,
|
||||
) void {
|
||||
const options = b.addOptions();
|
||||
options.addOption(bool, "enable_tracy", tracy_enabled);
|
||||
options.addOption(bool, "use_tree_sitter", use_tree_sitter);
|
||||
options.addOption(bool, "strip", strip);
|
||||
options.addOption(bool, "gui", gui);
|
||||
|
||||
const options_mod = options.createModule();
|
||||
|
||||
|
@ -266,7 +274,7 @@ pub fn build_exe(
|
|||
},
|
||||
});
|
||||
|
||||
const renderer_mod = b.createModule(.{
|
||||
const tui_renderer_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/renderer/vaxis/renderer.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "vaxis", .module = vaxis_mod },
|
||||
|
@ -280,6 +288,52 @@ pub fn build_exe(
|
|||
},
|
||||
});
|
||||
|
||||
const renderer_mod = blk: {
|
||||
if (gui) switch (target.result.os.tag) {
|
||||
.windows => {
|
||||
const direct2d_dep = b.lazyDependency("direct2d", .{}) orelse break :blk tui_renderer_mod;
|
||||
|
||||
const win32_dep = direct2d_dep.builder.dependency("win32", .{});
|
||||
const win32_mod = win32_dep.module("zigwin32");
|
||||
const gui_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/win32/gui.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "win32", .module = win32_mod },
|
||||
.{ .name = "ddui", .module = direct2d_dep.module("ddui") },
|
||||
.{ .name = "cbor", .module = cbor_mod },
|
||||
.{ .name = "thespian", .module = thespian_mod },
|
||||
.{ .name = "input", .module = input_mod },
|
||||
// TODO: we should be able to work without these modules
|
||||
.{ .name = "vaxis", .module = vaxis_mod },
|
||||
.{ .name = "color", .module = color_mod },
|
||||
},
|
||||
});
|
||||
gui_mod.addIncludePath(b.path("src/win32"));
|
||||
|
||||
const mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/renderer/win32/renderer.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "theme", .module = themes_dep.module("theme") },
|
||||
.{ .name = "win32", .module = win32_mod },
|
||||
.{ .name = "cbor", .module = cbor_mod },
|
||||
.{ .name = "thespian", .module = thespian_mod },
|
||||
.{ .name = "input", .module = input_mod },
|
||||
.{ .name = "gui", .module = gui_mod },
|
||||
// TODO: we should be able to work without these modules
|
||||
.{ .name = "tuirenderer", .module = tui_renderer_mod },
|
||||
.{ .name = "vaxis", .module = vaxis_mod },
|
||||
},
|
||||
});
|
||||
break :blk mod;
|
||||
},
|
||||
else => |tag| {
|
||||
std.log.err("OS '{s}' does not support -Dgui mode", .{@tagName(tag)});
|
||||
std.process.exit(0xff);
|
||||
},
|
||||
};
|
||||
break :blk tui_renderer_mod;
|
||||
};
|
||||
|
||||
const keybind_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/keybind/keybind.zig"),
|
||||
.imports = &.{
|
||||
|
@ -392,6 +446,7 @@ pub fn build_exe(
|
|||
.target = target,
|
||||
.optimize = optimize,
|
||||
.strip = strip,
|
||||
.win32_manifest = b.path("src/win32/flow.manifest"),
|
||||
});
|
||||
|
||||
if (use_llvm) |value| {
|
||||
|
@ -411,6 +466,16 @@ pub fn build_exe(
|
|||
exe.root_module.addImport("input", input_mod);
|
||||
exe.root_module.addImport("syntax", syntax_mod);
|
||||
exe.root_module.addImport("version_info", b.createModule(.{ .root_source_file = version_info_file }));
|
||||
|
||||
if (target.result.os.tag == .windows) {
|
||||
exe.addWin32ResourceFile(.{
|
||||
.file = b.path("src/win32/flow.rc"),
|
||||
});
|
||||
if (gui) {
|
||||
exe.subsystem = .Windows;
|
||||
}
|
||||
}
|
||||
|
||||
const exe_install = b.addInstallArtifact(exe, exe_install_options);
|
||||
b.getInstallStep().dependOn(&exe_install.step);
|
||||
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
.url = "https://github.com/rockorager/zeit/archive/9cca8ec620a54c3b07cd249f25e5bcb3153d03d7.tar.gz",
|
||||
.hash = "1220755ea2a5aa6bb3713437aaafefd44812169fe43f1da755c3ee6101b85940f441",
|
||||
},
|
||||
.direct2d = .{
|
||||
.url = "https://github.com/marler8997/direct2d-zig/archive/0d031389a26653bb71f81c2340d1b8ba6bd339c3.tar.gz",
|
||||
.hash = "122069b40656962c6ba9b9b3f9f882ba2e9cf4c5e1afebac7b7501404129e6bb4705",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"include",
|
||||
|
|
|
@ -142,11 +142,12 @@ pub fn input_fd_blocking(self: Self) i32 {
|
|||
return self.tty.fd;
|
||||
}
|
||||
|
||||
pub fn leave_alternate_screen(self: *Self) void {
|
||||
self.vx.exitAltScreen() catch {};
|
||||
}
|
||||
|
||||
pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) !void {
|
||||
pub fn process_renderer_event(self: *Self, msg: []const u8) !void {
|
||||
var input_: []const u8 = undefined;
|
||||
var text_: []const u8 = undefined;
|
||||
if (!try cbor.match(msg, .{ "RDR", cbor.extract(&input_), cbor.extract(&text_) }))
|
||||
return error.UnexpectedRendererEvent;
|
||||
const text = if (text_.len > 0) text_ else null;
|
||||
const event = std.mem.bytesAsValue(vaxis.Event, input_);
|
||||
switch (event.*) {
|
||||
.key_press => |key__| {
|
||||
|
@ -349,7 +350,7 @@ pub fn request_system_clipboard(self: *Self) void {
|
|||
self.vx.requestSystemClipboard(self.tty.anyWriter()) catch |e| log.logger(log_name).err("request_system_clipboard", e);
|
||||
}
|
||||
|
||||
pub fn request_windows_clipboard(self: *Self) ![]u8 {
|
||||
pub fn request_windows_clipboard(allocator: std.mem.Allocator) ![]u8 {
|
||||
const windows = std.os.windows;
|
||||
const win32 = struct {
|
||||
pub extern "user32" fn OpenClipboard(hWndNewOwner: ?windows.HWND) callconv(windows.WINAPI) windows.BOOL;
|
||||
|
@ -370,7 +371,7 @@ pub fn request_windows_clipboard(self: *Self) ![]u8 {
|
|||
const text = std.mem.span(data);
|
||||
defer _ = win32.GlobalUnlock(mem);
|
||||
|
||||
return self.allocator.dupe(u8, text);
|
||||
return allocator.dupe(u8, text);
|
||||
}
|
||||
|
||||
pub fn request_mouse_cursor_text(self: *Self, push_or_pop: bool) void {
|
||||
|
@ -493,7 +494,7 @@ const Loop = struct {
|
|||
},
|
||||
else => {},
|
||||
}
|
||||
self.pid.send(.{ "VXS", std.mem.asBytes(&event), text }) catch @panic("send VXS event failed");
|
||||
self.pid.send(.{ "RDR", std.mem.asBytes(&event), text }) catch @panic("send RDR event failed");
|
||||
if (free_text)
|
||||
self.vaxis.opts.system_clipboard_allocator.?.free(text);
|
||||
}
|
||||
|
|
397
src/renderer/win32/renderer.zig
Normal file
397
src/renderer/win32/renderer.zig
Normal file
|
@ -0,0 +1,397 @@
|
|||
const Self = @This();
|
||||
pub const log_name = "renderer";
|
||||
|
||||
const std = @import("std");
|
||||
const cbor = @import("cbor");
|
||||
const vaxis = @import("vaxis");
|
||||
const Style = @import("theme").Style;
|
||||
const Color = @import("theme").Color;
|
||||
pub const CursorShape = vaxis.Cell.CursorShape;
|
||||
|
||||
pub const Plane = @import("tuirenderer").Plane;
|
||||
const input = @import("input");
|
||||
|
||||
const win32 = @import("win32").everything;
|
||||
|
||||
pub const Cell = @import("tuirenderer").Cell;
|
||||
pub const StyleBits = @import("tuirenderer").style;
|
||||
const gui = @import("gui");
|
||||
const DropWriter = gui.DropWriter;
|
||||
pub const style = StyleBits;
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
vx: vaxis.Vaxis,
|
||||
|
||||
renders_missed: u32 = 0,
|
||||
|
||||
handler_ctx: *anyopaque,
|
||||
dispatch_input: ?*const fn (ctx: *anyopaque, cbor_msg: []const u8) void = null,
|
||||
dispatch_mouse: ?*const fn (ctx: *anyopaque, y: c_int, x: c_int, cbor_msg: []const u8) void = null,
|
||||
dispatch_mouse_drag: ?*const fn (ctx: *anyopaque, y: c_int, x: c_int, cbor_msg: []const u8) void = null,
|
||||
dispatch_event: ?*const fn (ctx: *anyopaque, cbor_msg: []const u8) void = null,
|
||||
|
||||
thread: ?std.Thread = null,
|
||||
|
||||
const global = struct {
|
||||
var init_called: bool = false;
|
||||
};
|
||||
|
||||
fn oom(e: error{OutOfMemory}) noreturn {
|
||||
@panic(@errorName(e));
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
allocator: std.mem.Allocator,
|
||||
handler_ctx: *anyopaque,
|
||||
no_alternate: bool,
|
||||
) !Self {
|
||||
std.debug.assert(!global.init_called);
|
||||
global.init_called = true;
|
||||
|
||||
_ = no_alternate;
|
||||
|
||||
gui.init();
|
||||
const opts: vaxis.Vaxis.Options = .{
|
||||
.kitty_keyboard_flags = .{
|
||||
.disambiguate = true,
|
||||
.report_events = true,
|
||||
.report_alternate_keys = true,
|
||||
.report_all_as_ctl_seqs = true,
|
||||
.report_text = true,
|
||||
},
|
||||
.system_clipboard_allocator = allocator,
|
||||
};
|
||||
var result = .{
|
||||
.allocator = allocator,
|
||||
.vx = try vaxis.init(allocator, opts),
|
||||
.handler_ctx = handler_ctx,
|
||||
};
|
||||
result.vx.caps.unicode = .unicode;
|
||||
result.vx.screen.width_method = .unicode;
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
std.log.warn("TODO: implement win32 renderer deinit", .{});
|
||||
var drop_writer = DropWriter{};
|
||||
self.vx.deinit(self.allocator, drop_writer.writer().any());
|
||||
}
|
||||
|
||||
threadlocal var thread_is_panicing = false;
|
||||
|
||||
pub fn panic(
|
||||
msg: []const u8,
|
||||
error_return_trace: ?*std.builtin.StackTrace,
|
||||
ret_addr: ?usize,
|
||||
) noreturn {
|
||||
if (!thread_is_panicing) {
|
||||
thread_is_panicing = true;
|
||||
const msg_z: [:0]const u8 = if (std.fmt.allocPrintZ(
|
||||
std.heap.page_allocator,
|
||||
"{s}",
|
||||
.{msg},
|
||||
)) |msg_z| msg_z else |_| "failed allocate error message";
|
||||
_ = win32.MessageBoxA(null, msg_z, "Flow Panic", .{ .ICONASTERISK = 1 });
|
||||
}
|
||||
std.builtin.default_panic(msg, error_return_trace, ret_addr);
|
||||
}
|
||||
|
||||
pub fn run(self: *Self) !void {
|
||||
if (self.thread) |_| return;
|
||||
|
||||
// dummy resize to fully init vaxis
|
||||
const drop_writer = DropWriter{};
|
||||
try self.vx.resize(
|
||||
self.allocator,
|
||||
drop_writer.writer().any(),
|
||||
.{ .rows = 25, .cols = 80, .x_pixel = 0, .y_pixel = 0 },
|
||||
);
|
||||
self.vx.queueRefresh();
|
||||
//if (self.dispatch_event) |f| f(self.handler_ctx, try self.fmtmsg(.{"resize"}));
|
||||
self.thread = try gui.start();
|
||||
}
|
||||
|
||||
pub fn fmtmsg(buf: []u8, value: anytype) []const u8 {
|
||||
var fbs = std.io.fixedBufferStream(buf);
|
||||
cbor.writeValue(fbs.writer(), value) catch |e| switch (e) {
|
||||
error.NoSpaceLeft => std.debug.panic("buffer of size {} not big enough", .{buf.len}),
|
||||
};
|
||||
return buf[0..fbs.pos];
|
||||
}
|
||||
|
||||
pub fn render(self: *Self) error{}!void {
|
||||
if (!gui.updateScreen(&self.vx.screen)) {
|
||||
self.renders_missed += 1;
|
||||
std.log.warn("missed {} renders, no gui window yet", .{self.renders_missed});
|
||||
}
|
||||
}
|
||||
pub fn stop(self: *Self) void {
|
||||
_ = self;
|
||||
std.log.warn("TODO: implement stop", .{});
|
||||
}
|
||||
|
||||
pub fn stdplane(self: *Self) Plane {
|
||||
const name = "root";
|
||||
var plane: Plane = .{
|
||||
.window = self.vx.window(),
|
||||
.name_buf = undefined,
|
||||
.name_len = name.len,
|
||||
};
|
||||
@memcpy(plane.name_buf[0..name.len], name);
|
||||
return plane;
|
||||
}
|
||||
|
||||
pub fn process_renderer_event(self: *Self, msg: []const u8) !void {
|
||||
const Input = struct {
|
||||
kind: u8,
|
||||
codepoint: u21,
|
||||
shifted_codepoint: u21,
|
||||
text: []const u8,
|
||||
mods: u8,
|
||||
};
|
||||
const MousePos = struct {
|
||||
col: i32,
|
||||
row: i32,
|
||||
xoffset: i32,
|
||||
yoffset: i32,
|
||||
};
|
||||
const Winsize = struct {
|
||||
cell_width: u16,
|
||||
cell_height: u16,
|
||||
pixel_width: u16,
|
||||
pixel_height: u16,
|
||||
};
|
||||
|
||||
{
|
||||
var args: Input = undefined;
|
||||
if (try cbor.match(msg, .{
|
||||
cbor.any,
|
||||
"I",
|
||||
cbor.extract(&args.kind),
|
||||
cbor.extract(&args.codepoint),
|
||||
cbor.extract(&args.shifted_codepoint),
|
||||
cbor.extract(&args.text),
|
||||
cbor.extract(&args.mods),
|
||||
})) {
|
||||
var buf: [300]u8 = undefined;
|
||||
const cbor_msg = fmtmsg(&buf, .{
|
||||
"I",
|
||||
args.kind,
|
||||
args.codepoint,
|
||||
args.shifted_codepoint,
|
||||
args.text,
|
||||
args.mods,
|
||||
});
|
||||
if (self.dispatch_input) |f| f(self.handler_ctx, cbor_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var args: Winsize = undefined;
|
||||
if (try cbor.match(msg, .{
|
||||
cbor.any,
|
||||
"Resize",
|
||||
cbor.extract(&args.cell_width),
|
||||
cbor.extract(&args.cell_height),
|
||||
cbor.extract(&args.pixel_width),
|
||||
cbor.extract(&args.pixel_height),
|
||||
})) {
|
||||
var drop_writer = DropWriter{};
|
||||
self.vx.resize(self.allocator, drop_writer.writer().any(), .{
|
||||
.rows = @intCast(args.cell_height),
|
||||
.cols = @intCast(args.cell_width),
|
||||
.x_pixel = @intCast(args.pixel_width),
|
||||
.y_pixel = @intCast(args.pixel_height),
|
||||
}) catch |err| std.debug.panic("resize failed with {s}", .{@errorName(err)});
|
||||
self.vx.queueRefresh();
|
||||
{
|
||||
var buf: [200]u8 = undefined;
|
||||
if (self.dispatch_event) |f| f(self.handler_ctx, fmtmsg(&buf, .{"resize"}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
var args: MousePos = undefined;
|
||||
if (try cbor.match(msg, .{
|
||||
cbor.any,
|
||||
"M",
|
||||
cbor.extract(&args.col),
|
||||
cbor.extract(&args.row),
|
||||
cbor.extract(&args.xoffset),
|
||||
cbor.extract(&args.yoffset),
|
||||
})) {
|
||||
var buf: [200]u8 = undefined;
|
||||
if (self.dispatch_mouse) |f| f(
|
||||
self.handler_ctx,
|
||||
@intCast(args.row),
|
||||
@intCast(args.col),
|
||||
fmtmsg(&buf, .{
|
||||
"M",
|
||||
args.col,
|
||||
args.row,
|
||||
args.xoffset,
|
||||
args.yoffset,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
var args: struct {
|
||||
pos: MousePos,
|
||||
button: struct {
|
||||
press: u8,
|
||||
id: u8,
|
||||
},
|
||||
} = undefined;
|
||||
if (try cbor.match(msg, .{
|
||||
cbor.any,
|
||||
"B",
|
||||
cbor.extract(&args.button.press),
|
||||
cbor.extract(&args.button.id),
|
||||
cbor.extract(&args.pos.col),
|
||||
cbor.extract(&args.pos.row),
|
||||
cbor.extract(&args.pos.xoffset),
|
||||
cbor.extract(&args.pos.yoffset),
|
||||
})) {
|
||||
var buf: [200]u8 = undefined;
|
||||
if (self.dispatch_mouse) |f| f(
|
||||
self.handler_ctx,
|
||||
@intCast(args.pos.row),
|
||||
@intCast(args.pos.col),
|
||||
fmtmsg(&buf, .{
|
||||
"B",
|
||||
args.button.press,
|
||||
args.button.id,
|
||||
input.utils.button_id_string(@enumFromInt(args.button.id)),
|
||||
args.pos.col,
|
||||
args.pos.row,
|
||||
args.pos.xoffset,
|
||||
args.pos.yoffset,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return error.UnexpectedRendererEvent;
|
||||
}
|
||||
|
||||
fn setEllipsis(str: []u16) void {
|
||||
std.debug.assert(str.len >= 3);
|
||||
str[str.len - 1] = '.';
|
||||
str[str.len - 2] = '.';
|
||||
str[str.len - 3] = '.';
|
||||
}
|
||||
|
||||
const ConversionSizes = struct {
|
||||
src_len: usize,
|
||||
dst_len: usize,
|
||||
};
|
||||
fn calcUtf8ToUtf16LeWithMax(utf8: []const u8, max_dst_len: usize) !ConversionSizes {
|
||||
var src_len: usize = 0;
|
||||
var dst_len: usize = 0;
|
||||
while (src_len < utf8.len) {
|
||||
if (dst_len >= max_dst_len) break;
|
||||
const n = try std.unicode.utf8ByteSequenceLength(utf8[src_len]);
|
||||
const next_src_len = src_len + n;
|
||||
const codepoint = try std.unicode.utf8Decode(utf8[src_len..next_src_len]);
|
||||
if (codepoint < 0x10000) {
|
||||
dst_len += 1;
|
||||
} else {
|
||||
if (dst_len + 2 > max_dst_len) break;
|
||||
dst_len += 2;
|
||||
}
|
||||
src_len = next_src_len;
|
||||
}
|
||||
return .{ .src_len = src_len, .dst_len = dst_len };
|
||||
}
|
||||
|
||||
pub fn set_terminal_title(self: *Self, title_utf8: []const u8) void {
|
||||
_ = self;
|
||||
|
||||
const max_title_wide = 500;
|
||||
const conversion_sizes = calcUtf8ToUtf16LeWithMax(title_utf8, max_title_wide) catch {
|
||||
std.log.err("title is invalid UTF-8", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
var title_wide_buf: [max_title_wide + 1]u16 = undefined;
|
||||
const len = @min(max_title_wide, conversion_sizes.dst_len);
|
||||
title_wide_buf[len] = 0;
|
||||
const title_wide = title_wide_buf[0..len :0];
|
||||
|
||||
const size = std.unicode.utf8ToUtf16Le(title_wide, title_utf8[0..conversion_sizes.src_len]) catch |err| switch (err) {
|
||||
error.InvalidUtf8 => {
|
||||
std.log.err("title is invalid UTF-8", .{});
|
||||
return;
|
||||
},
|
||||
};
|
||||
std.debug.assert(size == conversion_sizes.dst_len);
|
||||
if (conversion_sizes.src_len != title_utf8.len) {
|
||||
setEllipsis(title_wide);
|
||||
}
|
||||
var win32_err: gui.Win32Error = undefined;
|
||||
gui.setWindowTitle(title_wide, &win32_err) catch |err| switch (err) {
|
||||
error.NoWindow => std.log.warn("no window to set the title for", .{}),
|
||||
error.Win32 => std.log.err("{s} failed with {}", .{ win32_err.what, win32_err.code.fmt() }),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_terminal_style(self: *Self, style_: Style) void {
|
||||
_ = self;
|
||||
_ = style_;
|
||||
std.log.warn("TODO: implement set_terminal_style", .{});
|
||||
//if (style_.fg) |color|
|
||||
//self.vx.setTerminalForegroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {};
|
||||
//if (style_.bg) |color|
|
||||
//self.vx.setTerminalBackgroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {};
|
||||
}
|
||||
|
||||
pub fn set_terminal_cursor_color(self: *Self, color: Color) void {
|
||||
_ = self;
|
||||
std.log.warn("TODO: set_terminal_cursor_color '{any}'", .{color});
|
||||
//self.vx.setTerminalCursorColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {};
|
||||
}
|
||||
|
||||
pub fn set_terminal_working_directory(self: *Self, absolute_path: []const u8) void {
|
||||
_ = self;
|
||||
std.log.warn("TODO: set_terminal_working_directory '{s}'", .{absolute_path});
|
||||
//self.vx.setTerminalWorkingDirectory(self.tty.anyWriter(), absolute_path) catch {};
|
||||
}
|
||||
|
||||
pub fn copy_to_system_clipboard(self: *Self, text: []const u8) void {
|
||||
_ = self;
|
||||
_ = text;
|
||||
std.log.warn("TODO: copy_to_system_clipboard", .{});
|
||||
}
|
||||
|
||||
pub const request_windows_clipboard = @import("tuirenderer").request_windows_clipboard;
|
||||
|
||||
pub fn request_mouse_cursor_text(self: *Self, push_or_pop: bool) void {
|
||||
_ = self;
|
||||
_ = push_or_pop;
|
||||
//@panic("todo");
|
||||
}
|
||||
pub fn request_mouse_cursor_pointer(self: *Self, push_or_pop: bool) void {
|
||||
_ = self;
|
||||
_ = push_or_pop;
|
||||
//@panic("todo");
|
||||
}
|
||||
pub fn request_mouse_cursor_default(self: *Self, push_or_pop: bool) void {
|
||||
_ = self;
|
||||
_ = push_or_pop;
|
||||
//@panic("todo");
|
||||
}
|
||||
pub fn cursor_enable(self: *Self, y: c_int, x: c_int, shape: CursorShape) !void {
|
||||
_ = self;
|
||||
_ = y;
|
||||
_ = x;
|
||||
_ = shape;
|
||||
//@panic("todo");
|
||||
}
|
||||
pub fn cursor_disable(self: *Self) void {
|
||||
_ = self;
|
||||
//@panic("todo");
|
||||
}
|
|
@ -570,10 +570,10 @@ const cmds = struct {
|
|||
}
|
||||
pub const open_previous_file_meta = .{ .description = "Open the previous file" };
|
||||
|
||||
pub fn system_paste(_: *Self, _: Ctx) Result {
|
||||
pub fn system_paste(self: *Self, _: Ctx) Result {
|
||||
if (builtin.os.tag == .windows) {
|
||||
const text = try tui.current().rdr.request_windows_clipboard();
|
||||
defer tui.current().rdr.allocator.free(text);
|
||||
const text = try @import("renderer").request_windows_clipboard(self.allocator);
|
||||
defer self.allocator.free(text);
|
||||
return command.executeName("paste", command.fmt(.{text})) catch {};
|
||||
}
|
||||
tui.current().rdr.request_system_clipboard();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const tp = @import("thespian");
|
||||
const cbor = @import("cbor");
|
||||
const log = @import("log");
|
||||
|
@ -91,6 +92,7 @@ fn init(allocator: Allocator) !*Self {
|
|||
conf.input_mode = try allocator.dupe(u8, conf.input_mode);
|
||||
conf.top_bar = try allocator.dupe(u8, conf.top_bar);
|
||||
conf.bottom_bar = try allocator.dupe(u8, conf.bottom_bar);
|
||||
if (build_options.gui) conf.enable_terminal_cursor = false;
|
||||
|
||||
const frame_rate: usize = @intCast(tp.env.get().num("frame-rate"));
|
||||
if (frame_rate != 0)
|
||||
|
@ -246,10 +248,11 @@ fn receive(self: *Self, from: tp.pid_ref, m: tp.message) tp.result {
|
|||
}
|
||||
|
||||
fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
|
||||
var input: []const u8 = undefined;
|
||||
var text: []const u8 = undefined;
|
||||
if (try m.match(.{ "VXS", tp.extract(&input), tp.extract(&text) })) {
|
||||
try self.rdr.process_input_event(input, if (text.len > 0) text else null);
|
||||
if (try m.match(.{ "RDR", tp.more })) {
|
||||
self.rdr.process_renderer_event(m.buf) catch |e| switch (e) {
|
||||
error.UnexpectedRendererEvent => return tp.unexpected(m),
|
||||
else => return e,
|
||||
};
|
||||
try self.dispatch_flush_input_event();
|
||||
if (self.unrendered_input_events_count > 0 and !self.frame_clock_running)
|
||||
need_render();
|
||||
|
@ -304,6 +307,7 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
|
|||
return;
|
||||
}
|
||||
|
||||
var text: []const u8 = undefined;
|
||||
if (try m.match(.{ "system_clipboard", tp.extract(&text) })) {
|
||||
try self.dispatch_flush_input_event();
|
||||
return if (command.get_id("mini_mode_paste")) |id|
|
||||
|
|
1
src/win32/ResourceNames.h
Normal file
1
src/win32/ResourceNames.h
Normal file
|
@ -0,0 +1 @@
|
|||
#define ID_ICON_FLOW 1
|
BIN
src/win32/flow.ico
Normal file
BIN
src/win32/flow.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
14
src/win32/flow.manifest
Normal file
14
src/win32/flow.manifest
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
34
src/win32/flow.rc
Normal file
34
src/win32/flow.rc
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "ResourceNames.h"
|
||||
|
||||
// LANG_NEUTRAL(0), SUBLANG_NEUTRAL(0)
|
||||
LANGUAGE 0, 0
|
||||
|
||||
ID_ICON_FLOW ICON "flow.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
//FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_COMMIT_HEIGHT
|
||||
//PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,VERSION_COMMIT_HEIGHT
|
||||
//FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
//FILEFLAGS VER_DBG
|
||||
//FILEOS VOS_NT
|
||||
//FILETYPE VFT_APP
|
||||
//FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
//VALUE "CompanyName", "???"
|
||||
//VALUE "FileDescription", "???"
|
||||
//VALUE "FileVersion", VERSION
|
||||
//VALUE "LegalCopyright", "(C) 2024 ???"
|
||||
VALUE "OriginalFilename", "flow.exe"
|
||||
VALUE "ProductName", "Flow Control"
|
||||
//VALUE "ProductVersion", VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409,1200
|
||||
END
|
||||
END
|
1171
src/win32/gui.zig
Normal file
1171
src/win32/gui.zig
Normal file
File diff suppressed because it is too large
Load diff
365
src/win32/windowmsg.zig
Normal file
365
src/win32/windowmsg.zig
Normal file
|
@ -0,0 +1,365 @@
|
|||
const std = @import("std");
|
||||
const win32 = @import("win32").everything;
|
||||
|
||||
pub fn pointFromLparam(lparam: win32.LPARAM) win32.POINT {
|
||||
return .{
|
||||
.x = @as(i16, @bitCast(win32.loword(lparam))),
|
||||
.y = @as(i16, @bitCast(win32.hiword(lparam))),
|
||||
};
|
||||
}
|
||||
|
||||
pub const MessageNode = struct {
|
||||
tail_ref: *?*MessageNode,
|
||||
hwnd: win32.HWND,
|
||||
msg: u32,
|
||||
wparam: win32.WPARAM,
|
||||
lparam: win32.LPARAM,
|
||||
old_tail: ?*MessageNode,
|
||||
pub fn init(
|
||||
self: *MessageNode,
|
||||
tail_ref: *?*MessageNode,
|
||||
hwnd: win32.HWND,
|
||||
msg: u32,
|
||||
wparam: win32.WPARAM,
|
||||
lparam: win32.LPARAM,
|
||||
) void {
|
||||
if (tail_ref.*) |old_tail| {
|
||||
std.debug.assert(old_tail.hwnd == hwnd);
|
||||
}
|
||||
self.* = .{
|
||||
.tail_ref = tail_ref,
|
||||
.hwnd = hwnd,
|
||||
.msg = msg,
|
||||
.wparam = wparam,
|
||||
.lparam = lparam,
|
||||
.old_tail = tail_ref.*,
|
||||
};
|
||||
tail_ref.* = self;
|
||||
}
|
||||
pub fn deinit(self: *MessageNode) void {
|
||||
std.debug.assert(self.tail_ref.* == self);
|
||||
self.tail_ref.* = self.old_tail;
|
||||
}
|
||||
pub fn fmtPath(self: *MessageNode) FmtPath {
|
||||
return .{ .node = self };
|
||||
}
|
||||
};
|
||||
|
||||
fn writeMessageNodePath(
|
||||
writer: anytype,
|
||||
node: *MessageNode,
|
||||
) !void {
|
||||
if (node.old_tail) |old_tail| {
|
||||
try writeMessageNodePath(writer, old_tail);
|
||||
try writer.writeAll(" > ");
|
||||
}
|
||||
try writer.print("{s}:{}", .{ msg_name(node.msg) orelse "?", node.msg });
|
||||
switch (node.msg) {
|
||||
win32.WM_NCMOUSEMOVE,
|
||||
win32.WM_NCLBUTTONDOWN,
|
||||
=> {
|
||||
const hit_value = node.wparam;
|
||||
const point = pointFromLparam(node.lparam);
|
||||
try writer.print(
|
||||
"(hit={s}:{},point={},{})",
|
||||
.{ getHitName(@bitCast(hit_value)) orelse "?", hit_value, point.x, point.y },
|
||||
);
|
||||
},
|
||||
win32.WM_NCHITTEST,
|
||||
win32.WM_MOUSEMOVE,
|
||||
=> {
|
||||
const point = pointFromLparam(node.lparam);
|
||||
try writer.print("({},{})", .{ point.x, point.y });
|
||||
},
|
||||
win32.WM_CAPTURECHANGED => {
|
||||
try writer.print("({})", .{node.lparam});
|
||||
},
|
||||
win32.WM_SYSCOMMAND => {
|
||||
try writer.print("(type=0x{x})", .{0xfff0 & node.wparam});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
const FmtPath = struct {
|
||||
node: *MessageNode,
|
||||
const Self = @This();
|
||||
pub fn format(
|
||||
self: Self,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
try writeMessageNodePath(writer, self.node);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn msg_name(msg: u32) ?[]const u8 {
|
||||
return switch (msg) {
|
||||
0 => "WM_NULL",
|
||||
1 => "WM_CREATE",
|
||||
2 => "WM_DESTROY",
|
||||
3 => "WM_MOVE",
|
||||
5 => "WM_SIZE",
|
||||
6 => "WM_ACTIVATE",
|
||||
7 => "WM_SETFOCUS",
|
||||
8 => "WM_KILLFOCUS",
|
||||
10 => "WM_ENABLE",
|
||||
11 => "WM_SETREDRAW",
|
||||
12 => "WM_SETTEXT",
|
||||
13 => "WM_GETTEXT",
|
||||
14 => "WM_GETTEXTLENGTH",
|
||||
15 => "WM_PAINT",
|
||||
16 => "WM_CLOSE",
|
||||
17 => "WM_QUERYENDSESSION",
|
||||
18 => "WM_QUIT",
|
||||
19 => "WM_QUERYOPEN",
|
||||
20 => "WM_ERASEBKGND",
|
||||
21 => "WM_SYSCOLORCHANGE",
|
||||
22 => "WM_ENDSESSION",
|
||||
24 => "WM_SHOWWINDOW",
|
||||
25 => "WM_CTLCOLOR",
|
||||
26 => "WM_WININICHANGE",
|
||||
27 => "WM_DEVMODECHANGE",
|
||||
28 => "WM_ACTIVATEAPP",
|
||||
29 => "WM_FONTCHANGE",
|
||||
30 => "WM_TIMECHANGE",
|
||||
31 => "WM_CANCELMODE",
|
||||
32 => "WM_SETCURSOR",
|
||||
33 => "WM_MOUSEACTIVATE",
|
||||
34 => "WM_CHILDACTIVATE",
|
||||
35 => "WM_QUEUESYNC",
|
||||
36 => "WM_GETMINMAXINFO",
|
||||
38 => "WM_PAINTICON",
|
||||
39 => "WM_ICONERASEBKGND",
|
||||
40 => "WM_NEXTDLGCTL",
|
||||
42 => "WM_SPOOLERSTATUS",
|
||||
43 => "WM_DRAWITEM",
|
||||
44 => "WM_MEASUREITEM",
|
||||
45 => "WM_DELETEITEM",
|
||||
46 => "WM_VKEYTOITEM",
|
||||
47 => "WM_CHARTOITEM",
|
||||
48 => "WM_SETFONT",
|
||||
49 => "WM_GETFONT",
|
||||
50 => "WM_SETHOTKEY",
|
||||
51 => "WM_GETHOTKEY",
|
||||
55 => "WM_QUERYDRAGICON",
|
||||
57 => "WM_COMPAREITEM",
|
||||
61 => "WM_GETOBJECT",
|
||||
65 => "WM_COMPACTING",
|
||||
68 => "WM_COMMNOTIFY",
|
||||
70 => "WM_WINDOWPOSCHANGING",
|
||||
71 => "WM_WINDOWPOSCHANGED",
|
||||
72 => "WM_POWER",
|
||||
73 => "WM_COPYGLOBALDATA",
|
||||
74 => "WM_COPYDATA",
|
||||
75 => "WM_CANCELJOURNAL",
|
||||
78 => "WM_NOTIFY",
|
||||
80 => "WM_INPUTLANGCHANGEREQUEST",
|
||||
81 => "WM_INPUTLANGCHANGE",
|
||||
82 => "WM_TCARD",
|
||||
83 => "WM_HELP",
|
||||
84 => "WM_USERCHANGED",
|
||||
85 => "WM_NOTIFYFORMAT",
|
||||
123 => "WM_CONTEXTMENU",
|
||||
124 => "WM_STYLECHANGING",
|
||||
125 => "WM_STYLECHANGED",
|
||||
126 => "WM_DISPLAYCHANGE",
|
||||
127 => "WM_GETICON",
|
||||
128 => "WM_SETICON",
|
||||
129 => "WM_NCCREATE",
|
||||
130 => "WM_NCDESTROY",
|
||||
131 => "WM_NCCALCSIZE",
|
||||
132 => "WM_NCHITTEST",
|
||||
133 => "WM_NCPAINT",
|
||||
134 => "WM_NCACTIVATE",
|
||||
135 => "WM_GETDLGCODE",
|
||||
136 => "WM_SYNCPAINT",
|
||||
160 => "WM_NCMOUSEMOVE",
|
||||
161 => "WM_NCLBUTTONDOWN",
|
||||
162 => "WM_NCLBUTTONUP",
|
||||
163 => "WM_NCLBUTTONDBLCLK",
|
||||
164 => "WM_NCRBUTTONDOWN",
|
||||
165 => "WM_NCRBUTTONUP",
|
||||
166 => "WM_NCRBUTTONDBLCLK",
|
||||
167 => "WM_NCMBUTTONDOWN",
|
||||
168 => "WM_NCMBUTTONUP",
|
||||
169 => "WM_NCMBUTTONDBLCLK",
|
||||
171 => "WM_NCXBUTTONDOWN",
|
||||
172 => "WM_NCXBUTTONUP",
|
||||
173 => "WM_NCXBUTTONDBLCLK",
|
||||
255 => "WM_INPUT",
|
||||
256 => "WM_KEYDOWN",
|
||||
257 => "WM_KEYUP",
|
||||
258 => "WM_CHAR",
|
||||
259 => "WM_DEADCHAR",
|
||||
260 => "WM_SYSKEYDOWN",
|
||||
261 => "WM_SYSKEYUP",
|
||||
262 => "WM_SYSCHAR",
|
||||
263 => "WM_SYSDEADCHAR",
|
||||
265 => "WM_UNICHAR",
|
||||
266 => "WM_CONVERTREQUEST",
|
||||
267 => "WM_CONVERTRESULT",
|
||||
268 => "WM_INTERIM",
|
||||
269 => "WM_IME_STARTCOMPOSITION",
|
||||
270 => "WM_IME_ENDCOMPOSITION",
|
||||
271 => "WM_IME_COMPOSITION",
|
||||
272 => "WM_INITDIALOG",
|
||||
273 => "WM_COMMAND",
|
||||
274 => "WM_SYSCOMMAND",
|
||||
275 => "WM_TIMER",
|
||||
276 => "WM_HSCROLL",
|
||||
277 => "WM_VSCROLL",
|
||||
278 => "WM_INITMENU",
|
||||
279 => "WM_INITMENUPOPUP",
|
||||
280 => "WM_SYSTIMER",
|
||||
287 => "WM_MENUSELECT",
|
||||
288 => "WM_MENUCHAR",
|
||||
289 => "WM_ENTERIDLE",
|
||||
290 => "WM_MENURBUTTONUP",
|
||||
291 => "WM_MENUDRAG",
|
||||
292 => "WM_MENUGETOBJECT",
|
||||
293 => "WM_UNINITMENUPOPUP",
|
||||
294 => "WM_MENUCOMMAND",
|
||||
295 => "WM_CHANGEUISTATE",
|
||||
296 => "WM_UPDATEUISTATE",
|
||||
297 => "WM_QUERYUISTATE",
|
||||
305 => "WM_LBTRACKPOINT",
|
||||
306 => "WM_CTLCOLORMSGBOX",
|
||||
307 => "WM_CTLCOLOREDIT",
|
||||
308 => "WM_CTLCOLORLISTBOX",
|
||||
309 => "WM_CTLCOLORBTN",
|
||||
310 => "WM_CTLCOLORDLG",
|
||||
311 => "WM_CTLCOLORSCROLLBAR",
|
||||
312 => "WM_CTLCOLORSTATIC",
|
||||
512 => "WM_MOUSEMOVE",
|
||||
513 => "WM_LBUTTONDOWN",
|
||||
514 => "WM_LBUTTONUP",
|
||||
515 => "WM_LBUTTONDBLCLK",
|
||||
516 => "WM_RBUTTONDOWN",
|
||||
517 => "WM_RBUTTONUP",
|
||||
518 => "WM_RBUTTONDBLCLK",
|
||||
519 => "WM_MBUTTONDOWN",
|
||||
520 => "WM_MBUTTONUP",
|
||||
521 => "WM_MBUTTONDBLCLK",
|
||||
522 => "WM_MOUSEWHEEL",
|
||||
523 => "WM_XBUTTONDOWN",
|
||||
524 => "WM_XBUTTONUP",
|
||||
525 => "WM_XBUTTONDBLCLK",
|
||||
526 => "WM_MOUSEHWHEEL",
|
||||
528 => "WM_PARENTNOTIFY",
|
||||
529 => "WM_ENTERMENULOOP",
|
||||
530 => "WM_EXITMENULOOP",
|
||||
531 => "WM_NEXTMENU",
|
||||
532 => "WM_SIZING",
|
||||
533 => "WM_CAPTURECHANGED",
|
||||
534 => "WM_MOVING",
|
||||
536 => "WM_POWERBROADCAST",
|
||||
537 => "WM_DEVICECHANGE",
|
||||
544 => "WM_MDICREATE",
|
||||
545 => "WM_MDIDESTROY",
|
||||
546 => "WM_MDIACTIVATE",
|
||||
547 => "WM_MDIRESTORE",
|
||||
548 => "WM_MDINEXT",
|
||||
549 => "WM_MDIMAXIMIZE",
|
||||
550 => "WM_MDITILE",
|
||||
551 => "WM_MDICASCADE",
|
||||
552 => "WM_MDIICONARRANGE",
|
||||
553 => "WM_MDIGETACTIVE",
|
||||
560 => "WM_MDISETMENU",
|
||||
561 => "WM_ENTERSIZEMOVE",
|
||||
562 => "WM_EXITSIZEMOVE",
|
||||
563 => "WM_DROPFILES",
|
||||
564 => "WM_MDIREFRESHMENU",
|
||||
640 => "WM_IME_REPORT",
|
||||
641 => "WM_IME_SETCONTEXT",
|
||||
642 => "WM_IME_NOTIFY",
|
||||
643 => "WM_IME_CONTROL",
|
||||
644 => "WM_IME_COMPOSITIONFULL",
|
||||
645 => "WM_IME_SELECT",
|
||||
646 => "WM_IME_CHAR",
|
||||
648 => "WM_IME_REQUEST",
|
||||
656 => "WM_IME_KEYDOWN",
|
||||
657 => "WM_IME_KEYUP",
|
||||
672 => "WM_NCMOUSEHOVER",
|
||||
673 => "WM_MOUSEHOVER",
|
||||
674 => "WM_NCMOUSELEAVE",
|
||||
675 => "WM_MOUSELEAVE",
|
||||
768 => "WM_CUT",
|
||||
769 => "WM_COPY",
|
||||
770 => "WM_PASTE",
|
||||
771 => "WM_CLEAR",
|
||||
772 => "WM_UNDO",
|
||||
773 => "WM_RENDERFORMAT",
|
||||
774 => "WM_RENDERALLFORMATS",
|
||||
775 => "WM_DESTROYCLIPBOARD",
|
||||
776 => "WM_DRAWCLIPBOARD",
|
||||
777 => "WM_PAINTCLIPBOARD",
|
||||
778 => "WM_VSCROLLCLIPBOARD",
|
||||
779 => "WM_SIZECLIPBOARD",
|
||||
780 => "WM_ASKCBFORMATNAME",
|
||||
781 => "WM_CHANGECBCHAIN",
|
||||
782 => "WM_HSCROLLCLIPBOARD",
|
||||
783 => "WM_QUERYNEWPALETTE",
|
||||
784 => "WM_PALETTEISCHANGING",
|
||||
785 => "WM_PALETTECHANGED",
|
||||
786 => "WM_HOTKEY",
|
||||
791 => "WM_PRINT",
|
||||
792 => "WM_PRINTCLIENT",
|
||||
793 => "WM_APPCOMMAND",
|
||||
799 => "WM_DWMNCRENDERINGCHANGED",
|
||||
856 => "WM_HANDHELDFIRST",
|
||||
863 => "WM_HANDHELDLAST",
|
||||
864 => "WM_AFXFIRST",
|
||||
895 => "WM_AFXLAST",
|
||||
896 => "WM_PENWINFIRST",
|
||||
897 => "WM_RCRESULT",
|
||||
898 => "WM_HOOKRCRESULT",
|
||||
899 => "WM_GLOBALRCCHANGE",
|
||||
900 => "WM_SKB",
|
||||
901 => "WM_PENCTL",
|
||||
902 => "WM_PENMISC",
|
||||
903 => "WM_CTLINIT",
|
||||
904 => "WM_PENEVENT",
|
||||
911 => "WM_PENWINLAST",
|
||||
1024 => "WM_USER+0",
|
||||
1025 => "WM_USER+1",
|
||||
1026 => "WM_USER+2",
|
||||
1027 => "WM_USER+3",
|
||||
1028 => "WM_USER+4",
|
||||
1029 => "WM_USER+5",
|
||||
1030 => "WM_USER+6",
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getHitName(hit: win32.LRESULT) ?[]const u8 {
|
||||
return switch (hit) {
|
||||
win32.HTERROR => "err",
|
||||
win32.HTTRANSPARENT => "transprnt",
|
||||
win32.HTNOWHERE => "nowhere",
|
||||
win32.HTCLIENT => "client",
|
||||
win32.HTCAPTION => "caption",
|
||||
win32.HTSYSMENU => "sysmnu",
|
||||
win32.HTSIZE => "size",
|
||||
win32.HTMENU => "menu",
|
||||
win32.HTHSCROLL => "hscroll",
|
||||
win32.HTVSCROLL => "vscroll",
|
||||
win32.HTMINBUTTON => "minbtn",
|
||||
win32.HTMAXBUTTON => "max",
|
||||
win32.HTLEFT => "left",
|
||||
win32.HTRIGHT => "right",
|
||||
win32.HTTOP => "top",
|
||||
win32.HTTOPLEFT => "topleft",
|
||||
win32.HTTOPRIGHT => "topright",
|
||||
win32.HTBOTTOM => "bottom",
|
||||
win32.HTBOTTOMLEFT => "botmleft",
|
||||
win32.HTBOTTOMRIGHT => "botmright",
|
||||
win32.HTBORDER => "border",
|
||||
win32.HTCLOSE => "close",
|
||||
win32.HTHELP => "help",
|
||||
else => null,
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue