From 3372c1a7b24ba617c90307c32711d11d4d44d905 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 28 May 2018 01:24:02 +0200 Subject: [PATCH] sculpt: manage leitzentrale window layout With this patch, the sculpt manager takes over the role the window layouter of the leitzentrale, which eliminates the need to manually position and size the inspect window. --- repos/gems/recipes/pkg/sculpt/archives | 1 - repos/gems/run/leitzentrale.run | 7 +- repos/gems/run/sculpt.run | 1 + repos/gems/run/sculpt/drop_shadow.png | Bin 0 -> 1494 bytes repos/gems/run/sculpt/fonts.config | 3 + repos/gems/run/sculpt/leitzentrale.config | 54 +++--- repos/gems/src/app/sculpt_manager/gui.cc | 7 +- repos/gems/src/app/sculpt_manager/gui.h | 5 + repos/gems/src/app/sculpt_manager/main.cc | 173 +++++++++++++++++- .../sculpt_manager/runtime/file_browser.cc | 7 +- 10 files changed, 212 insertions(+), 46 deletions(-) create mode 100644 repos/gems/run/sculpt/drop_shadow.png diff --git a/repos/gems/recipes/pkg/sculpt/archives b/repos/gems/recipes/pkg/sculpt/archives index bf173772fce..a8c868560d6 100644 --- a/repos/gems/recipes/pkg/sculpt/archives +++ b/repos/gems/recipes/pkg/sculpt/archives @@ -38,7 +38,6 @@ _/src/e2fsprogs-minimal _/src/nvme_drv _/src/wm _/src/themed_decorator -_/src/floating_window_layouter _/src/libpng _/src/zlib _/src/menu_view diff --git a/repos/gems/run/leitzentrale.run b/repos/gems/run/leitzentrale.run index 00bf8a41a9b..6e88ab8fe74 100644 --- a/repos/gems/run/leitzentrale.run +++ b/repos/gems/run/leitzentrale.run @@ -279,10 +279,11 @@ install_config { } -file copy -force [genode_dir]/repos/gems/recipes/raw/fonts_fs/fonts_fs.config [run_dir]/genode/fonts.config -file copy -force [genode_dir]/repos/gems/run/sculpt/leitzentrale.config [run_dir]/genode/ -file copy -force [genode_dir]/repos/gems/run/sculpt/vimrc [run_dir]/genode/ +file copy -force [genode_dir]/repos/gems/run/sculpt/fonts.config [run_dir]/genode/ +file copy -force [genode_dir]/repos/gems/run/sculpt/leitzentrale.config [run_dir]/genode/ +file copy -force [genode_dir]/repos/gems/run/sculpt/vimrc [run_dir]/genode/ file copy -force [genode_dir]/repos/gems/src/app/backdrop/genode_logo.png [run_dir]/genode/ +file copy -force [genode_dir]/repos/gems/run/sculpt/drop_shadow.png [run_dir]/genode/ proc install_rom_module { name content } { set fd [open [run_dir]/genode/$name w] diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run index 53964a65b75..f57232fe2bb 100644 --- a/repos/gems/run/sculpt.run +++ b/repos/gems/run/sculpt.run @@ -447,6 +447,7 @@ file copy -force [genode_dir]/repos/gems/recipes/raw/depot_download/depot_downlo file copy -force [genode_dir]/VERSION [run_dir]/genode/ file copy -force [genode_dir]/repos/gems/src/app/backdrop/genode_logo.png [run_dir]/genode/ +file copy -force [genode_dir]/repos/gems/run/sculpt/drop_shadow.png [run_dir]/genode/ exec gzip -dc [genode_dir]/repos/gems/run/sculpt/machine.vdi.gz > [run_dir]/genode/machine.vdi diff --git a/repos/gems/run/sculpt/drop_shadow.png b/repos/gems/run/sculpt/drop_shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..b9eab99386d76bba16211b68fff8a8369a00f5d8 GIT binary patch literal 1494 zcmZ{kZ9LO!7{~t~AB+tRsVp?-FprxNww99eG}#i{Dk`++wOQ7f>XdACS~PmbDe^2i z(RNa%GdrkGqK-*Q(W8phs4+#wne*m+&WrQnzOK*jy6@lj_v*Tj#u1~e!7wlY0M_{E z@OWciGk+{hjTJ~yl8x1r8Ab>L0C@rATdJ8+!>Q5n1OV8J0Dyys0AR*AIyeFV8E62| zrT_r02mluEI^VJ}#CTz{V|`ROFn6S&TWwSzA)XKcdSz~5Y@nQG&i@#nQcQog(aG)$^xxe4BH!x8zS4N*+_!I1+D+Rkeal+7^rD%p zjVS?L35xO7wDo&}6&n=~>uoiak?u>aIacDzj##(%i@UPQ*Hka!^0=#{vj~{8Je~AD z=ypKn@w@;{WS=ER!dfU>J?bVY6P>miv0iU|))dC&@&XeBUC7Lnp^)rWiJ~l^+q^SR z(`i4218o@}+0_uX6*|&Xky1~oZ%Vvy>@?Xc+rj?kj{K^Vq{D;QolqGr%wwsUvPaus zYavc_XU)wPEX$sHxxZl&(RyIokgQJeNMEhW^ZG&jWP{eB_FYFo=uWcBRhD1vPq!tP zFGp5yNuObtU!c=8v$&i}DMeRHu00az z)ZE3EPm@e*;)Lv9f}rvf1ltL4juy2uoASc5`J;G&pZTX@gYWd5YpUd2dfA^ZHa4HK zi8=!b-E7CQbt;_Zkbi%iwBBT2En%~20`j~d=8u=xOin?jnA2$l+9^m{gZ&+;_D1Z5 zkXDtYkCT?K!IPvVN=1s&9a61y? z1hpEIgKEtBpP}2_W>t!p_WGyFGNsd1un9-v<+{xk%CzqPEKVp@qQ~hdi|VsCqMWcL zN1kIHHo2e*?$^UBY==S|JghQBG11Db0oer5=Q7k~D%2|i_c>aEqCP)9L|dxU-Mx5n zn^Q5Rql)dJCOZ;j)%(KR6E+HdTJJY5Ce9hzZ7Q2oioU;We{0O8X|<5jS289u-;kLp zo`X3Xx_Y@vP|exhy^De>s7D72Rr;sc#>SH+v_3~?XH;n`i-OsmKI{3_mwmM~W}-&1 zVx@*~@3BlZoIaNSC=>QzlsVa{cGqNI!R%Fb0`g4$zQ&=^e7NSU1>;>_OG z&|DiBJKuxqHMLhc+1-((o2e_N6t}!RMV7qz3)-kUmwg30wEuvB)5GjsXv>FUN6`j# z?R)v86~g{QU~olS`Egy|CxrXV+G^xEUT>ZEw%$+qx(oAb?|A^!%g9BjNP%mO|IAil z#Ae|-K95IF69Vz{G#Xt14^I`+aqs}NKNg7&MxwEB|3KVw3~qT)A~=qlDrE2lJRCd= z8=M>*h}=a*a@lDaSx9DD2H42i#pcolI5^YC2Ofk9K>33cUR}Z)bKK{1X!BsIfNpHS zzj%^=@IQEr4>|ycM&|;_HUBa2_%t?S&;J{~ZhHqa8eHcS68H?EC{;iQ;x@ i%TX8<8kLd8XE4}Qb}ILb@=KQSF@TRChBvHD5&sQ}6_GUn literal 0 HcmV?d00001 diff --git a/repos/gems/run/sculpt/fonts.config b/repos/gems/run/sculpt/fonts.config index f15f3becc2d..b5ee5db4be1 100644 --- a/repos/gems/run/sculpt/fonts.config +++ b/repos/gems/run/sculpt/fonts.config @@ -20,4 +20,7 @@ + + + diff --git a/repos/gems/run/sculpt/leitzentrale.config b/repos/gems/run/sculpt/leitzentrale.config index cded9e45bba..69d701b17d6 100644 --- a/repos/gems/run/sculpt/leitzentrale.config +++ b/repos/gems/run/sculpt/leitzentrale.config @@ -90,17 +90,15 @@ - - - - + + + - - - + + @@ -110,7 +108,6 @@ - @@ -121,29 +118,26 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -164,7 +158,7 @@ - + @@ -190,6 +184,8 @@ + + @@ -208,7 +204,7 @@ - + @@ -223,9 +219,9 @@ - + - + @@ -235,6 +231,8 @@ + + diff --git a/repos/gems/src/app/sculpt_manager/gui.cc b/repos/gems/src/app/sculpt_manager/gui.cc index 3b02b3d1f4e..7252215be32 100644 --- a/repos/gems/src/app/sculpt_manager/gui.cc +++ b/repos/gems/src/app/sculpt_manager/gui.cc @@ -27,7 +27,7 @@ void Sculpt::Gui::_gen_menu_view_start_content(Xml_generator &xml, { xml.attribute("version", version.value); - gen_common_start_content(xml, label, Cap_quota{150}, Ram_quota{8*1024*1024}); + gen_common_start_content(xml, label, Cap_quota{150}, Ram_quota{9*1024*1024}); gen_named_node(xml, "binary", "menu_view"); @@ -98,6 +98,11 @@ void Sculpt::Gui::_generate_config(Xml_generator &xml) const gen_parent_service<::File_system::Session>(xml); }); + xml.node("resource", [&] () { + xml.attribute("name", "RAM"); + xml.attribute("preserve", "1M"); + }); + xml.node("start", [&] () { _gen_menu_view_start_content(xml, "menu_view", Point(0, 0)); }); } diff --git a/repos/gems/src/app/sculpt_manager/gui.h b/repos/gems/src/app/sculpt_manager/gui.h index 88a72373d57..6d531bf47fe 100644 --- a/repos/gems/src/app/sculpt_manager/gui.h +++ b/repos/gems/src/app/sculpt_manager/gui.h @@ -48,6 +48,11 @@ struct Sculpt::Gui _config.generate([&] (Xml_generator &xml) { _generate_config(xml); }); } + void font_size(float px) + { + menu_width = max(px*21, 320.0); + } + Gui(Env &env) : _env(env) { } }; diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index 5ae39121eac..dfd3c448e3f 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -64,7 +64,24 @@ struct Sculpt::Main : Input_event_handler, Managed_config
_fonts_config { _env, "config", "fonts", *this, &Main::_handle_fonts_config }; - void _handle_fonts_config(Xml_node) { _handle_nitpicker_mode(); } + void _handle_fonts_config(Xml_node config) + { + /* + * Obtain font size from manually maintained fonts configuration + * so that we can adjust the GUI layout accordingly. + */ + config.for_each_sub_node("vfs", [&] (Xml_node vfs) { + vfs.for_each_sub_node("dir", [&] (Xml_node dir) { + if (dir.attribute_value("name", String<16>()) == "fonts") { + dir.for_each_sub_node("dir", [&] (Xml_node type) { + if (type.attribute_value("name", String<16>()) == "text") { + type.for_each_sub_node("ttf", [&] (Xml_node ttf) { + float const px = ttf.attribute_value("size_px", 0.0); + if (px > 0.0) + _gui.font_size(px); }); } }); } }); }); + + _handle_nitpicker_mode(); + } Managed_config
_input_filter_config { _env, "config", "input_filter", *this, &Main::_handle_input_filter_config }; @@ -337,6 +354,22 @@ struct Sculpt::Main : Input_event_handler, _gui.generate_config(); } + void _handle_window_layout(); + + Attached_rom_dataspace _window_list { _env, "window_list" }; + + Signal_handler
_window_list_handler { + _env.ep(), *this, &Main::_handle_window_layout }; + + Expanding_reporter _wm_focus { _env, "focus", "wm_focus" }; + + Attached_rom_dataspace _decorator_margins { _env, "decorator_margins" }; + + Signal_handler
_decorator_margins_handler { + _env.ep(), *this, &Main::_handle_window_layout }; + + Expanding_reporter _window_layout { _env, "window_layout", "window_layout" }; + Main(Env &env) : _env(env) { _runtime_state.sigh(_runtime_state_handler); @@ -345,10 +378,12 @@ struct Sculpt::Main : Input_event_handler, /* * Subscribe to reports */ - _update_state_rom.sigh(_update_state_handler); - _nitpicker_hover .sigh(_nitpicker_hover_handler); - _hover_rom .sigh(_hover_handler); - _pci_devices .sigh(_pci_devices_handler); + _update_state_rom .sigh(_update_state_handler); + _nitpicker_hover .sigh(_nitpicker_hover_handler); + _hover_rom .sigh(_hover_handler); + _pci_devices .sigh(_pci_devices_handler); + _window_list .sigh(_window_list_handler); + _decorator_margins.sigh(_decorator_margins_handler); /* * Generate initial configurations @@ -368,15 +403,125 @@ struct Sculpt::Main : Input_event_handler, }; +void Sculpt::Main::_handle_window_layout() +{ + struct Decorator_margins + { + unsigned top = 0, bottom = 0, left = 0, right = 0; + + Decorator_margins(Xml_node node) + { + if (!node.has_sub_node("floating")) + return; + + Xml_node const floating = node.sub_node("floating"); + + top = floating.attribute_value("top", 0UL); + bottom = floating.attribute_value("bottom", 0UL); + left = floating.attribute_value("left", 0UL); + right = floating.attribute_value("right", 0UL); + } + }; + + /* read decorator margins from the decorator's report */ + _decorator_margins.update(); + Decorator_margins const margins(_decorator_margins.xml()); + + unsigned const log_min_w = 400, log_min_h = 200; + + if (!_nitpicker.constructed()) + return; + + Framebuffer::Mode const mode = _nitpicker->mode(); + + typedef Nitpicker::Rect Rect; + + Rect avail(Point(_gui.menu_width, 0), + Point(mode.width() - 1, mode.height() - 1)); + + /* + * When the screen width is at least twice the log width, place the + * log at the right side of the screen. Otherwise, with resolutions + * as low as 1024x768, place it to the bottom to allow the inspect + * window to use the available screen width to the maximum extend. + */ + bool const log_at_right = + (avail.w() > 2*(log_min_w + margins.left + margins.right)); + + /* the upper-left point depends on whether the log is at the right or bottom */ + Point const log_p1 = + log_at_right ? Point(avail.x2() - log_min_w - margins.right + 1, + margins.top) + : Point(_gui.menu_width + margins.left, + avail.y2() - log_min_h - margins.bottom + 1); + + /* the lower-right point (p2) of the log is always the same */ + Point const log_p2(mode.width() - margins.right - 1, + mode.height() - margins.bottom - 1); + + /* position of the inspect window */ + Point const inspect_p1(avail.x1() + margins.right, margins.top); + + Point const inspect_p2 = + log_at_right ? Point(log_p1.x() - margins.right - margins.left - 1, log_p2.y()) + : Point(log_p2.x(), log_p1.y() - margins.bottom - margins.top - 1); + + typedef String<128> Label; + Label const inspect_label("runtime -> leitzentrale -> storage browser"); + + _window_list.update(); + _window_layout.generate([&] (Xml_generator &xml) { + + _window_list.xml().for_each_sub_node("window", [&] (Xml_node win) { + + Label const label = win.attribute_value("label", Label()); + + /** + * Generate window with 'rect' geometry if label matches 'match' + */ + auto gen_matching_window = [&] (Label const &match, Rect rect) { + if (label == match && rect.valid()) { + xml.node("window", [&] () { + xml.attribute("id", win.attribute_value("id", 0UL)); + xml.attribute("xpos", rect.x1()); + xml.attribute("ypos", rect.y1()); + xml.attribute("width", rect.w()); + xml.attribute("height", rect.h()); + }); + } + }; + + gen_matching_window("log", Rect(log_p1, log_p2)); + gen_matching_window(inspect_label, Rect(inspect_p1, inspect_p2)); + }); + }); + + /* define window-manager focus */ + _wm_focus.generate([&] (Xml_generator &xml) { + _window_list.xml().for_each_sub_node("window", [&] (Xml_node win) { + Label const label = win.attribute_value("label", Label()); + if (label == inspect_label) + xml.node("window", [&] () { + xml.attribute("id", win.attribute_value("id", 0UL)); }); + }); + }); +} + + void Sculpt::Main::_handle_nitpicker_mode() { - if (!_fonts_config.try_generate_manually_managed()) { + if (!_nitpicker.constructed()) + return; + + Framebuffer::Mode const mode = _nitpicker->mode(); - Framebuffer::Mode const mode = _nitpicker->mode(); + _handle_window_layout(); + + if (!_fonts_config.try_generate_manually_managed()) { float const text_size = (float)mode.height() / 60.0; - _gui.menu_width = text_size*21; + _gui.font_size(text_size); _fonts_config.generate([&] (Xml_generator &xml) { xml.node("vfs", [&] () { @@ -403,6 +548,18 @@ void Sculpt::Main::_handle_nitpicker_mode() }); }); xml.node("default-policy", [&] () { xml.attribute("root", "/fonts"); }); + + auto gen_color = [&] (unsigned index, Color color) { + xml.node("color", [&] () { + xml.attribute("index", index); + xml.attribute("bg", String<16>(color)); + }); + }; + + Color const background(0x1c, 0x22, 0x32); + + gen_color(0, background); + gen_color(8, background); }); } diff --git a/repos/gems/src/app/sculpt_manager/runtime/file_browser.cc b/repos/gems/src/app/sculpt_manager/runtime/file_browser.cc index b1d62cf351d..4808e3ac4b1 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/file_browser.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/file_browser.cc @@ -34,7 +34,7 @@ namespace Sculpt { void Sculpt::gen_nit_fb_start(Xml_generator &xml, Rom_name const &name) { - gen_common_start_content(xml, name, Cap_quota{100}, Ram_quota{4*1024*1024}); + gen_common_start_content(xml, name, Cap_quota{100}, Ram_quota{8*1024*1024}); gen_named_node(xml, "binary", "nit_fb"); @@ -43,10 +43,7 @@ void Sculpt::gen_nit_fb_start(Xml_generator &xml, Rom_name const &name) gen_service_node(xml, [&] () {}); }); - xml.node("config", [&] () { - xml.attribute("initial_width", "600"); - xml.attribute("initial_height", "500"); - }); + xml.node("config", [&] () { }); xml.node("route", [&] () { gen_parent_rom_route(xml, "nit_fb");