Skip to content

Commit

Permalink
window_layouter: modernized coding style
Browse files Browse the repository at this point in the history
Replace the use of pointers and the copying of XML nodes by the 'with_'
pattern. Use plain struct where appropriate, replace constructors by { }
initialization. Use C++20 function template syntax. Replace accessors by
public constants where possible. Follow 'from_xml' convention. Follow
usual 'Action' interface naming.

Issue genodelabs#5390
  • Loading branch information
nfeske committed Dec 18, 2024
1 parent 17d3c7f commit 8494838
Show file tree
Hide file tree
Showing 14 changed files with 426 additions and 568 deletions.
86 changes: 0 additions & 86 deletions repos/gems/src/app/window_layouter/action.h

This file was deleted.

118 changes: 63 additions & 55 deletions repos/gems/src/app/window_layouter/assign.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,63 @@ class Window_layouter::Assign : public List_model<Assign>::Element
: Registry<Member>::Element(registry, *this), window(window) { }
};

using Label = String<80>;

Target::Name target_name { };

private:

Registry<Member> _members { };

struct Label
{
using Value = String<80>;

Value exact, prefix, suffix;

static Label from_xml(Xml_node const &node)
{
return { .exact = node.attribute_value("label", Value()),
.prefix = node.attribute_value("label_prefix", Value()),
.suffix = node.attribute_value("label_suffix", Value()) };
}

bool operator == (Label const &other) const
{
return exact == other.exact
&& prefix == other.prefix
&& suffix == other.suffix;
}

bool matches(Value const &label) const
{
if (exact.valid() && label == exact)
return true;

if (exact.valid())
return false;

bool const prefix_matches =
prefix.valid() &&
!strcmp(label.string(), prefix.string(), prefix.length() - 1);

bool suffix_matches = false;
if (label.length() >= suffix.length()) {
size_t const offset = label.length() - suffix.length();
suffix_matches = !strcmp(label.string() + offset, suffix.string());
}

return (!prefix.valid() || prefix_matches)
&& (!suffix.valid() || suffix_matches);
}

void gen_attr(Xml_generator &xml) const
{
if (exact .valid()) xml.attribute("label", exact);
if (prefix.valid()) xml.attribute("label_prefix", prefix);
if (suffix.valid()) xml.attribute("label_suffix", suffix);
}
};

Label const _label;
Label const _label_prefix;
Label const _label_suffix;

bool _pos_defined = false;
bool _xpos_any = false;
Expand All @@ -66,12 +112,7 @@ class Window_layouter::Assign : public List_model<Assign>::Element

public:

Assign(Xml_node assign)
:
_label (assign.attribute_value("label", Label())),
_label_prefix(assign.attribute_value("label_prefix", Label())),
_label_suffix(assign.attribute_value("label_suffix", Label()))
{ }
Assign(Xml_node assign) : _label(Label::from_xml(assign)) { }

void update(Xml_node assign)
{
Expand All @@ -89,19 +130,12 @@ class Window_layouter::Assign : public List_model<Assign>::Element
/**
* List_model::Element
*/
bool matches(Xml_node node) const
{
return node.attribute_value("label", Label()) == _label
&& node.attribute_value("label_prefix", Label()) == _label_prefix
&& node.attribute_value("label_suffix", Label()) == _label_suffix;
}
bool matches(Xml_node node) const { return Label::from_xml(node) == _label; }

/**
* List_model::Element
*/
static bool type_matches(Xml_node const &node)
{
return node.has_type("assign");
static bool type_matches(Xml_node const &node) { return node.has_type("assign");
}

/**
Expand Down Expand Up @@ -136,38 +170,19 @@ class Window_layouter::Assign : public List_model<Assign>::Element
*
* This method is used for associating assignments to windows.
*/
template <typename FN>
void with_matching_members_registry(Label const &label, FN const &fn)
void with_matching_members_registry(Label::Value const &label, auto const &fn)
{
bool const label_matches = (_label.valid() && label == _label);

bool const prefix_matches =
_label_prefix.valid() &&
!strcmp(label.string(),
_label_prefix.string(), _label_prefix.length() - 1);

bool suffix_matches = false;
if (label.length() >= _label_suffix.length()) {
unsigned const offset = (unsigned)(label.length() - _label_suffix.length());
suffix_matches = !strcmp(_label.string() + offset, _label_suffix.string());
}

bool const wildcard_matches = !_label.valid()
&& (!_label_prefix.valid() || prefix_matches)
&& (!_label_suffix.valid() || suffix_matches);

if (label_matches || wildcard_matches)
if (_label.matches(label))
fn(_members);
}

/**
* Used to generate <assign> nodes of windows captured via wildcard
*/
template <typename FN>
void for_each_wildcard_member(FN const &fn) const
void for_each_wildcard_member(auto const &fn) const
{
/* skip non-wildcards */
if (_label.valid())
if (_label.exact.valid())
return;

_members.for_each([&] (Assign::Member const &member) { fn(member); });
Expand All @@ -176,28 +191,24 @@ class Window_layouter::Assign : public List_model<Assign>::Element
/**
* Used to bring wildcard-matching windows to front
*/
template <typename FN>
void for_each_wildcard_member(FN const &fn)
void for_each_wildcard_member(auto const &fn)
{
if (_label.valid())
if (_label.exact.valid())
return;

_members.for_each([&] (Assign::Member &member) { fn(member); });
}

bool floating() const { return _pos_defined; }

bool wildcard() const { return !_label.valid(); }
bool wildcard() const { return !_label.exact.valid(); }

/**
* Generate <assign> node
*/
void gen_assign_attr(Xml_generator &xml) const
{
if (_label.valid()) xml.attribute("label", _label);
if (_label_prefix.valid()) xml.attribute("label_prefix", _label_prefix);
if (_label_suffix.valid()) xml.attribute("label_suffix", _label_suffix);

_label.gen_attr(xml);
xml.attribute("target", target_name);
}

Expand Down Expand Up @@ -247,11 +258,8 @@ class Window_layouter::Assign : public List_model<Assign>::Element
xml.attribute("visible", "no");
}

template <typename FN>
void for_each_member(FN const &fn) { _members.for_each(fn); }

template <typename FN>
void for_each_member(FN const &fn) const { _members.for_each(fn); }
void for_each_member(auto const &fn) { _members.for_each(fn); }
void for_each_member(auto const &fn) const { _members.for_each(fn); }
};

#endif /* _ASSIGN_H_ */
8 changes: 3 additions & 5 deletions repos/gems/src/app/window_layouter/assign_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,19 @@ class Window_layouter::Assign_list : Noncopyable
auto fn = [&] (Registry<Assign::Member> &registry) {
window.assignment(registry); };

assign.with_matching_members_registry(window.label(), fn);
assign.with_matching_members_registry(window.label, fn);
});
});
}

template <typename FN>
void for_each_wildcard_member(FN const &fn) const
void for_each_wildcard_member(auto const &fn) const
{
_assignments.for_each([&] (Assign const &assign) {
assign.for_each_wildcard_member([&] (Assign::Member const &member) {
fn(assign, member); }); });
}

template <typename FN>
void for_each_wildcard_assigned_window(FN const &fn)
void for_each_wildcard_assigned_window(auto const &fn)
{
_assignments.for_each([&] (Assign &assign) {
assign.for_each_wildcard_member([&] (Assign::Member &member) {
Expand Down
52 changes: 52 additions & 0 deletions repos/gems/src/app/window_layouter/command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* \brief Command triggered via the keyboard
* \author Norman Feske
* \date 2016-02-01
*/

/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/

#ifndef _COMMAND_H_
#define _COMMAND_H_

#include <target.h>

namespace Window_layouter { class Command; }


struct Window_layouter::Command
{
enum Type { NONE, NEXT_WINDOW, PREV_WINDOW, RAISE_WINDOW, TOGGLE_FULLSCREEN,
NEXT_TAB, PREV_TAB, SCREEN, RELEASE_GRAB, };

Type type;
Target::Name target;

static Command from_xml(Xml_node const &node)
{
auto from_string = [] (auto const &string) -> Type
{
if (string == "next_window") return NEXT_WINDOW;
if (string == "prev_window") return PREV_WINDOW;
if (string == "raise_window") return RAISE_WINDOW;
if (string == "toggle_fullscreen") return TOGGLE_FULLSCREEN;
if (string == "screen") return SCREEN;
if (string == "release_grab") return RELEASE_GRAB;

warning("cannot convert \"", string, "\" to action type");
return NONE;
};

return {
.type = from_string(node.attribute_value("action", String<32>())),
.target = node.attribute_value("target", Name())
};
}
};

#endif /* _COMMAND_H_ */
14 changes: 7 additions & 7 deletions repos/gems/src/app/window_layouter/decorator_margins.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ struct Window_layouter::Decorator_margins
{
unsigned top, bottom, left, right;

Decorator_margins(Xml_node node)
:
top (node.attribute_value("top", 0U)),
bottom(node.attribute_value("bottom", 0U)),
left (node.attribute_value("left", 0U)),
right (node.attribute_value("right", 0U))
{ }
static Decorator_margins from_xml(Xml_node const &node)
{
return { .top = node.attribute_value("top", 0U),
.bottom = node.attribute_value("bottom", 0U),
.left = node.attribute_value("left", 0U),
.right = node.attribute_value("right", 0U) };
}

/**
* Convert outer geometry to inner geometry
Expand Down
Loading

0 comments on commit 8494838

Please sign in to comment.