Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
62bc98b
build: downgrade strawberry-perl
ColdLemonTea Jul 1, 2025
338ab04
fix: zero initialization of bitmapinfo
ColdLemonTea Jul 1, 2025
2dd87d0
chore: scripts for running in standalone process
ColdLemonTea Jul 1, 2025
c8551bd
feat(taskbar): implement taskbar window
ColdLemonTea Jul 1, 2025
09f04a0
feat: taskbar icons
ColdLemonTea Jul 1, 2025
782ad18
feat(taskbar): asyncify icon loading
ColdLemonTea Jul 2, 2025
5e75f9b
refactor: move button widget to ui lib
ColdLemonTea Jul 2, 2025
f322bae
feat(ui): allow initializing button_widget without a text widget
ColdLemonTea Jul 2, 2025
65f049c
feat(taskbar): draw outline
ColdLemonTea Jul 2, 2025
4c65b33
feat(taskbar): customizable animation
ColdLemonTea Jul 2, 2025
e24876c
feat(taskbar): basic control, active indicator
ColdLemonTea Jul 2, 2025
6fb7b1b
fix(taskbar): do not focus on self
ColdLemonTea Jul 2, 2025
d4a603d
feat(taskbar): use exe icon if nothing is found
ColdLemonTea Jul 2, 2025
1dd21ca
fix: tolower exe filename first to make it case-insensitive
ColdLemonTea Jul 3, 2025
88306a5
fix(ui): repaint when unnecessary
ColdLemonTea Jul 3, 2025
08dfc29
fix(ui): dpi scaling in mixed dpi monitors
ColdLemonTea Jul 29, 2025
e17ee11
Merge branch 'master' into master
std-microblock Jul 30, 2025
73ab297
Merge pull request #1 from std-microblock/master
ColdLemonTea Jul 30, 2025
6649c5c
Merge branch 'master' of github-forst:ColdLemonTea/breeze-shell
ColdLemonTea Jul 30, 2025
9312c46
feat(taskbar): implement windows btn
ColdLemonTea Aug 7, 2025
4f507ee
refactor: separate background of menu to background_widget
ColdLemonTea Aug 8, 2025
ce44954
refactor: file structure
ColdLemonTea Aug 8, 2025
f3fe8e1
refactor: use absolute path for all includes
ColdLemonTea Aug 8, 2025
e0185f9
refactor(taskbar): improve visuals of current impl
ColdLemonTea Aug 8, 2025
42e5369
refactor(taskbar): move implementations to inline
ColdLemonTea Aug 8, 2025
99c81ab
feat(taskbar): update window when window created or closed
ColdLemonTea Aug 8, 2025
7841bd5
feat(taskbar): animate when window list changes
ColdLemonTea Aug 9, 2025
55f0276
refactor: migrate embed script to typescript project
ColdLemonTea Aug 9, 2025
156ef22
feat(shell): allow script to create window
ColdLemonTea Aug 9, 2025
c918b1c
v0.0.1
ColdLemonTea Aug 9, 2025
7daa5c9
v0.0.2
ColdLemonTea Aug 9, 2025
906f86e
v0.0.3
ColdLemonTea Aug 9, 2025
6d9884c
v0.0.4
ColdLemonTea Aug 9, 2025
df3265c
v0.0.5
ColdLemonTea Aug 9, 2025
599343a
v0.0.6
ColdLemonTea Aug 9, 2025
23853aa
feat(shell): allow scripts to open separate windows
ColdLemonTea Aug 9, 2025
19735c7
fix(script): minify
ColdLemonTea Aug 9, 2025
076ed88
feat(ui): support spacer
ColdLemonTea Aug 9, 2025
df24b42
feat(taskbar): clock and desktop widget
ColdLemonTea Aug 9, 2025
bc97b5b
v0.0.7
ColdLemonTea Aug 9, 2025
be6cc24
v0.0.8
ColdLemonTea Aug 9, 2025
ed6b90e
v0.0.9
ColdLemonTea Aug 9, 2025
1d29f21
feat: support animations for js widgets
ColdLemonTea Aug 9, 2025
56757ab
v0.0.10
ColdLemonTea Aug 9, 2025
b7b6808
feat: support non auto sizing widgets for js
ColdLemonTea Aug 9, 2025
6a8fae5
v0.0.11
ColdLemonTea Aug 9, 2025
fdd7142
feat: js image widget
ColdLemonTea Aug 9, 2025
80909aa
refactor: move xywh to base jswidget
ColdLemonTea Aug 9, 2025
02cc7dc
feat: implement image widget
ColdLemonTea Aug 9, 2025
b34c119
feat: image widget for js and api fixes
ColdLemonTea Aug 9, 2025
33e4e1d
refactor: use independent breeze-ui library
ColdLemonTea Sep 14, 2025
615586e
build: update blook library
ColdLemonTea Sep 14, 2025
9065741
build: update blook library
ColdLemonTea Sep 14, 2025
7457c11
fix: update module and moduleResolution to node16 in tsconfig
ColdLemonTea Sep 14, 2025
1df3de2
fix: add exception for C++ in project settings
ColdLemonTea Sep 14, 2025
7ee6e9d
fix: update blook
ColdLemonTea Sep 14, 2025
573055c
fix: update blook version and clean up dependencies
ColdLemonTea Sep 14, 2025
b321ca7
fix: reset item widget widths in menu update
ColdLemonTea Sep 14, 2025
b9db5fe
Merge branch 'master' into master
std-microblock Oct 3, 2025
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
5 changes: 5 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
Language: Cpp
AccessModifierOffset: -4
IndentWidth: 4
...
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "blook"]
path = dependencies/blook
url = https://github.com/std-microblock/blook
[submodule "dependencies/glfw"]
path = dependencies/glfw
url = https://github.com/breeze-shell/glfw
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The config menu of breeze-shell can be found as you open your `Data Folder` and

## Lightweight & Fast

Breeze uses breeze-ui, which is implemented to be a cross-platform, simple,
Breeze uses breeze_ui, which is implemented to be a cross-platform, simple,
animation-friendly and fast ui library for modern C++, with the support of both
NanoVG and ThorVG render context. This allowed Breeze to have a delicated user
interface in ~2MiB.
Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ shell.menu_controller.add_menu_listener((e) => {

## 轻量高速

Breeze 基于自研 breeze-ui 框架实现,这是一个跨平台、简洁优雅、动画友好的现代 C++ UI 库,支持 NanoVG 和 ThorVG 双渲染后端。这使得 Breeze 能在约 2MB 的体积下实现精致的视觉体验。
Breeze 基于自研 breeze_ui 框架实现,这是一个跨平台、简洁优雅、动画友好的现代 C++ UI 库,支持 NanoVG 和 ThorVG 双渲染后端。这使得 Breeze 能在约 2MB 的体积下实现精致的视觉体验。

# 立即体验

Expand Down
1 change: 0 additions & 1 deletion dependencies/blook
Submodule blook deleted from 034579
33 changes: 15 additions & 18 deletions dependencies/blook.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package("blook")
add_deps("cmake")
add_syslinks("advapi32")
set_sourcedir(path.join(os.scriptdir(), "blook"))
on_install(function (package)
local fcdir = package:cachedir() .. "/fetchcontent"
import("package.tools.cmake").install(package, {
"-DCMAKE_INSTALL_PREFIX=" .. package:installdir(),
"-DCMAKE_PREFIX_PATH=" .. package:installdir(),
"-DFETCHCONTENT_QUIET=OFF",
"-DFETCHCONTENT_BASE_DIR=" .. fcdir,
})

os.cp("include/blook/**", package:installdir("include/blook/"))
os.cp("external/zasm/zasm/include/**", package:installdir("include/zasm/"))
os.cp(fcdir .. "/zydis-src/dependencies/zycore/include/**", package:installdir("include/zycore/"))
os.cp(package:buildir() .. "/blook.lib", package:installdir("lib"))
os.cp(package:buildir() .. "/external/zasm/zasm.lib", package:installdir("lib"))
set_description("A modern C++ library for hacking.")
set_license("GPL-3.0")

add_urls("https://github.com/std-microblock/blook.git")

add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})

if is_plat("windows") then
add_syslinks("advapi32")
end

add_deps("zasm c239a78b51c1b0060296193174d78b802f02a618")

on_install("windows", function (package)
import("package.tools.xmake").install(package, {}, {target = "blook"})
end)
package_end()
18 changes: 18 additions & 0 deletions dependencies/breeze-ui.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package("breeze-glfw")
set_base("glfw")
set_urls("https://github.com/breeze-shell/glfw.git")
add_versions("latest", "master")

package("breeze-ui")
add_urls("https://github.com/std-microblock/breeze-ui.git")
add_versions("20250815.6", "d4d279aa7c381d70d164de5a45454a71f3260165")
add_deps("breeze-glfw", "nanovg", "glad", "nanosvg")
add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = true})

if is_plat("windows") then
add_syslinks("dwmapi", "shcore")
end

on_install("windows", function (package)
import("package.tools.xmake").install(package, {}, {target = "breeze_ui"})
end)
6 changes: 0 additions & 6 deletions dependencies/glfw.lua

This file was deleted.

26 changes: 1 addition & 25 deletions scripts/additional-types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,4 @@ declare module "mshell" {
type intptr_t = number;
type uintptr_t = number;
type ssize_t = number;
}

// helper to access field based on dot path
type FieldPath<T, K extends string> = K extends keyof T ? T[K] : K extends `${infer K1}.${infer K2}` ? K1 extends keyof T ? FieldPath<T[K1], K2> : never : never;

declare function plugin<T = object>(import_meta: { url: string }, default_config?: T): {
i18n: {
define(lang: string, data: { [key: string]: string }): void;
t(key: string): string;
};
set_on_menu(callback: (m:
import('mshell').menu_controller
) => void): void;
config_directory: string;
config: {
read_config(): void;
write_config(): void;
get<K extends string>(key: K): FieldPath<T, K>;
set<K extends string>(key: K, value: FieldPath<T, K>): void;
all(): T;
};
log(...args: any[]): void;
};

declare type ShellPluginHelper = ReturnType<typeof plugin>;
}
6 changes: 6 additions & 0 deletions scripts/rebuild_taskbar.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$pids = (Get-WmiObject Win32_Process -Filter "name = 'rundll32.exe'" | where { $_.CommandLine -like 'taskbar' }).ProcessId
foreach ($pidx in $pids) {
Stop-Process -Id $pidx -Force
}

xmake r --yes shell taskbar
145 changes: 11 additions & 134 deletions src/inject/inject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include <thread>
#include <vector>

#include "animator.h"
#include "ui.h"
#include "widget.h"
#include "breeze_ui/animator.h"
#include "breeze_ui/ui.h"
#include "breeze_ui/widget.h"

static unsigned char g_icon_png[] = {
#include "icon-small.png.h"
Expand Down Expand Up @@ -233,130 +233,7 @@ struct inject_ui_title : public ui::widget_flex {
}
};

struct button_widget : public ui::padding_widget {
button_widget(const std::string &button_text) {
auto text = emplace_child<ui::text_widget>();
text->text = button_text;
text->font_size = 14;
text->color.reset_to({1, 1, 1, 0.95});

padding_bottom->reset_to(10);
padding_top->reset_to(10);
padding_left->reset_to(22);
padding_right->reset_to(20);

border_top.reset_to({1, 1, 1, 0.12});
border_right.reset_to({1, 1, 1, 0.04});
border_bottom.reset_to({1, 1, 1, 0.02});
border_left.reset_to({1, 1, 1, 0.04});
}

ui::animated_color border_top = {this, 0, 0, 0, 0},
border_right = {this, 0, 0, 0, 0},
border_bottom = {this, 0, 0, 0, 0},
border_left = {this, 0, 0, 0, 0};

void render(ui::nanovg_context ctx) override {

ctx.fillColor(bg_color);
ctx.fillRoundedRect(*x, *y, *width, *height, 6);

float bw = 1.0f;

float radius = 6.0f;
// 4 edges
ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_top);
ctx.moveTo(*x + radius, *y + bw / 2);
ctx.lineTo(*x + *width - radius, *y + bw / 2);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_right);
ctx.moveTo(*x + *width - bw / 2, *y + radius);
ctx.lineTo(*x + *width - bw / 2, *y + *height - radius);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_bottom);
ctx.moveTo(*x + *width - radius, *y + *height - bw / 2);
ctx.lineTo(*x + radius, *y + *height - bw / 2);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_left);
ctx.moveTo(*x + bw / 2, *y + *height - radius);
ctx.lineTo(*x + bw / 2, *y + radius);
ctx.stroke();

// 4 corners
float cr = radius - bw / 2;
ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_right.blend(border_top));
ctx.moveTo(*x + *width - radius, *y + bw / 2);
ctx.arcTo(*x + *width - bw / 2, *y + bw / 2, *x + *width - bw / 2,
*y + radius, cr);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_bottom.blend(border_right));
ctx.moveTo(*x + *width - bw / 2, *y + *height - radius);
ctx.arcTo(*x + *width - bw / 2, *y + *height - bw / 2, *x + *width - radius,
*y + *height - bw / 2, cr);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_left.blend(border_bottom));
ctx.moveTo(*x + radius, *y + *height - bw / 2);
ctx.arcTo(*x + bw / 2, *y + *height - bw / 2, *x + bw / 2,
*y + *height - radius, cr);
ctx.stroke();

ctx.beginPath();
ctx.strokeWidth(bw);
ctx.strokeColor(border_top.blend(border_left));
ctx.moveTo(*x + bw / 2, *y + radius);
ctx.arcTo(*x + bw / 2, *y + bw / 2, *x + radius, *y + bw / 2, cr);
ctx.stroke();

padding_widget::render(ctx);
}

ui::animated_color bg_color = {this, 40 / 255.f, 40 / 255.f, 40 / 255.f, 0.6};

virtual void on_click() = 0;

virtual void update_colors(bool is_active, bool is_hovered) {
if (is_active) {
bg_color.animate_to({0.3, 0.3, 0.3, 0.7});
} else if (is_hovered) {
bg_color.animate_to({0.35, 0.35, 0.35, 0.7});
} else {
bg_color.animate_to({0.3, 0.3, 0.3, 0.6});
}
}
ui::update_context *ctx;
void update(ui::update_context &ctx) override {
padding_widget::update(ctx);

if (ctx.mouse_clicked_on_hit(this)) {
this->ctx = &ctx;
on_click();
this->ctx = nullptr;
}

update_colors(ctx.mouse_down_on(this), ctx.hovered(this));
}
};

struct start_when_startup_switch : public button_widget {
struct start_when_startup_switch : public ui::button_widget {
bool start_when_startup = false;

static bool check_startup() {
Expand Down Expand Up @@ -442,7 +319,7 @@ void restart_explorer() {
}
}

struct restart_explorer_btn : public button_widget {
struct restart_explorer_btn : public ui::button_widget {
restart_explorer_btn()
: button_widget(english ? "Restart explorer" : "重启资源管理器") {}

Expand All @@ -452,7 +329,7 @@ struct restart_explorer_btn : public button_widget {
};

struct injector_ui_main;
struct switch_lang_btn : public button_widget {
struct switch_lang_btn : public ui::button_widget {
switch_lang_btn() : button_widget(english ? "中文" : "English") {}

void on_click() override {
Expand Down Expand Up @@ -485,7 +362,7 @@ void InjectAllConsistent() {
}
}

struct inject_all_switch : public button_widget {
struct inject_all_switch : public ui::button_widget {
bool injecting_all = false;
std::chrono::steady_clock::time_point last_check;
inject_all_switch() : button_widget(english ? "Inject All" : "全局注入") {
Expand Down Expand Up @@ -541,7 +418,7 @@ struct inject_all_switch : public button_widget {
}
};

struct inject_once_switch : public button_widget {
struct inject_once_switch : public ui::button_widget {
inject_once_switch() : button_widget(english ? "Inject Once" : "注入一次") {}

void on_click() override {
Expand All @@ -552,7 +429,7 @@ struct inject_once_switch : public button_widget {
}
};

struct data_dir_btn : public button_widget {
struct data_dir_btn : public ui::button_widget {
data_dir_btn() : button_widget(english ? "Data Folder" : "数据目录") {}

void on_click() override {
Expand Down Expand Up @@ -723,13 +600,13 @@ void ShowCrashDialog() {
btn_container->horizontal = true;
btn_container->gap = 10;

class close_button : public button_widget {
class close_button : public ui::button_widget {
public:
close_button() : button_widget(english ? "Close" : "关闭") {}
void on_click() override { exit(1); }
};

class github_button : public button_widget {
class github_button : public ui::button_widget {
public:
github_button() : button_widget(english ? "Check GitHub" : "查看 GitHub") {}
void on_click() override {
Expand Down
14 changes: 14 additions & 0 deletions src/shell/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,18 @@ std::string config::dump_config() { return rfl::json::write(*config::current); }
std::filesystem::path config::default_mono_font() {
return std::filesystem::path(env("WINDIR").value()) / "Fonts" / "consola.ttf";
}
void config::apply_fonts_to_nvg(NVGcontext *nvg) {
nvgCreateFont(nvg, "main", font_path_main.string().c_str());
nvgCreateFont(nvg, "fallback", font_path_fallback.string().c_str());
nvgCreateFont(nvg, "monospace", font_path_monospace.string().c_str());
nvgAddFallbackFont(nvg, "main", "fallback");
nvgAddFallbackFont(nvg, "monospace", "main");
}
void config::animated_float_conf::apply_to(ui::animated_color &anim,
float delay) {
apply_to(anim.r, delay);
apply_to(anim.g, delay);
apply_to(anim.b, delay);
apply_to(anim.a, delay);
}
} // namespace mb_shell
Loading
Loading