diff --git a/.gitignore b/.gitignore index ea8c4bf..de68c24 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/Output \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 7bb8e67..53417c8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,15 +7,15 @@ { "type": "lldb", "request": "launch", - "name": "Debug 'log_history'", + "name": "Debug executable 'm42_workspace'", "cargo": { "args": [ "build", - "--bin=workspace_log_history", - "--package=workspace" + "--bin=m42_workspace", + "--package=m42_workspace" ], "filter": { - "name": "workspace_log_history", + "name": "m42_workspace", "kind": "bin" } }, @@ -25,34 +25,16 @@ { "type": "lldb", "request": "launch", - "name": "Debug executable 'workspace'", - "cargo": { - "args": [ - "build", - "--bin=workspace", - "--package=workspace" - ], - "filter": { - "name": "workspace", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in executable 'workspace'", + "name": "Debug unit tests in executable 'm42_workspace'", "cargo": { "args": [ "test", "--no-run", - "--bin=workspace", - "--package=workspace" + "--bin=m42_workspace", + "--package=m42_workspace" ], "filter": { - "name": "workspace", + "name": "m42_workspace", "kind": "bin" } }, diff --git a/Cargo.lock b/Cargo.lock index ed4244d..b6531d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2082,6 +2082,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "m42_workspace" +version = "0.1.0" +dependencies = [ + "anyhow", + "image 0.25.2", + "indexmap", + "known-folders", + "notan", + "rsn", + "serde", + "tao", + "tokio", + "tray-icon", + "winresource", +] + [[package]] name = "mach2" version = "0.4.2" @@ -3921,7 +3938,7 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml", + "toml 0.8.2", "version-compare", ] @@ -4127,6 +4144,18 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + [[package]] name = "toml" version = "0.8.2" @@ -4155,6 +4184,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow 0.5.40", ] @@ -4904,19 +4935,13 @@ dependencies = [ ] [[package]] -name = "workspace" -version = "0.1.0" +name = "winresource" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e2aaaf8cfa92078c0c0375423d631f82f2f57979c2884fdd5f604a11e45329" dependencies = [ - "anyhow", - "image 0.25.2", - "indexmap", - "known-folders", - "notan", - "rsn", - "serde", - "tao", - "tokio", - "tray-icon", + "toml 0.7.8", + "version_check", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 81bbeba..af5af43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,17 @@ [package] -name = "workspace" +name = "m42_workspace" version = "0.1.0" edition = "2021" +default-run = "m42_workspace" + +[[bin]] +name = "m42_workspace" +path = "src/main.rs" + +[[bin]] +name = "m42_log_history" +path = "src/bin/log_history.rs" + [dependencies] tray-icon = "0.19.0" @@ -24,3 +34,6 @@ notan = { version = "0.12.1", features = [ "text", ] } tao = "0.30.3" + +[build-dependencies] +winresource = "0.1.17" diff --git a/icon.ico b/assets/icon.ico similarity index 100% rename from icon.ico rename to assets/icon.ico diff --git a/icon.png b/assets/icon.png similarity index 100% rename from icon.png rename to assets/icon.png diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..29df986 --- /dev/null +++ b/build.rs @@ -0,0 +1,14 @@ +use { + std::{env, io}, + winresource::WindowsResource, +}; + +fn main() -> io::Result<()> { + if env::var_os("CARGO_CFG_WINDOWS").is_some() { + WindowsResource::new() + // This path can be absolute, or relative to your crate root. + .set_icon("assets/icon.ico") + .compile()?; + } + Ok(()) +} diff --git a/setup.iss b/setup.iss new file mode 100644 index 0000000..d018ee5 --- /dev/null +++ b/setup.iss @@ -0,0 +1,58 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "Workspace" +#define MyAppVersion "0.1" +#define MyAppPublisher "-" +#define MyAppURL "-" +#define MyAppExeName "m42_workspace.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{3B478709-0F8E-4715-BE35-1F76B4FDA134} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName=c:\m_workspace\{#MyAppName} +DisableDirPage=yes +; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run +; on anything but x64 and Windows 11 on Arm. +ArchitecturesAllowed=x64compatible +; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the +; install be done in "64-bit mode" on x64 or Windows 11 on Arm, +; meaning it should use the native 64-bit Program Files directory and +; the 64-bit view of the registry. +ArchitecturesInstallIn64BitMode=x64compatible +DisableProgramGroupPage=yes +; Remove the following line to run in administrative install mode (install for all users.) +PrivilegesRequired=lowest +OutputBaseFilename=m42_workspace +SetupIconFile=assets/icon.ico +Compression=lzma +SolidCompression=yes +WizardStyle=modern + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "target\release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "target\release\m42_log_history.exe"; DestDir: "{app}"; Flags: ignoreversion +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon +Name: "{userstartup}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/src/bin/workspace_log_history.rs b/src/bin/log_history.rs similarity index 92% rename from src/bin/workspace_log_history.rs rename to src/bin/log_history.rs index 9161284..099f553 100644 --- a/src/bin/workspace_log_history.rs +++ b/src/bin/log_history.rs @@ -1,3 +1,8 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + use std::str::FromStr; use std::{path::PathBuf, process::Command}; @@ -38,6 +43,8 @@ impl State { fn main() -> Result<(), String> { let win = WindowConfig::new() .set_vsync(false) + .set_title("Log History") + .set_resizable(true) .set_lazy_loop(true) .set_transparent(true) .set_high_dpi(true); @@ -76,10 +83,11 @@ fn event(_app: &mut App, _assets: &mut Assets, state: &mut State, evt: Event) { } } -fn draw(_app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut State) { +fn draw(app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut State) { let mut output = plugins.egui(|ctx| { - egui::SidePanel::left("side_panel").show(ctx, |ui| { - ui.collapsing("Logs", |ui| { + egui::SidePanel::left("side_panel") + .exact_width(app.window().width() as f32) + .show(ctx, |ui| { egui::ScrollArea::vertical().show(ui, |ui| { let mut to_swap = None; let mut to_delete = None; @@ -118,8 +126,7 @@ fn draw(_app: &mut App, gfx: &mut Graphics, plugins: &mut Plugins, state: &mut S state.save(); } }) - }) - }); + }); }); output.clear_color(Color::BLACK); diff --git a/src/main.rs b/src/main.rs index 8672b55..21f2a10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] #![allow(dead_code)] #![allow(unused_imports)] @@ -16,6 +20,16 @@ use tray_icon::{ }; fn main() { + let log_history_exe = std::env::current_exe() + .ok() + .and_then(|exe| exe.parent().map(|p| p.to_path_buf())) + .map(|exe| exe.join("m42_log_history.exe")) + .unwrap_or_else(|| PathBuf::from("m42_log_history.exe")); + + if !log_history_exe.exists() { + panic!("Could not find exe: {:#?}", log_history_exe); + } + let event_loop = EventLoop::new(); let mut window = Some( @@ -37,14 +51,12 @@ fn main() { ); if let tao::event::Event::NewEvents(tao::event::StartCause::Init) = event { - let path = concat!(env!("CARGO_MANIFEST_DIR"), "/icon.png"); - let tray_menu = Menu::new(); tray_menu .append_items(&[&log_history_i, &PredefinedMenuItem::separator(), &quit_i]) .unwrap(); - let icon = load_icon(std::path::Path::new(path)); + let icon = load_icon(include_bytes!("../assets/icon.png")); tray_icon = Some( TrayIconBuilder::new() @@ -99,11 +111,11 @@ fn main() { match &mut log_history { Some(log_history) => { if let Ok(Some(_)) = log_history.try_wait() { - *log_history = Command::new("workspace_log_history").spawn().unwrap(); + *log_history = Command::new(&log_history_exe).spawn().unwrap(); } } None => { - log_history = Some(Command::new("workspace_log_history").spawn().unwrap()); + log_history = Some(Command::new(&log_history_exe).spawn().unwrap()); } } } @@ -111,9 +123,9 @@ fn main() { }); } -fn load_icon(path: &std::path::Path) -> tray_icon::Icon { +fn load_icon(img: &[u8]) -> tray_icon::Icon { let (icon_rgba, icon_width, icon_height) = { - let image = image::open(path) + let image = image::load_from_memory(img) .expect("Failed to open icon path") .into_rgba8(); let (width, height) = image.dimensions();