Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ wayland/*.helper.go
__debug_bin*
term.everything
term.everything❗mmulet.com-dont_forget_to_chmod_+x_this_file
result
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ protocols_files := $(shell find ./wayland/generate)

xml_protocols := $(shell find ./wayland/generate -name "*.xml")

generated_protocols := $(patsubst ./wayland/generate/resources/%,./wayland/protocols/%.go,$(xml_protocols))
generated_protocols := $(patsubst ./wayland/generate/resources/%, ./wayland/protocols/%.go, $(xml_protocols))

generated_helpers := $(patsubst ./wayland/generate/resources/%,./wayland/%.helper.go,$(xml_protocols))
generated_helpers := $(patsubst ./wayland/generate/resources/%, ./wayland/%.helper.go, $(xml_protocols))

build: $(generated_protocols) $(generated_helpers) $(bin_name)

Expand All @@ -29,4 +29,4 @@ clean:
rm __debug_bin* 2>/dev/null || true
if [ -z "$$MULTI_PLATFORM" ]; then rm -rf ./dist 2>/dev/null || true; fi
rm ./wayland/protocols/*.xml.go 2>/dev/null || true
rm ./wayland/*.helper.go 2>/dev/null || true
rm ./wayland/*.helper.go 2>/dev/null || true
7 changes: 3 additions & 4 deletions distribute.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env sh

# This script builds a distributable AppImage
# of the term.everything application using Podman.
Expand All @@ -15,7 +15,7 @@ get_distro() {
else
DISTRO="unknown"
fi

case $DISTRO in
ubuntu|debian)
echo "sudo apt update && sudo apt install -y "
Expand Down Expand Up @@ -51,7 +51,7 @@ if ! command -v podman >/dev/null 2>&1; then
echo "Please install podman to proceed, it's literally all you need. Don't even need attention. Just podman. Just get podman. What are you waiting for? Stop reading this and install podman."
exit 1
fi

fi

if [ -z "${PLATFORM+x}" ]; then
Expand All @@ -66,4 +66,3 @@ $PODMAN run \
--volume .:/home/mount \
--rm alpine:latest /bin/sh /home/mount/resources/alpineCompile.sh && \
echo "Output is ./dist/$PLATFORM/static/$APP_NAME"

27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
description = "Run any GUI app in the terminal";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs =
{
self,
nixpkgs,
...
}:
let
allSystems = [
"x86_64-linux"
"aarch64-linux"
# "x86_64-darwin"
# "aarch64-darwin"
];
forAllSystems =
f:
nixpkgs.lib.genAttrs allSystems (
system:
f {
pkgs = import nixpkgs { inherit system; };
}
);
in
{
packages = forAllSystems (
{ pkgs }:
{
default = pkgs.buildGoModule rec {
pname = "term-everything";
name = pname;
version = "0.7.8";
subPackages = [ "." ];
src = ./.;
vendorHash = null;
nativeBuildInputs = with pkgs; [
pkg-config
];
buildInputs = with pkgs; [
glib
chafa
];
preBuild = ''
go generate ./wayland
'';
postInstall = ''
# rm $out/bin/generate
mv $out/bin/term.everything $out/bin/${name}
'';
};
}
);
};
}
51 changes: 40 additions & 11 deletions termeverything/MainLoop.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,38 @@ import (

func MainLoop() {
args := ParseArgs()
SetVirtualMonitorSize(args.VirtualMonitorSize)
var logger = newLogger(args.DebugLog, nil, args.Verbose)
logger.logVerbose(`
arguments:
WaylandDisplayNameArg=%v
SupportOldApps=%v
Xwayland=%v
XwaylandWM=%v
Shell=%v
HideStatusBar=%v
VirtualMonitorSize=%v
DebugLog=%v
ReverseScroll=%v
MaxFrameRate=%v
Positionals=%v
Verbose=%v`,
args.WaylandDisplayNameArg,
args.SupportOldApps,
args.Xwayland,
args.XwaylandWM,
args.Shell,
args.HideStatusBar,
args.VirtualMonitorSize,
args.DebugLog,
args.ReverseScroll,
args.MaxFrameRate,
args.Positionals,
args.Verbose)
logger.checkFatalErr(SetVirtualMonitorSize(args.VirtualMonitorSize))

listener, err := wayland.MakeSocketListener(&args)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create socket listener: %v\n", err)
os.Exit(1)
logger.logFatal("Failed to create socket listener: %v", err)
}

displaySize := wayland.Size{
Expand Down Expand Up @@ -56,7 +83,7 @@ func MainLoop() {
cmdStr := strings.Join(args.Positionals, " ")
shell := args.Shell
cmd := exec.Command(shell, "-c", cmdStr)

logger.logVerbose("command: %v", cmd)
baseEnv := os.Environ()
filtered := make([]string, 0, len(baseEnv))
for _, e := range baseEnv {
Expand All @@ -79,13 +106,15 @@ func MainLoop() {
// cmd.Stderr = os.Stderr
// cmd.Stdin = os.Stdin

if err := cmd.Start(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to start command: %v\n", err)
} else {
go func() {
_ = cmd.Wait()
}()
}
result := make(chan error)
go func(ret chan error) {
output, err := cmd.CombinedOutput()
if err != nil {
ret <- fmt.Errorf("command failed to run %v; returncode: %v\nstdout/err: %v", cmd, err, string(output))
}
}(result)
err := <-result
logger.checkFatalErr(err)
}

<-done
Expand Down
5 changes: 3 additions & 2 deletions termeverything/ParseArgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type CommandLineArgs struct {
ReverseScroll bool
MaxFrameRate string
Positionals []string
Verbose bool
}

func (args *CommandLineArgs) WaylandDisplayName() string {
Expand All @@ -41,7 +42,7 @@ func ParseArgs() CommandLineArgs {
flag.BoolVar(&args.SupportOldApps, "support-old-apps", false, "")
flag.StringVar(&args.Xwayland, "xwayland", "", "")
flag.StringVar(&args.XwaylandWM, "xwayland-wm", "", "")
flag.StringVar(&args.Shell, "shell", "/bin/bash", "")
flag.StringVar(&args.Shell, "shell", "/bin/sh", "")
flag.BoolVar(&args.HideStatusBar, "hide-status-bar", false, "")
flag.StringVar(&args.VirtualMonitorSize, "virtual-monitor-size", "", "")
versionFlag := flag.Bool("version", false, "")
Expand All @@ -51,7 +52,7 @@ func ParseArgs() CommandLineArgs {
licensesFlag := flag.Bool("licenses", false, "")
flag.BoolVar(&args.ReverseScroll, "reverse-scroll", false, "")
flag.StringVar(&args.MaxFrameRate, "max-frame-rate", "", "")

flag.BoolVar(&args.Verbose, "verbose", false, "")
flag.Parse()

if *versionFlag {
Expand Down
36 changes: 23 additions & 13 deletions termeverything/SetVirtualMonitorSize.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,42 @@ package termeverything

import (
"fmt"
"os"
"strconv"
"strings"

"github.com/mmulet/term.everything/wayland"
)

func SetVirtualMonitorSize(newVirtualMonitorSize string) {
func SetVirtualMonitorSize(newVirtualMonitorSize string) error {
mkError := func(msg string, a ...any) error {
errorMessage := fmt.Sprintf("Invalid virtual monitor size %s, expected <width>x<height>", newVirtualMonitorSize)
return fmt.Errorf("%v; %v", errorMessage, fmt.Sprintf(msg, a...))
}

if newVirtualMonitorSize == "" {
return
return nil
}
parts := strings.Split(newVirtualMonitorSize, "x")
if len(parts) != 2 {
fmt.Fprintf(os.Stderr, "Invalid virtual monitor size %s, expected <width>x<height>\n", newVirtualMonitorSize)
os.Exit(1)
return mkError("found less than 2 dimensions %v", parts)
}
rawWidth, rawHeight := parts[0], parts[1]
width, widthErr := strconv.Atoi(rawWidth)
height, heightErr := strconv.Atoi(rawHeight)
// using the actual error strings are too verbose so just printing the raw value
if widthErr != nil {
return mkError("invalid width %v; must be an integer", rawWidth)
}
if heightErr != nil {
return mkError("invalid height %v; must be an integer", rawHeight)
}
width, err1 := strconv.Atoi(parts[0])
height, err2 := strconv.Atoi(parts[1])
if err1 != nil || err2 != nil {
fmt.Fprintf(os.Stderr, "Invalid virtual monitor size %s, expected <width>x<height>\n", newVirtualMonitorSize)
os.Exit(1)
if width <= 0 {
return mkError("invalid width %v; must be greater than zero", width)
}
if width <= 0 || height <= 0 {
fmt.Fprintf(os.Stderr, "Invalid virtual monitor size %s, expected <width>x<height>\n", newVirtualMonitorSize)
os.Exit(1)
if height <= 0 {
return mkError("invalid height %v; must be greater than zero", height)
}
wayland.VirtualMonitorSize.Width = wayland.Pixels(width)
wayland.VirtualMonitorSize.Height = wayland.Pixels(height)
return nil
}
96 changes: 96 additions & 0 deletions termeverything/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// // error logging
package termeverything

import (
"fmt"
"os"
)

const DEFAULT_DEBUG_FILE string = "debug.log"

type Logger struct {
useDebugFile bool
debugFile *os.File
verbose bool
}

func newLogger(useDebugFile bool, debugFile *string, verbose bool) Logger {
if useDebugFile {
if debugFile == nil || *debugFile == "" {
var t = DEFAULT_DEBUG_FILE // disgusting
debugFile = &t
}
var file, err = os.Create(*debugFile)
if err != nil {
fmt.Print(formatError("failed to open debug file: %v", err))
os.Exit(1)
}
return Logger{useDebugFile, file, verbose}
} else {
return Logger{useDebugFile, nil, verbose}
}
}

// check used for functions that return complete errors
func (l Logger) checkErr(err error) {
if err != nil {
l.log("%v", err.Error())
}
}

func (l Logger) checkFatalErr(err error) {
if err != nil {
l.logFatal("%v", err.Error())
}
}

// log used for errors which need to be formatted
func (l Logger) logFatal(msg string, a ...any) {
l.log(msg, a...)
l.close()
os.Exit(1)
}
func (l Logger) logVerbose(msg string, a ...any) {
if l.verbose {
l._log(fmt.Sprintf("Verbose: %v\n", fmt.Sprintf(msg, a...)))
}
}

// log error on stderr or DEBUG_FILE if useDebugFile automatically prepends Error: and appends \n
// unsure if to hard crash on error logging failures, or if stderr is even accessible in term.everything?
func (l Logger) log(msg string, a ...any) {
l._log(formatError(msg, a...))
}

func (l Logger) close() {
if l.debugFile != nil {
l.debugFile.Close()
}
}

func (l Logger) _log(s string) {
if l.useDebugFile {
if l.debugFile == nil {
// fmt.Println(formatError(""))
printFormatError("debug file is \"nil\", this should be impossible") // should be unreachable but who knows!
os.Exit(1)
} else {
var _, err = l.debugFile.WriteString(s)
if err != nil {
printFormatError("failed to write to debug file %v", err)
// os.Exit(1)
}
}
} else {
printStderr("%v", s)
}
}
func formatError(msg string, a ...any) string {
return "Error: " + fmt.Sprintf(msg, a...) + "\n"
}
func printStderr(msg string, a ...any) {
fmt.Fprintf(os.Stderr, msg, a...)
}
func printFormatError(msg string, a ...any) {
printStderr("%v", formatError(msg, a...))
}
Loading