From 6a4504b1fe5e17a09a019edf0377646cc5dd72aa Mon Sep 17 00:00:00 2001 From: Marcus Fritzsch Date: Thu, 17 Aug 2017 16:45:56 +0200 Subject: Implement surface names * request_surface(name: string) -> id: int. * activate_surface(name: string). * names will be mapped to their respective layers by use of the layers' surface rola match, a regex. * the generated IDs are global and not reused. * allow wp-request to use -p, disable use of pygments even if found. Things missing: * surface removal does not remove already established mappings/names. * Mostly untested. Signed-off-by: Marcus Fritzsch --- src/app.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 14 deletions(-) (limited to 'src/app.cpp') diff --git a/src/app.cpp b/src/app.cpp index db0a5e3..c38a7f4 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace wm { @@ -44,8 +45,7 @@ struct wm::area area_from_json(json const &j) { return wm::area{ j["name"], { - j["width"], j["height"], - j["x"], j["y"], + j["width"], j["height"], j["x"], j["y"], }, j["zorder"], }; @@ -126,7 +126,11 @@ App::App(wl::display *d) outputs(), config(), layouts(), - layers() { + layers(), + pending(), + name_mapping(), + id_alloc{} +{ assert(g_app == nullptr); g_app = this; @@ -280,8 +284,10 @@ void App::surface_set_layout(uint32_t surface_id) { } uint32_t layer_id = o_layer_id.value(); + logdebug("surface_set_layout for surface %u on layer %u", surface_id, layer_id); - auto rect = this->layers.get_layer_rect(surface_id).value(); + auto const &layer = this->layers.get_layer(layer_id); + auto rect = layer.value().rect; auto &s = this->controller->surfaces[surface_id]; int x = rect.x; @@ -305,7 +311,7 @@ void App::surface_set_layout(uint32_t surface_id) { // XXX: visibility should be determined independently of our // layer + geometry setup. - s->set_visibility(1); + s->set_visibility(surface_id == (unsigned)this->layers.main_surface ? 1 : 0); this->controller->layers[layer_id]->add_surface(s.get()); logdebug("Surface %u now on layer %u with rect { %d, %d, %d, %d }", @@ -317,7 +323,7 @@ char const *App::activate_surface(uint32_t surface_id) { return "Surface does not exist"; } - // This shouild involve a policy check, but as we do not (yet) have + // This should involve a policy check, but as we do not (yet) have // such a thing, we will just switch to this surface. // XXX: input focus missing!!1 @@ -376,24 +382,81 @@ void App::surface_removed(uint32_t surface_id) { logdebug("surface_id is %u", surface_id); } +result App::request_surface(char const *drawing_name) { + auto lid = this->layers.get_layer_id(std::string(drawing_name)); + if (!lid) { + // XXX: to we need to put these applications on the App layer? + return Err("Drawing name does not match any role"); + } + + auto rname = this->id_alloc[drawing_name]; + if (! rname) { + // name does not exist yet, allocate surface id... + // XXX: how to allocate surface IDs? + // * allocate by running a counter for each layer? + // * allocate IDs globally, i.e. do not have layers contain + // ID ranges (only define the surfaces on the layer by + // role?) + auto id = int(this->id_alloc(drawing_name)); + this->layers.add_surface(id, lid.value()); + + // XXX: setup the main_surface id if we registered HomeScreen + // XXX: you should fix this! + if (!this->layers.main_surface_name.empty() && + this->layers.main_surface_name == drawing_name) { + this->layers.main_surface = id; + this->activate_surface(id); + logdebug("Set main_surface id to %u", id); + } + + return Ok(id); + } + + // Check currently registered drawing names if it is already there. + return Err("Surface already present"); +} + +char const* App::activate_surface(char const *drawing_name) { + auto osid = this->id_alloc[drawing_name]; + + if (osid) { + logdebug("ativate surface with name %s and id %u", drawing_name, osid.value()); + this->activate_surface(osid.value()); + return nullptr; + } + + logerror("surface %s unknown", drawing_name); + return "Surface unknown"; +} + // _ _ _ _ _ _ _ // | |__ (_)_ __ __| (_)_ __ __ _ __ _ _ __ (_) (_)_ __ ___ _ __ | | // | '_ \| | '_ \ / _` | | '_ \ / _` | / _` | '_ \| | | | '_ ` _ \| '_ \| | // | |_) | | | | | (_| | | | | | (_| | | (_| | |_) | | | | | | | | | |_) | | // |_.__/|_|_| |_|\__,_|_|_| |_|\__, |___\__,_| .__/|_| |_|_| |_| |_| .__/|_| // |___/_____| |_| |_| -binding_api::result_type binding_api::register_surface(uint32_t appid, - uint32_t surfid) { - logdebug("%s appid %u surfid %u", __func__, appid, surfid); - if (appid > 0xff) { - return Err("invalid appid"); +binding_api::result_type binding_api::request_surface( + char const *drawing_name) { + auto r = this->app->request_surface(drawing_name); + if (r.is_err()) { + return Err(r.unwrap_err()); } + return Ok(json_object_new_int(r.unwrap())); +} - if (surfid > 0xffff) { - return Err("invalid surfaceid"); +binding_api::result_type binding_api::activate_surface( + char const *drawing_name) { + logdebug("%s drawing_name %s", __func__, drawing_name); + auto r = this->app->activate_surface(drawing_name); + if (r) { + return Err(r); } + return Ok(json_object_new_object()); +} - return Ok(json_object_new_int((appid << 16) + surfid)); +binding_api::result_type binding_api::list_drawing_names() { + json j = this->app->id_alloc.names; + return Ok(json_tokener_parse(j.dump().c_str())); } binding_api::result_type binding_api::debug_layers() { -- cgit 1.2.3-korg