From af07d7774994283b5f70c72a7ca3fab865533f91 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 3 Mar 2023 03:32:59 +0000 Subject: [PATCH] Support using recent window position When the application is started with the setting window position option, the application core saves the position information to the file. And then, the application will use the recent window poisition when it is restarted. Change-Id: I3e9a5c3760a2fd56e66db135d14d6e73027ed1ba Signed-off-by: Hwankyu Jhun --- tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc | 109 +++++++++++----- .../app-core-ui-cpp/window_position_private.cc | 144 +++++++++++++++++++++ .../app-core-ui-cpp/window_position_private.hh | 53 ++++++++ 3 files changed, 275 insertions(+), 31 deletions(-) create mode 100644 tizen-cpp/app-core-ui-cpp/window_position_private.cc create mode 100644 tizen-cpp/app-core-ui-cpp/window_position_private.hh diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc index cfc6e6c..e7f8c0e 100644 --- a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc +++ b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include "app-core-cpp/app_core_base.hh" #include "app-core-ui-cpp/api/app_core_ui_base.h" @@ -39,6 +40,7 @@ #include "app-core-ui-cpp/app_core_ui_delegator_private.hh" #include "app-core-ui-cpp/app_core_ui_plugin_private.hh" #include "app-core-ui-cpp/wayland_handler_private.hh" +#include "app-core-ui-cpp/window_position_private.hh" #include "common/ecore_handler.hh" #include "common/glib_private.hh" #include "common/log_private.hh" @@ -46,6 +48,8 @@ namespace tizen_cpp { constexpr const char K_SERVICE_THREAD[] = "__K_SERVICE_THREAD"; +constexpr const char K_HINT_RECENT_SCREEN_POSITION[] = + "__K_HINT_RECENT_SCREEN_POSITION"; void SetComm(const std::string& name) { pid_t tid = syscall(__NR_gettid); @@ -69,7 +73,8 @@ class AppCoreUiBase::Impl { : parent_(parent), hint_(hint), handler_(std::make_shared(parent)), - wl_handler_(new WaylandHandler()) { + wl_handler_(new WaylandHandler()), + wp_manager_(new WindowPositionManager()) { } private: @@ -105,24 +110,6 @@ class AppCoreUiBase::Impl { } }; - class WindowPosition { - public: - WindowPosition(int x, int y, int w, int h) - : x_(x), y_(y), w_(w), h_(h){ - } - - int GetPositionX() const { return x_; } - int GetPositionY() const { return y_; } - int GetScreenWidth() const { return w_; } - int GetScreenHeight() const { return h_; } - - private: - int x_; - int y_; - int w_; - int h_; - }; - void ExitFromSuspend(); void PrepareToSuspend(); void DoStart(tizen_base::Bundle b); @@ -143,6 +130,9 @@ class AppCoreUiBase::Impl { void PluginInit(int argc, char** argv); void PluginFini(); void SetWindowPosition(const tizen_base::Bundle& b); + void SetWindowPosition(); + void SetWindow(unsigned int wid); + Ecore_Wl2_Window* GetWindow() const; void Run(int argc, char** argv); void Exit(); @@ -164,6 +154,8 @@ class AppCoreUiBase::Impl { GMainContext* context_ = nullptr; std::thread thread_; std::unique_ptr position_; + Ecore_Wl2_Window* window_ = nullptr; + std::unique_ptr wp_manager_; }; AppCoreUiBase::AppCoreUiBase(unsigned int hint) @@ -190,6 +182,7 @@ bool AppCoreUiBase::Impl::AddWin(unsigned int win, unsigned int surf) { return false; } + SetWindow(win); winnode_list_.emplace_back(new WinNode(win, surf)); return true; } @@ -201,6 +194,7 @@ bool AppCoreUiBase::Impl::DeleteWin(unsigned int win) { return false; } + SetWindow(0); winnode_list_.remove_if( [win](std::shared_ptr node) { return node->win_ == win; @@ -222,6 +216,10 @@ bool AppCoreUiBase::Impl::UpdateWin(unsigned int win, unsigned int surf, if (vis != VT_NONE) node->vis_ = vis; + if (GetWindow() == nullptr) + SetWindow(win); + + SetWindowPosition(); return true; } @@ -417,24 +415,72 @@ void AppCoreUiBase::Impl::PluginFini() { } void AppCoreUiBase::Impl::SetWindowPosition(const tizen_base::Bundle& b) { - std::string x_str = b.GetString(AUL_K_HINT_SCREEN_POS_X); - if (x_str.empty()) + position_ = wp_manager_->ReadFromBundle(b); + if (position_) { + _D("x: %d, y: %d, w: %d, h: %d", + position_->GetPositionX(), position_->GetPositionY(), + position_->GetScreenWidth(), position_->GetScreenHeight()); + } + + auto recent_screen_position = b.GetString(K_HINT_RECENT_SCREEN_POSITION); + if (!recent_screen_position.empty()) { + auto position = wp_manager_->ReadFromFile(); + if (position) { + _D("x: %d, y: %d, w: %d, h: %d", + position->GetPositionX(), position->GetPositionY(), + position->GetScreenWidth(), position->GetScreenHeight()); + position_ = std::move(position); + } else { + _D("There is no window position"); + } + } + + if (position_) + wp_manager_->WriteToFile(position_); +} + +void AppCoreUiBase::Impl::SetWindowPosition() { + if (!position_) return; - std::string y_str = b.GetString(AUL_K_HINT_SCREEN_POS_Y); - if (y_str.empty()) + if (GetWindow() == nullptr) { + _E("window is nullptr"); return; + } + + int x = 0; + int y = 0; + int w = 0; + int h = 0; + ecore_wl2_window_geometry_get(GetWindow(), &x, &y, &w, &h); + + _W("x: %d, y: %d, w: %d, h: %d", w, y, w, h); + if (position_->GetPositionX() != x || + position_->GetPositionY() != y || + position_->GetScreenWidth() != w || + position_->GetScreenHeight() != h) { + position_.reset(new WindowPosition(x, y, w, h)); + wp_manager_->WriteToFile(position_); + } +} - std::string w_str = b.GetString(AUL_K_HINT_SCREEN_WIDTH); - if (w_str.empty()) +void AppCoreUiBase::Impl::SetWindow(unsigned int wid) { + if (wid == 0) { + window_ = nullptr; return; + } - std::string h_str = b.GetString(AUL_K_HINT_SCREEN_HEIGHT); - if (h_str.empty()) + window_ = ecore_wl2_window_find(wid); + if (window_ == nullptr) { + _E("ecore_wl2_window_find() is failed. wid(%u)", wid); return; + } + + _D("wid(%u), window(%p)", wid, window_); +} - position_ = std::make_unique( - std::stoi(x_str), std::stoi(y_str), std::stoi(w_str), std::stoi(h_str)); +Ecore_Wl2_Window* AppCoreUiBase::Impl::GetWindow() const { + return window_; } void AppCoreUiBase::DoRun(int argc, char** argv) { @@ -481,7 +527,7 @@ void AppCoreUiBase::DoExit() { void AppCoreUiBase::Impl::Run(int argc, char** argv) { if (hint_ & HINT_DUAL_THREAD) { // For the loader case - while (ecore_shutdown() != 0); + while (ecore_shutdown() != 0) {} service_ = parent_->CreateTask(); context_ = g_main_context_new(); @@ -816,8 +862,9 @@ void AppCoreUiBase::OnShow(int type, void* event) { else impl_->UpdateWin(win, surf, Impl::VT_NONE); - if (surf != 0) + if (surf != 0) { GroupAdd(); + } } bool AppCoreUiBase::Impl::CheckVisible() { diff --git a/tizen-cpp/app-core-ui-cpp/window_position_private.cc b/tizen-cpp/app-core-ui-cpp/window_position_private.cc new file mode 100644 index 0000000..ffdb5ac --- /dev/null +++ b/tizen-cpp/app-core-ui-cpp/window_position_private.cc @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "app-core-ui-cpp/window_position_private.hh" + +#include +#include +#include + +#include +#include +#include + +#include "common/log_private.hh" + +namespace tizen_cpp { +namespace { + +constexpr const char PATH_AUL[] = "/run/aul/apps/"; +constexpr uid_t REGULAR_UID_MIN = 5000; + +std::string WindowPositionToRaw( + const std::unique_ptr& win_pos) { + tizen_base::Bundle b { + { AUL_K_HINT_SCREEN_POS_X, std::to_string(win_pos->GetPositionX()) }, + { AUL_K_HINT_SCREEN_POS_Y, std::to_string(win_pos->GetPositionY()) }, + { AUL_K_HINT_SCREEN_WIDTH, std::to_string(win_pos->GetScreenWidth()) }, + { AUL_K_HINT_SCREEN_HEIGHT, std::to_string(win_pos->GetScreenHeight()) }, + }; + + return std::string(reinterpret_cast(b.ToRaw().first.get())); +} + +std::unique_ptr WindowPositionFromBundle( + const tizen_base::Bundle& b) { + auto x_str = b.GetString(AUL_K_HINT_SCREEN_POS_X); + if (x_str.empty()) + return nullptr; + + auto y_str = b.GetString(AUL_K_HINT_SCREEN_POS_Y); + if (y_str.empty()) + return nullptr; + + auto w_str = b.GetString(AUL_K_HINT_SCREEN_WIDTH); + if (w_str.empty()) + return nullptr; + + auto h_str = b.GetString(AUL_K_HINT_SCREEN_HEIGHT); + if (h_str.empty()) + return nullptr; + + return std::make_unique(std::stoi(x_str), + std::stoi(y_str), std::stoi(w_str), std::stoi(h_str)); +} + +std::unique_ptr WindowPositionFromRaw( + const std::string& raw) { + tizen_base::Bundle b(raw); + return WindowPositionFromBundle(b); +} + +std::string GetAulAppPath() { + static std::string path; + + if (!path.empty() || getuid() < REGULAR_UID_MIN) + return path; + + char appid[256] = { 0, }; + int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)); + if (ret != AUL_R_OK) { + _E("aul_app_get_appid_bypid() is failed. error(%d)", ret); + return {}; + } + + path = PATH_AUL + std::to_string(getuid()) + "/." + std::string(appid); + return path; +} + +} // namespace + +WindowPosition::WindowPosition(int x, int y, int w, int h) + : x_(x), y_(y), w_(w), h_(h) { +} + +int WindowPosition::GetPositionX() const { + return x_; +} + +int WindowPosition::GetPositionY() const { + return y_; +} + +int WindowPosition::GetScreenWidth() const { + return w_; +} + +int WindowPosition::GetScreenHeight() const { + return h_; +} + +void WindowPositionManager::WriteToFile( + const std::unique_ptr& win_pos) { + std::string raw = WindowPositionToRaw(win_pos); + std::ofstream stream(GetAulAppPath()); + stream << raw; + stream.close(); +} + +std::unique_ptr WindowPositionManager::ReadFromFile() { + std::ifstream stream(GetAulAppPath()); + if (!stream.good()) { + _W("There is no files"); + stream.close(); + return nullptr; + } + + std::string raw; + stream >> raw; + stream.close(); + if (raw.empty()) + return nullptr; + + return WindowPositionFromRaw(raw); +} + +std::unique_ptr WindowPositionManager::ReadFromBundle( + const tizen_base::Bundle& b) { + return WindowPositionFromBundle(b); +} + +} // namespace tizen_cpp diff --git a/tizen-cpp/app-core-ui-cpp/window_position_private.hh b/tizen-cpp/app-core-ui-cpp/window_position_private.hh new file mode 100644 index 0000000..a7066be --- /dev/null +++ b/tizen-cpp/app-core-ui-cpp/window_position_private.hh @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_ +#define TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_ + +#include + +#include + +namespace tizen_cpp { + +class WindowPosition { + public: + WindowPosition(int x, int y, int w, int h); + + int GetPositionX() const; + int GetPositionY() const; + int GetScreenWidth() const; + int GetScreenHeight() const; + + private: + int x_; + int y_; + int w_; + int h_; +}; + +class WindowPositionManager { + public: + WindowPositionManager() = default; + + void WriteToFile(const std::unique_ptr& win_pos); + std::unique_ptr ReadFromFile(); + std::unique_ptr ReadFromBundle(const tizen_base::Bundle& b); +}; + +} // namespace tizen_cpp + +#endif // TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_ -- 2.7.4