diff --git a/doc/riverctl.1 b/doc/riverctl.1 index 2a0a523..0fa8dbb 100644 --- a/doc/riverctl.1 +++ b/doc/riverctl.1 @@ -170,9 +170,9 @@ List of valid options: .IP \(bu border_width (non-negative integer) .IP \(bu -border_color_focused (RGB hex code) +border_color_focused (RGB/RGBA hex code) .IP \(bu -border_color_unfocused (RGB hex code) +border_color_unfocused (RGB/RGBA hex code) .IP \(bu outer_padding (non-negative integer) diff --git a/river/Config.zig b/river/Config.zig index 761b078..c0355ba 100644 --- a/river/Config.zig +++ b/river/Config.zig @@ -23,17 +23,16 @@ const c = @import("c.zig"); const Log = @import("log.zig").Log; const Server = @import("Server.zig"); -const Rgb = @import("Rgb.zig"); const Mapping = @import("Mapping.zig"); /// Width of borders in pixels border_width: u32, -/// Color of border of focused window in RGB -border_color_focused: Rgb, +/// Color of border of focused window in RGBA +border_color_focused: [4]f32, -/// Color of border of unfocused window in RGB -border_color_unfocused: Rgb, +/// Color of border of unfocused window in RGBA +border_color_unfocused: [4]f32, /// Amount of view padding in pixels view_padding: u32, @@ -52,8 +51,8 @@ float_filter: std.ArrayList([*:0]const u8), pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { self.border_width = 2; - try self.border_color_focused.parseString("#93A1A1"); // Solarized base1 - try self.border_color_unfocused.parseString("#586E75"); // Solarized base0 + self.border_color_focused = [_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 }; // Solarized base1 + self.border_color_unfocused = [_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0 }; // Solarized base0 self.view_padding = 8; self.outer_padding = 8; diff --git a/river/Control.zig b/river/Control.zig index 3153e31..660268a 100644 --- a/river/Control.zig +++ b/river/Control.zig @@ -126,7 +126,7 @@ fn runCommand( command.Error.Overflow => "value out of bounds", command.Error.InvalidCharacter => "invalid character in argument", command.Error.InvalidDirection => "invalid direction. Must be 'next' or 'previous'", - command.Error.InvalidRgbFormat => "invalid RGB format", + command.Error.InvalidRgba => "invalid color format, must be #RRGGBB or #RRGGBBAA", command.Error.OutOfMemory => "out of memory", command.Error.CommandFailed => unreachable, }, diff --git a/river/Rgb.zig b/river/Rgb.zig deleted file mode 100644 index 57a605d..0000000 --- a/river/Rgb.zig +++ /dev/null @@ -1,45 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Rishabh Das -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -const Self = @This(); - -const std = @import("std"); - -r: u8, -g: u8, -b: u8, - -pub fn parseString(self: *Self, string: []const u8) !void { - if (string[0] != '#' or string.len != 7) return error.InvalidRgbFormat; - - const r = try std.fmt.parseInt(u8, string[1..3], 16); - const g = try std.fmt.parseInt(u8, string[3..5], 16); - const b = try std.fmt.parseInt(u8, string[5..7], 16); - - self.r = r; - self.g = g; - self.b = b; -} - -pub fn getDecimalRgbaArray(self: Self) [4]f32 { - return [4]f32{ - @intToFloat(f32, self.r) / 255.0, - @intToFloat(f32, self.g) / 255.0, - @intToFloat(f32, self.b) / 255.0, - 1.0, - }; -} diff --git a/river/command.zig b/river/command.zig index 5d25cee..512184f 100644 --- a/river/command.zig +++ b/river/command.zig @@ -91,7 +91,7 @@ pub const Error = error{ Overflow, InvalidCharacter, InvalidDirection, - InvalidRgbFormat, + InvalidRgba, UnknownOption, OutOfMemory, CommandFailed, diff --git a/river/command/set_option.zig b/river/command/set_option.zig index ebb4a8b..b3fb110 100644 --- a/river/command/set_option.zig +++ b/river/command/set_option.zig @@ -38,7 +38,7 @@ pub fn setOption( if (args.len < 3) return Error.NotEnoughArguments; if (args.len > 3) return Error.TooManyArguments; - const config = &seat.focused_output.root.server.config; + const config = &seat.input_manager.server.config; // Parse option and value. const option = std.meta.stringToEnum(Option, args[1]) orelse return Error.UnknownOption; @@ -46,11 +46,28 @@ pub fn setOption( // Assign value to option. switch (option) { .border_width => config.border_width = try std.fmt.parseInt(u32, args[2], 10), - .border_color_focused => try config.border_color_focused.parseString(args[2]), - .border_color_unfocused => try config.border_color_unfocused.parseString(args[2]), + .border_color_focused => config.border_color_focused = try parseRgba(args[2]), + .border_color_unfocused => config.border_color_unfocused = try parseRgba(args[2]), .outer_padding => config.outer_padding = try std.fmt.parseInt(u32, args[2], 10), } // 'Refresh' focused output to display the desired changes. seat.focused_output.root.arrange(); } + +/// Parse a color in the format #RRGGBB or #RRGGBBAA +pub fn parseRgba(string: []const u8) ![4]f32 { + if (string[0] != '#' or (string.len != 7 and string.len != 9)) return error.InvalidRgba; + + const r = try std.fmt.parseInt(u8, string[1..3], 16); + const g = try std.fmt.parseInt(u8, string[3..5], 16); + const b = try std.fmt.parseInt(u8, string[5..7], 16); + const a = if (string.len == 9) try std.fmt.parseInt(u8, string[7..9], 16) else 255; + + return [4]f32{ + @intToFloat(f32, r) / 255.0, + @intToFloat(f32, g) / 255.0, + @intToFloat(f32, b) / 255.0, + @intToFloat(f32, a) / 255.0, + }; +} diff --git a/river/render.zig b/river/render.zig index c505091..6414630 100644 --- a/river/render.zig +++ b/river/render.zig @@ -238,11 +238,12 @@ fn renderTexture( } fn renderBorders(output: Output, view: *View, now: *c.timespec) void { + const config = &output.root.server.config; var border: Box = undefined; const color = if (view.focused) - output.root.server.config.border_color_focused.getDecimalRgbaArray() + &output.root.server.config.border_color_focused else - output.root.server.config.border_color_unfocused.getDecimalRgbaArray(); + &output.root.server.config.border_color_unfocused; const border_width = output.root.server.config.border_width; // left and right, covering the corners as well @@ -272,13 +273,13 @@ fn renderBorders(output: Output, view: *View, now: *c.timespec) void { renderRect(output, border, color); } -fn renderRect(output: Output, box: Box, color: [4]f32) void { +fn renderRect(output: Output, box: Box, color: *const [4]f32) void { var wlr_box = box.toWlrBox(); scaleBox(&wlr_box, output.wlr_output.scale); c.wlr_render_rect( output.getRenderer(), &wlr_box, - &color, + color, &output.wlr_output.transform_matrix, ); }