App/API: fix event emission methods
[staging/windowmanager.git] / src / app.cpp
index 53a1a86..b8d3a86 100644 (file)
@@ -32,6 +32,7 @@
 #include <bits/signum.h>
 #include <csignal>
 #include <fstream>
+#include <thread>
 #include <json.hpp>
 
 namespace wm {
@@ -127,7 +128,6 @@ App::App(wl::display *d)
      config(),
      layouts(),
      layers(),
-     pending(),
      name_mapping(),
      id_alloc{},
      last_active() {
@@ -211,7 +211,7 @@ int App::dispatch_events() {
    this->display->flush();
 
    // execute pending tasks, that is layout changes etc.
-   this->execute_pending();
+   //this->execute_pending();
 
    return 0;
 }
@@ -270,6 +270,35 @@ int App::init_layout() {
    return 0;
 }
 
+namespace {
+
+// This can fix the HomeScreen...
+void redraw_fix(App *app, std::unique_ptr<genivi::surface> &s, int x, int y, int w, int h) {
+   { // XXX: Work around weston redraw issues
+      // trigger an update by changing the source dimensions!
+      s->set_configuration(w, h);
+      s->set_source_rectangle(0, 0, w, h);
+      s->set_destination_rectangle(x, y, w, h);
+      app->controller->commit_changes();
+      app->display->roundtrip();
+
+      // wait some time, for the process to do its thing...
+      using namespace std::chrono_literals;
+      std::this_thread::sleep_for(100ms);
+
+      // Set a different size then what we actually want.
+      s->set_configuration(w + 1, h);
+      s->set_source_rectangle(0, 0, w + 1, h);
+      s->set_destination_rectangle(x, y, w + 1, h);
+      app->controller->commit_changes();
+      app->display->roundtrip();
+
+      std::this_thread::sleep_for(100ms);
+   }
+}
+
+}  // namespace
+
 void App::surface_set_layout(uint32_t surface_id) {
    if (!this->controller->surface_exists(surface_id)) {
       logerror("Surface %d does not exist", int(surface_id));
@@ -305,18 +334,32 @@ void App::surface_set_layout(uint32_t surface_id) {
       h = this->controller->output_size.h + 1 + h;
    }
 
+   redraw_fix(this, s, x, y, w, h);
+
    // configure surface to wxh dimensions
    s->set_configuration(w, h);
+
    // set source reactangle, even if we should not need to set it.
    s->set_source_rectangle(0, 0, w, h);
+
    // set destination to the display rectangle
    s->set_destination_rectangle(x, y, w, h);
 
-   // XXX: The main_surface will be visible regardless
-   s->set_visibility(
-      surface_id == static_cast<unsigned>(this->layers.main_surface) ? 1 : 0);
+   s->set_visibility(0);
+   s->set_opacity(256);
+
+   this->controller->commit_changes();
+   this->display->roundtrip();
+
    this->controller->layers[layer_id]->add_surface(s.get());
 
+   // activate the main_surface right away
+   if (surface_id == static_cast<unsigned>(this->layers.main_surface)) {
+      logdebug("Activating main_surface (%d)", surface_id);
+
+      this->activate_surface(surface_id);
+   }
+
    logdebug("Surface %u now on layer %u with rect { %d, %d, %d, %d }",
             surface_id, layer_id, x, y, w, h);
 }
@@ -336,9 +379,10 @@ char const *App::activate_surface(uint32_t surface_id) {
    // Set all others invisible
    for (auto &i : this->controller->surfaces) {
       auto &si = this->controller->sprops[i.second->id];
-      if (si.visibility == 1 && si.id != s->id &&
-          int(si.id) != this->layers.main_surface) {
+      if (int(si.id) != this->layers.main_surface) {
          i.second->set_visibility(0);
+         this->controller->commit_changes();
+         this->display->flush();
       }
    }
    s->set_visibility(1);
@@ -390,22 +434,6 @@ char const *App::deactivate_surface(uint32_t surface_id) {
    return nullptr;
 }
 
-void App::add_task(char const *name, std::function<void()> &&f) {
-   this->pending.emplace_back(std::make_pair(name, f));
-}
-
-void App::execute_pending() {
-   if (!this->pending.empty()) {
-      for (auto &t : this->pending) {
-         logdebug("executing task '%s'", t.first);
-         t.second();
-      }
-      this->pending.clear();
-      this->controller->commit_changes();
-      this->display->flush();
-   }
-}
-
 //                      _          _   _____                 _
 //  _ __  _ __ _____  _(_) ___  __| | | ____|_   _____ _ __ | |_ ___
 // | '_ \| '__/ _ \ \/ / |/ _ \/ _` | |  _| \ \ / / _ \ '_ \| __/ __|
@@ -413,47 +441,46 @@ void App::execute_pending() {
 // | .__/|_|  \___/_/\_\_|\___|\__,_| |_____| \_/ \___|_| |_|\__|___/
 // |_|
 void App::surface_created(uint32_t surface_id) {
-   surface_id &= id_allocator::id_mask;
+   //surface_id >>= id_allocator::id_shift;
 
    logdebug("surface_id is %u", surface_id);
 
-   // We need to execute the surface setup after its creation.
-   this->add_task("surface_set_layout",
-                  [surface_id, this] { this->surface_set_layout(surface_id); });
+   this->surface_set_layout(surface_id);
 }
 
 void App::surface_removed(uint32_t surface_id) {
-   surface_id &= id_allocator::id_mask;
+   //surface_id >>= id_allocator::id_shift;
 
    logdebug("surface_id is %u", surface_id);
 
-   this->add_task("remove surface ID",
-                  [surface_id, this] {
-                     this->id_alloc.remove_id(surface_id);
+   this->id_alloc.remove_id(surface_id);
 
-                     // Also remove from last_active, if found
-                     auto i = std::find(this->last_active.begin(),
-                                        this->last_active.end(), surface_id);
-                     if (i != this->last_active.end()) {
-                        this->last_active.erase(i);
-                     }
-                  });
+   // Also remove from last_active, if found
+   auto i = std::find(this->last_active.begin(),
+                      this->last_active.end(), surface_id);
+   if (i != this->last_active.end()) {
+      this->last_active.erase(i);
+   }
 }
 
 void App::emit_activated(char const *label) {
-   this->api.send_event("activated", json_object_new_string(label));
+   this->api.send_event("activated", label);
 }
 
 void App::emit_deactivated(char const *label) {
-   this->api.send_event("deactivated", json_object_new_string(label));
+   this->api.send_event("deactivated", label);
 }
 
 void App::emit_syncdraw(char const *label) {
-   this->api.send_event("syncdraw", json_object_new_string(label));
+   this->api.send_event("syncdraw", label);
+}
+
+void App::emit_flushdraw(char const *label) {
+   this->api.send_event("syncdraw", label);
 }
 
 void App::emit_visible(char const *label, bool is_visible) {
-   this->api.send_event(is_visible ? "visible" : "invisible", json_object_new_string(label));
+   this->api.send_event(is_visible ? "visible" : "invisible", label);
 }
 
 result<int> App::request_surface(char const *drawing_name) {
@@ -617,8 +644,4 @@ void controller_hooks::surface_removed(uint32_t surface_id) {
    this->app->surface_removed(surface_id);
 }
 
-void controller_hooks::add_task(char const *name, std::function<void()> &&f) {
-   this->app->add_task(name, std::move(f));
-}
-
 }  // namespace wm