Skip to content
Snippets Groups Projects
Commit 2fbe02f7 authored by Jiří Kalvoda's avatar Jiří Kalvoda
Browse files

Add OnClick

parent 2cbbc7c1
No related branches found
No related tags found
No related merge requests found
...@@ -47,6 +47,17 @@ static class POSIX ...@@ -47,6 +47,17 @@ static class POSIX
public static int SIGUSR1 = 10; public static int SIGUSR1 = 10;
public static int EEXIST = 17; public static int EEXIST = 17;
public static int ERRNO { get => Marshal.GetLastPInvokeError();} public static int ERRNO { get => Marshal.GetLastPInvokeError();}
public static void Bash(string cmd)
{
var process = new Process();
process.StartInfo.FileName = "bash";
process.StartInfo.Arguments = "";
process.StartInfo.RedirectStandardInput = true;
process.Start();
TextWriter stdin = process.StandardInput;
stdin.Write(cmd);
stdin.Close();
}
} }
static class ProcesExtended static class ProcesExtended
...@@ -97,6 +108,33 @@ enum Markup ...@@ -97,6 +108,33 @@ enum Markup
Pango Pango
} }
record Coordinates(
int X,
int Y
);
enum MouseButton
{
Left,
Right,
Middle
}
[Flags]
enum Modifiers
{
Shift=1,
Ctrl=2
}
record ClickEvent(
Coordinates Relative, // relative_x, relative_y
Coordinates Size, // width, height
MouseButton Button,
Coordinates? Absolute = null, // x, y
Coordinates? Output = null, // output_x, output_y
Modifiers Modifiers = 0
);
record Block( record Block(
string Text, string Text,
...@@ -114,7 +152,8 @@ record Block( ...@@ -114,7 +152,8 @@ record Block(
bool Urgent = false, bool Urgent = false,
bool Separator = true, bool Separator = true,
int? SeparatorBlockWidth=null, int? SeparatorBlockWidth=null,
Markup Markup = Markup.None Markup Markup = Markup.None,
Action<ClickEvent>? OnClick=null
); );
...@@ -417,14 +456,82 @@ class StatusBarTerminal: StatusBarPlainText ...@@ -417,14 +456,82 @@ class StatusBarTerminal: StatusBarPlainText
} }
class StatusBarI3: RootStatusBar class StatusBarI3: RootStatusBar
{ {
public StatusBarI3(FileInfo configFile):base(configFile){} Thread? inputThread;
record HistoryElement(
long time_ms,
long id,
IEnumerable<Block> data
);
Queue<HistoryElement> history = new(); // for finding correct lambda in inputThread
int outputCounter = 0;
public StatusBarI3(FileInfo configFile, bool doInput):base(configFile)
{
Console.Error.Flush();
if(doInput)
{
inputThread = new Thread(this.inputThreadFunc);
inputThread.IsBackground = true;
inputThread.Start();
}
}
void inputThreadFunc()
{
Console.ReadLine(); // read "["
while(true)
{
#pragma warning disable 8602
string? line = Console.ReadLine();
if(line == null) throw new Exception("I3bar close input");
if(line[0] == ',') line = line[1..];
JsonObject json = JsonObject.Parse(line).AsObject();
MouseButton button;
int jsonButton = json["button"].AsValue().GetValue<int>();
if(jsonButton == 1) button = MouseButton.Left; else
if(jsonButton == 2) button = MouseButton.Middle; else
if(jsonButton == 3) button = MouseButton.Left; else
break;
var ev = new ClickEvent(
Relative: new Coordinates(json["relative_x"].AsValue().GetValue<int>(), json["relative_y"].AsValue().GetValue<int>()),
Size: new Coordinates(json["height"].AsValue().GetValue<int>(), json["width"].AsValue().GetValue<int>()),
Button: button
);
string name = json["name"].AsValue().GetValue<string>();
int outputId = int.Parse(name.Split(".")[0]);
int blockId = int.Parse(name.Split(".")[1]);
HistoryElement currentBar;
lock(history)
{
while(history.Count > 0 && history.Peek().id < outputId)
history.Dequeue();
if(history.Count <= 0) break;
currentBar = history.Peek();
}
var block = currentBar.data.ElementAt(blockId);
if(block.OnClick != null)
block.OnClick(ev);
#pragma warning restore 8602
}
}
override protected void initOutput(TextWriter w) override protected void initOutput(TextWriter w)
{ {
if(inputThread == null)
w.WriteLine("{\"version\":1}"); w.WriteLine("{\"version\":1}");
else
w.WriteLine("{\"version\":1, \"click_events\": true }");
w.WriteLine("[{}"); w.WriteLine("[{}");
} }
override protected void format(TextWriter w, List<Block> elements) override protected void format(TextWriter w, List<Block> elements)
{ {
if(inputThread != null)
{
lock(history)
{
while(history.Count > 0 && history.Peek().time_ms < Environment.TickCount64 - 1000)
history.Dequeue();
history.Enqueue(new HistoryElement(Environment.TickCount64, outputCounter, elements));
}
}
JsonNode? intStringUnion(int? _int, string? _string) JsonNode? intStringUnion(int? _int, string? _string)
{ {
JsonNode? n = null; JsonNode? n = null;
...@@ -432,7 +539,9 @@ class StatusBarI3: RootStatusBar ...@@ -432,7 +539,9 @@ class StatusBarI3: RootStatusBar
if(_string != null) n = _string; if(_string != null) n = _string;
return n; return n;
} }
int i = 0;
var json = new JsonArray((from e in elements select new JsonObject(){ var json = new JsonArray((from e in elements select new JsonObject(){
["name"] = $"{outputCounter}.{i++}",
["full_text"] = e.Text, ["full_text"] = e.Text,
["short_text"] = e.ShortText, ["short_text"] = e.ShortText,
["color"] = e.Color?.ToHex(), ["color"] = e.Color?.ToHex(),
...@@ -453,6 +562,7 @@ class StatusBarI3: RootStatusBar ...@@ -453,6 +562,7 @@ class StatusBarI3: RootStatusBar
opt.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; opt.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
w.Write(","); w.Write(",");
w.WriteLine(json.ToJsonString(opt)); w.WriteLine(json.ToJsonString(opt));
outputCounter++;
} }
} }
...@@ -504,10 +614,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>."); ...@@ -504,10 +614,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.");
var c_i3 = new Command("i3", "Comunicate with i3bar."); var c_i3 = new Command("i3", "Comunicate with i3bar.");
rootCommand.Add(c_i3); rootCommand.Add(c_i3);
c_i3.SetHandler(async (config) => var c_i3_input = new Option<bool>
{ ("--input", "Read mouse clicks.");
(new StatusBarI3(config)).Run(Console.Out); c_i3_input.AddAlias("-i");
}, configOption); c_i3.Add(c_i3_input);
c_i3.SetHandler(async (config, input) =>
{
(new StatusBarI3(config, input)).Run(Console.Out);
}, configOption, c_i3_input);
rootCommand.Invoke(args); rootCommand.Invoke(args);
return 0; return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment