44#include " Windows.h"
55#include " menu_widget.h"
66
7+ #include " breeze_ui/ui.h"
78#include " shell/entry.h"
89#include " shell/logger.h"
910#include " shell/script/binding_types.hpp"
10- #include " breeze_ui/ui.h"
1111#include < mutex>
1212#include < thread>
1313
14+
1415namespace mb_shell {
1516std::optional<menu_render *> menu_render::current{};
16- menu_render menu_render::create (int x, int y, menu menu) {
17- if (auto res = ui::render_target::init_global (); !res) {
18- MessageBoxW (NULL , L" Failed to initialize global render target" , L" Error" ,
19- MB_ICONERROR);
20- return {nullptr , std::nullopt };
21- }
22-
23- static auto rt = []() {
24- static window_proc_hook glfw_proc_hook;
25- auto rt = std::make_shared<ui::render_target>();
26- rt->transparent = true ;
27- rt->no_activate = true ;
28- rt->capture_all_input = true ;
29- rt->decorated = false ;
30- rt->topmost = true ;
31- rt->vsync = config::current->context_menu .vsync ;
32-
33- if (config::current->avoid_resize_ui ) {
34- rt->width = 3840 ;
35- rt->height = 2159 ;
17+ menu_render menu_render::create (int x, int y, menu menu, bool run_js) {
18+ if (auto res = ui::render_target::init_global (); !res) {
19+ MessageBoxW (NULL , L" Failed to initialize global render target" ,
20+ L" Error" , MB_ICONERROR);
21+ return {nullptr , std::nullopt };
3622 }
3723
38- if (auto res = rt->init (); !res) {
39- MessageBoxW (NULL , L" Failed to initialize render target" , L" Error" ,
40- MB_ICONERROR);
24+ static auto rt = []() {
25+ static window_proc_hook glfw_proc_hook;
26+ auto rt = std::make_shared<ui::render_target>();
27+ rt->transparent = true ;
28+ rt->no_activate = true ;
29+ rt->capture_all_input = true ;
30+ rt->decorated = false ;
31+ rt->topmost = true ;
32+ rt->vsync = config::current->context_menu .vsync ;
33+
34+ if (config::current->avoid_resize_ui ) {
35+ rt->width = 3840 ;
36+ rt->height = 2159 ;
37+ }
38+
39+ if (auto res = rt->init (); !res) {
40+ MessageBoxW (NULL , L" Failed to initialize render target" , L" Error" ,
41+ MB_ICONERROR);
42+ }
43+
44+ glfw_proc_hook.install (rt->hwnd ());
45+ SetCapture ((HWND)rt->hwnd ());
46+ glfw_proc_hook.hooks .push_back ([](void *hwnd, void *original_proc,
47+ size_t msg, size_t wparam,
48+ size_t lparam) -> std::optional<int > {
49+ if (msg == WM_MOUSEACTIVATE) {
50+ return MA_NOACTIVATE;
51+ }
52+
53+ return std::nullopt ;
54+ });
55+
56+ config::current->apply_fonts_to_nvg (rt->nvg );
57+ return rt;
58+ }();
59+ auto render = menu_render (rt, std::nullopt );
60+
61+ rt->parent = menu.parent_window ;
62+
63+ // get the monitor in which the menu is being shown
64+ auto monitor = MonitorFromPoint ({x, y}, MONITOR_DEFAULTTONEAREST);
65+ MONITORINFOEX monitor_info;
66+ monitor_info.cbSize = sizeof (MONITORINFOEX);
67+ GetMonitorInfo (monitor, &monitor_info);
68+
69+ // set the position of the window to fullscreen in this monitor + padding
70+
71+ dbgout (" Monitor: {} {} {} {}" , monitor_info.rcMonitor .left ,
72+ monitor_info.rcMonitor .top , monitor_info.rcMonitor .right ,
73+ monitor_info.rcMonitor .bottom );
74+
75+ rt->set_position (monitor_info.rcMonitor .left + 1 ,
76+ monitor_info.rcMonitor .top + 1 );
77+ if (!config::current->avoid_resize_ui )
78+ rt->resize (
79+ monitor_info.rcMonitor .right - monitor_info.rcMonitor .left - 2 ,
80+ monitor_info.rcMonitor .bottom - monitor_info.rcMonitor .top - 2 );
81+
82+ glfwMakeContextCurrent (rt->window );
83+ glfwSwapInterval (config::current->context_menu .vsync ? 1 : 0 );
84+
85+ rt->show ();
86+ auto menu_wid = std::make_shared<mouse_menu_widget_main>(
87+ menu,
88+ // convert the x and y to the window coordinates
89+ x - monitor_info.rcMonitor .left , y - monitor_info.rcMonitor .top );
90+ rt->root ->children .push_back (menu_wid);
91+ auto current_js_context =
92+ entry::main_window_loop_hook
93+ .add_task ([&]() {
94+ return std::make_shared<js::js_menu_context>(
95+ js::js_menu_context::$from_window (menu.parent_window ));
96+ })
97+ .get ();
98+
99+ js::menu_info_basic_js menu_info{
100+ .menu = std::make_shared<js::menu_controller>(menu_wid->menu_wid ),
101+ .context = current_js_context};
102+
103+ if (run_js) {
104+ dbgout (" [perf] JS plugins start" );
105+ auto before_js = rt->clock .now ();
106+ for (auto &listener : menu_callbacks_js) {
107+ listener->operator ()(menu_info);
108+ }
109+ dbgout (" [perf] JS plugins costed {}ms" ,
110+ std::chrono::duration_cast<std::chrono::milliseconds>(
111+ rt->clock .now () - before_js)
112+ .count ());
113+ } else {
114+ dbgout (" Skipped running JS" );
41115 }
42116
43- glfw_proc_hook.install (rt->hwnd ());
44- SetCapture ((HWND)rt->hwnd ());
45- glfw_proc_hook.hooks .push_back ([](void *hwnd, void *original_proc,
46- size_t msg, size_t wparam,
47- size_t lparam) -> std::optional<int > {
48- if (msg == WM_MOUSEACTIVATE) {
49- return MA_NOACTIVATE;
50- }
51-
52- return std::nullopt ;
53- });
54-
55- config::current->apply_fonts_to_nvg (rt->nvg );
56- return rt;
57- }();
58- auto render = menu_render (rt, std::nullopt );
59-
60- rt->parent = menu.parent_window ;
61-
62- // get the monitor in which the menu is being shown
63- auto monitor = MonitorFromPoint ({x, y}, MONITOR_DEFAULTTONEAREST);
64- MONITORINFOEX monitor_info;
65- monitor_info.cbSize = sizeof (MONITORINFOEX);
66- GetMonitorInfo (monitor, &monitor_info);
67-
68- // set the position of the window to fullscreen in this monitor + padding
69-
70- dbgout (" Monitor: {} {} {} {}" , monitor_info.rcMonitor .left ,
71- monitor_info.rcMonitor .top , monitor_info.rcMonitor .right ,
72- monitor_info.rcMonitor .bottom );
73-
74- rt->set_position (monitor_info.rcMonitor .left + 1 ,
75- monitor_info.rcMonitor .top + 1 );
76- if (!config::current->avoid_resize_ui )
77- rt->resize (monitor_info.rcMonitor .right - monitor_info.rcMonitor .left - 2 ,
78- monitor_info.rcMonitor .bottom - monitor_info.rcMonitor .top - 2 );
79-
80- glfwMakeContextCurrent (rt->window );
81- glfwSwapInterval (config::current->context_menu .vsync ? 1 : 0 );
82-
83- rt->show ();
84- auto menu_wid = std::make_shared<mouse_menu_widget_main>(
85- menu,
86- // convert the x and y to the window coordinates
87- x - monitor_info.rcMonitor .left , y - monitor_info.rcMonitor .top );
88- rt->root ->children .push_back (menu_wid);
89- auto current_js_context =
90- entry::main_window_loop_hook
91- .add_task ([&]() {
92- return std::make_shared<js::js_menu_context>(
93- js::js_menu_context::$from_window (menu.parent_window ));
94- })
95- .get ();
96-
97- js::menu_info_basic_js menu_info{
98- .menu = std::make_shared<js::menu_controller>(menu_wid->menu_wid ),
99- .context = current_js_context};
100-
101- dbgout (" [perf] JS plugins start" );
102- auto before_js = rt->clock .now ();
103- for (auto &listener : menu_callbacks_js) {
104- listener->operator ()(menu_info);
105- }
106- dbgout (" [perf] JS plugins costed {}ms" ,
107- std::chrono::duration_cast<std::chrono::milliseconds>(rt->clock .now () -
108- before_js)
109- .count ());
110-
111- dbgout (" Current menu: {}" , menu_render::current.has_value ());
112- return render;
117+ dbgout (" Current menu: {}" , menu_render::current.has_value ());
118+ return render;
113119}
114120
115121menu_render::menu_render (std::shared_ptr<ui::render_target> rt,
116122 std::optional<int > selected_menu)
117123 : rt(std::move(rt)), selected_menu(selected_menu) {
118- current = this ;
124+ current = this ;
119125}
120126menu_render::~menu_render () {
121- if (this ->rt ) {
122- current = nullptr ;
123- }
127+ if (this ->rt ) {
128+ current = nullptr ;
129+ }
124130}
125131menu_render::menu_render (menu_render &&t) {
126- current = this ;
132+ current = this ;
127133
128- rt = std::move (t.rt );
129- selected_menu = std::move (t.selected_menu );
134+ rt = std::move (t.rt );
135+ selected_menu = std::move (t.selected_menu );
130136}
131137menu_render &menu_render::operator =(menu_render &&t) {
132- current = this ;
133- rt = std::move (t.rt );
134- selected_menu = std::move (t.selected_menu );
135- return *this ;
138+ current = this ;
139+ rt = std::move (t.rt );
140+ selected_menu = std::move (t.selected_menu );
141+ return *this ;
136142}
137143}; // namespace mb_shell
0 commit comments