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 00000000000..b9eab99386d
Binary files /dev/null and b/repos/gems/run/sculpt/drop_shadow.png differ
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");