Set focus to current active window
This commit is contained in:
parent
161099057b
commit
84b3fa430b
15 changed files with 189 additions and 41 deletions
|
|
@ -29,6 +29,7 @@ LOCAL_SRC_FILES := \
|
||||||
android/service/host_connector.cpp \
|
android/service/host_connector.cpp \
|
||||||
android/service/local_socket_connection.cpp \
|
android/service/local_socket_connection.cpp \
|
||||||
android/service/message_processor.cpp \
|
android/service/message_processor.cpp \
|
||||||
|
android/service/activity_manager_interface.cpp \
|
||||||
android/service/android_api_skeleton.cpp \
|
android/service/android_api_skeleton.cpp \
|
||||||
android/service/platform_service_interface.cpp \
|
android/service/platform_service_interface.cpp \
|
||||||
android/service/platform_service.cpp \
|
android/service/platform_service.cpp \
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ set(ANBOXD_SOURCES
|
||||||
${CMAKE_SOURCE_DIR}/src/anbox/rpc/message_processor.cpp
|
${CMAKE_SOURCE_DIR}/src/anbox/rpc/message_processor.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/anbox/rpc/pending_call_cache.cpp
|
${CMAKE_SOURCE_DIR}/src/anbox/rpc/pending_call_cache.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/anbox/common/fd.cpp
|
${CMAKE_SOURCE_DIR}/src/anbox/common/fd.cpp
|
||||||
|
service/activity_manager_interface.cpp
|
||||||
service/platform_service.cpp
|
service/platform_service.cpp
|
||||||
service/platform_service_interface.cpp
|
service/platform_service_interface.cpp
|
||||||
service/platform_api_stub.cpp
|
service/platform_api_stub.cpp
|
||||||
|
|
|
||||||
35
android/service/activity_manager_interface.cpp
Normal file
35
android/service/activity_manager_interface.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 3, as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||||
|
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "Anboxd"
|
||||||
|
|
||||||
|
#include "android/service/activity_manager_interface.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
BpActivityManager::BpActivityManager(const sp<IBinder> &binder) :
|
||||||
|
BpInterface<IActivityManager>(binder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t BpActivityManager::setFocusedTask(int32_t id) {
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
|
||||||
|
data.writeInt32(id);
|
||||||
|
return remote()->transact(IActivityManager::SET_FOCUSED_TASK, data, &reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_META_INTERFACE(ActivityManager, "android.app.IActivityManager");
|
||||||
|
} // namespace android
|
||||||
50
android/service/activity_manager_interface.h
Normal file
50
android/service/activity_manager_interface.h
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 3, as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||||
|
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANBOX_ANDROID_ACTIVITY_MANAGER_INTERFACE_H_
|
||||||
|
#define ANBOX_ANDROID_ACTIVITY_MANAGER_INTERFACE_H_
|
||||||
|
|
||||||
|
#include <binder/IBinder.h>
|
||||||
|
#include <binder/IInterface.h>
|
||||||
|
#include <binder/Parcel.h>
|
||||||
|
|
||||||
|
#include <utils/String16.h>
|
||||||
|
#include <utils/StrongPointer.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
class IActivityManager : public IInterface {
|
||||||
|
public:
|
||||||
|
DECLARE_META_INTERFACE(ActivityManager);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// This needs to stay synchronized with frameworks/base/core/java/android/app/IActivityManager.java
|
||||||
|
SET_FOCUSED_TASK = IBinder::FIRST_CALL_TRANSACTION + 130,
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual status_t setFocusedTask(int32_t id) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BpActivityManager : public BpInterface<IActivityManager> {
|
||||||
|
public:
|
||||||
|
BpActivityManager(const sp<IBinder> &binder);
|
||||||
|
|
||||||
|
status_t setFocusedTask(int32_t id) override;
|
||||||
|
};
|
||||||
|
} // namespace android
|
||||||
|
#endif
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "Anboxd"
|
||||||
|
|
||||||
#include "android/service/android_api_skeleton.h"
|
#include "android/service/android_api_skeleton.h"
|
||||||
|
|
||||||
#include "anbox_rpc.pb.h"
|
#include "anbox_rpc.pb.h"
|
||||||
|
|
@ -23,6 +25,8 @@
|
||||||
#include <core/posix/exec.h>
|
#include <core/posix/exec.h>
|
||||||
#include <core/posix/child_process.h>
|
#include <core/posix/child_process.h>
|
||||||
|
|
||||||
|
#include <binder/IServiceManager.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::map<std::string,std::string> common_env = {
|
std::map<std::string,std::string> common_env = {
|
||||||
{"ANDROID_DATA", "/data"},
|
{"ANDROID_DATA", "/data"},
|
||||||
|
|
@ -48,6 +52,14 @@ void AndroidApiSkeleton::wait_for_process(core::posix::ChildProcess &process,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidApiSkeleton::connect_services() {
|
||||||
|
if (!activity_manager_.get()) {
|
||||||
|
auto am = android::defaultServiceManager()->getService(android::String16("activity"));
|
||||||
|
if (am.get())
|
||||||
|
activity_manager_ = new android::BpActivityManager(am);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidApiSkeleton::install_application(anbox::protobuf::bridge::InstallApplication const *request,
|
void AndroidApiSkeleton::install_application(anbox::protobuf::bridge::InstallApplication const *request,
|
||||||
anbox::protobuf::rpc::Void *response,
|
anbox::protobuf::rpc::Void *response,
|
||||||
google::protobuf::Closure *done) {
|
google::protobuf::Closure *done) {
|
||||||
|
|
@ -106,4 +118,19 @@ void AndroidApiSkeleton::set_dns_servers(anbox::protobuf::bridge::SetDnsServers
|
||||||
|
|
||||||
done->Run();
|
done->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidApiSkeleton::set_focused_task(anbox::protobuf::bridge::SetFocusedTask const *request,
|
||||||
|
anbox::protobuf::rpc::Void *response,
|
||||||
|
google::protobuf::Closure *done) {
|
||||||
|
(void) response;
|
||||||
|
|
||||||
|
connect_services();
|
||||||
|
|
||||||
|
if (activity_manager_.get())
|
||||||
|
activity_manager_->setFocusedTask(request->id());
|
||||||
|
else
|
||||||
|
response->set_error("ActivityManager is not available");
|
||||||
|
|
||||||
|
done->Run();
|
||||||
|
}
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#ifndef ANBOX_PLATFORM_API_SKELETON_H_
|
#ifndef ANBOX_PLATFORM_API_SKELETON_H_
|
||||||
#define ANBOX_PLATFORM_API_SKELETON_H_
|
#define ANBOX_PLATFORM_API_SKELETON_H_
|
||||||
|
|
||||||
|
#include "android/service/activity_manager_interface.h"
|
||||||
|
|
||||||
namespace google {
|
namespace google {
|
||||||
namespace protobuf {
|
namespace protobuf {
|
||||||
class Closure;
|
class Closure;
|
||||||
|
|
@ -36,6 +38,7 @@ namespace bridge {
|
||||||
class InstallApplication;
|
class InstallApplication;
|
||||||
class LaunchApplication;
|
class LaunchApplication;
|
||||||
class SetDnsServers;
|
class SetDnsServers;
|
||||||
|
class SetFocusedTask;
|
||||||
} // namespace bridge
|
} // namespace bridge
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
class Void;
|
class Void;
|
||||||
|
|
@ -58,9 +61,17 @@ public:
|
||||||
anbox::protobuf::rpc::Void *response,
|
anbox::protobuf::rpc::Void *response,
|
||||||
google::protobuf::Closure *done);
|
google::protobuf::Closure *done);
|
||||||
|
|
||||||
|
void set_focused_task(anbox::protobuf::bridge::SetFocusedTask const *request,
|
||||||
|
anbox::protobuf::rpc::Void *response,
|
||||||
|
google::protobuf::Closure *done);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void wait_for_process(core::posix::ChildProcess &process,
|
void wait_for_process(core::posix::ChildProcess &process,
|
||||||
anbox::protobuf::rpc::Void *response);
|
anbox::protobuf::rpc::Void *response);
|
||||||
|
|
||||||
|
void connect_services();
|
||||||
|
|
||||||
|
android::sp<android::BpActivityManager> activity_manager_;
|
||||||
};
|
};
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ void MessageProcessor::dispatch(rpc::Invocation const& invocation) {
|
||||||
invoke(this, platform_api_.get(), &AndroidApiSkeleton::launch_application, invocation);
|
invoke(this, platform_api_.get(), &AndroidApiSkeleton::launch_application, invocation);
|
||||||
else if (invocation.method_name() == "set_dns_servers")
|
else if (invocation.method_name() == "set_dns_servers")
|
||||||
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_dns_servers, invocation);
|
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_dns_servers, invocation);
|
||||||
|
else if (invocation.method_name() == "set_focused_task")
|
||||||
|
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_focused_task, invocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageProcessor::process_event_sequence(const std::string&) {
|
void MessageProcessor::process_event_sequence(const std::string&) {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ void AndroidApiStub::install(const std::string &path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidApiStub::application_installed(Request<protobuf::rpc::Void> *request) {
|
void AndroidApiStub::application_installed(Request<protobuf::rpc::Void> *request) {
|
||||||
|
(void) request;
|
||||||
install_wait_handle_.result_received();
|
install_wait_handle_.result_received();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,6 +111,7 @@ void AndroidApiStub::launch(const std::string &package, const std::string &activ
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidApiStub::application_launched(Request<protobuf::rpc::Void> *request) {
|
void AndroidApiStub::application_launched(Request<protobuf::rpc::Void> *request) {
|
||||||
|
(void) request;
|
||||||
launch_wait_handle_.result_received();
|
launch_wait_handle_.result_received();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,7 +145,37 @@ void AndroidApiStub::set_dns_servers(const std::string &domain, const std::vecto
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidApiStub::dns_servers_set(Request<protobuf::rpc::Void> *request) {
|
void AndroidApiStub::dns_servers_set(Request<protobuf::rpc::Void> *request) {
|
||||||
|
(void) request;
|
||||||
set_dns_servers_wait_handle_.result_received();
|
set_dns_servers_wait_handle_.result_received();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidApiStub::set_focused_task(const std::int32_t &id) {
|
||||||
|
ensure_rpc_channel();
|
||||||
|
|
||||||
|
auto c = std::make_shared<Request<protobuf::rpc::Void>>();
|
||||||
|
|
||||||
|
protobuf::bridge::SetFocusedTask message;
|
||||||
|
message.set_id(id);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
set_focused_task_handle_.expect_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_->call_method("set_focused_task",
|
||||||
|
&message,
|
||||||
|
c->response.get(),
|
||||||
|
google::protobuf::NewCallback(this, &AndroidApiStub::focused_task_set, c.get()));
|
||||||
|
|
||||||
|
set_focused_task_handle_.wait_for_all();
|
||||||
|
|
||||||
|
if (c->response->has_error())
|
||||||
|
throw std::runtime_error(c->response->error());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidApiStub::focused_task_set(Request<protobuf::rpc::Void> *request) {
|
||||||
|
(void) request;
|
||||||
|
set_focused_task_handle_.result_received();
|
||||||
|
}
|
||||||
} // namespace bridge
|
} // namespace bridge
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ public:
|
||||||
void launch(const std::string &package, const std::string &activity) override;
|
void launch(const std::string &package, const std::string &activity) override;
|
||||||
|
|
||||||
void set_dns_servers(const std::string &domain, const std::vector<std::string> &servers);
|
void set_dns_servers(const std::string &domain, const std::vector<std::string> &servers);
|
||||||
|
void set_focused_task(const std::int32_t &id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ensure_rpc_channel();
|
void ensure_rpc_channel();
|
||||||
|
|
@ -60,12 +61,14 @@ private:
|
||||||
void application_installed(Request<protobuf::rpc::Void> *request);
|
void application_installed(Request<protobuf::rpc::Void> *request);
|
||||||
void application_launched(Request<protobuf::rpc::Void> *request);
|
void application_launched(Request<protobuf::rpc::Void> *request);
|
||||||
void dns_servers_set(Request<protobuf::rpc::Void> *request);
|
void dns_servers_set(Request<protobuf::rpc::Void> *request);
|
||||||
|
void focused_task_set(Request<protobuf::rpc::Void> *request);
|
||||||
|
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
std::shared_ptr<rpc::Channel> channel_;
|
std::shared_ptr<rpc::Channel> channel_;
|
||||||
common::WaitHandle install_wait_handle_;
|
common::WaitHandle install_wait_handle_;
|
||||||
common::WaitHandle launch_wait_handle_;
|
common::WaitHandle launch_wait_handle_;
|
||||||
common::WaitHandle set_dns_servers_wait_handle_;
|
common::WaitHandle set_dns_servers_wait_handle_;
|
||||||
|
common::WaitHandle set_focused_task_handle_;
|
||||||
};
|
};
|
||||||
} // namespace bridge
|
} // namespace bridge
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,9 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
|
||||||
|
|
||||||
auto input_manager = std::make_shared<input::Manager>(rt);
|
auto input_manager = std::make_shared<input::Manager>(rt);
|
||||||
|
|
||||||
auto policy = std::make_shared<ubuntu::PlatformPolicy>(input_manager);
|
auto android_api_stub = std::make_shared<bridge::AndroidApiStub>();
|
||||||
|
|
||||||
|
auto policy = std::make_shared<ubuntu::PlatformPolicy>(input_manager, android_api_stub);
|
||||||
// FIXME this needs to be removed and solved differently behind the scenes
|
// FIXME this needs to be removed and solved differently behind the scenes
|
||||||
registerDisplayManager(policy);
|
registerDisplayManager(policy);
|
||||||
|
|
||||||
|
|
@ -116,7 +118,6 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
|
||||||
renderer->socket_path(),
|
renderer->socket_path(),
|
||||||
icon_));
|
icon_));
|
||||||
|
|
||||||
auto android_api_stub = std::make_shared<bridge::AndroidApiStub>();
|
|
||||||
|
|
||||||
auto bridge_connector = std::make_shared<network::PublishedSocketConnector>(
|
auto bridge_connector = std::make_shared<network::PublishedSocketConnector>(
|
||||||
utils::string_format("%s/anbox_bridge", config::socket_path()),
|
utils::string_format("%s/anbox_bridge", config::socket_path()),
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ message SetDnsServers {
|
||||||
repeated Server servers = 2;
|
repeated Server servers = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SetFocusedTask {
|
||||||
|
required int32 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message BootFinishedEvent {
|
message BootFinishedEvent {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "anbox/ubuntu/keycode_converter.h"
|
#include "anbox/ubuntu/keycode_converter.h"
|
||||||
#include "anbox/input/manager.h"
|
#include "anbox/input/manager.h"
|
||||||
#include "anbox/input/device.h"
|
#include "anbox/input/device.h"
|
||||||
|
#include "anbox/bridge/android_api_stub.h"
|
||||||
#include "anbox/logger.h"
|
#include "anbox/logger.h"
|
||||||
|
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
@ -199,6 +200,15 @@ void PlatformPolicy::window_deleted(const Window::Id &id) {
|
||||||
windows_.erase(w);
|
windows_.erase(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlatformPolicy::window_wants_focus(const Window::Id &id) {
|
||||||
|
auto w = windows_.find(id);
|
||||||
|
if (w == windows_.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (auto window = w->second.lock())
|
||||||
|
android_api_->set_focused_task(window->task());
|
||||||
|
}
|
||||||
|
|
||||||
DisplayManager::DisplayInfo PlatformPolicy::display_info() const {
|
DisplayManager::DisplayInfo PlatformPolicy::display_info() const {
|
||||||
return display_info_;
|
return display_info_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,18 +33,23 @@ namespace input {
|
||||||
class Device;
|
class Device;
|
||||||
class Manager;
|
class Manager;
|
||||||
} // namespace input
|
} // namespace input
|
||||||
|
namespace bridge {
|
||||||
|
class AndroidApiStub;
|
||||||
|
} // namespace bridge
|
||||||
namespace ubuntu {
|
namespace ubuntu {
|
||||||
class PlatformPolicy : public std::enable_shared_from_this<PlatformPolicy>,
|
class PlatformPolicy : public std::enable_shared_from_this<PlatformPolicy>,
|
||||||
public wm::PlatformPolicy,
|
public wm::PlatformPolicy,
|
||||||
public Window::Observer,
|
public Window::Observer,
|
||||||
public DisplayManager {
|
public DisplayManager {
|
||||||
public:
|
public:
|
||||||
PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager);
|
PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager,
|
||||||
|
const std::shared_ptr<bridge::AndroidApiStub> &android_api);
|
||||||
~PlatformPolicy();
|
~PlatformPolicy();
|
||||||
|
|
||||||
std::shared_ptr<wm::Window> create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) override;
|
std::shared_ptr<wm::Window> create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) override;
|
||||||
|
|
||||||
void window_deleted(const Window::Id &id) override;
|
void window_deleted(const Window::Id &id) override;
|
||||||
|
void window_wants_focus(const Window::Id &id) override;
|
||||||
|
|
||||||
DisplayInfo display_info() const override;
|
DisplayInfo display_info() const override;
|
||||||
|
|
||||||
|
|
@ -55,6 +60,7 @@ private:
|
||||||
static Window::Id next_window_id();
|
static Window::Id next_window_id();
|
||||||
|
|
||||||
std::shared_ptr<input::Manager> input_manager_;
|
std::shared_ptr<input::Manager> input_manager_;
|
||||||
|
std::shared_ptr<bridge::AndroidApiStub> android_api_;
|
||||||
// We don't own the windows anymore after the got created by us so we
|
// We don't own the windows anymore after the got created by us so we
|
||||||
// need to be careful once we try to use them again.
|
// need to be careful once we try to use them again.
|
||||||
std::map<Window::Id, std::weak_ptr<Window>> windows_;
|
std::map<Window::Id, std::weak_ptr<Window>> windows_;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ Window::Window(const Id &id,
|
||||||
SDL_GetWindowWMInfo(window_, &info);
|
SDL_GetWindowWMInfo(window_, &info);
|
||||||
switch (info.subsystem) {
|
switch (info.subsystem) {
|
||||||
case SDL_SYSWM_X11:
|
case SDL_SYSWM_X11:
|
||||||
DEBUG("Running on X11");
|
|
||||||
native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
|
native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
|
||||||
native_window_ = static_cast<EGLNativeWindowType>(info.info.x11.window);
|
native_window_ = static_cast<EGLNativeWindowType>(info.info.x11.window);
|
||||||
break;
|
break;
|
||||||
|
|
@ -75,41 +74,6 @@ Window::Window(const Id &id,
|
||||||
int actual_x = 0, actual_y = 0;
|
int actual_x = 0, actual_y = 0;
|
||||||
SDL_GetWindowSize(window_, &actual_width, &actual_height);
|
SDL_GetWindowSize(window_, &actual_width, &actual_height);
|
||||||
SDL_GetWindowPosition(window_, &actual_x, &actual_y);
|
SDL_GetWindowPosition(window_, &actual_x, &actual_y);
|
||||||
DEBUG("Window created {%d,%d,%d,%d}", actual_x, actual_y, actual_width, actual_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
Window::Window(int x, int y, int width, int height) :
|
|
||||||
wm::Window(0, graphics::Rect{x,y,x + width,y + height}),
|
|
||||||
native_display_(0),
|
|
||||||
native_window_(0) {
|
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
|
||||||
|
|
||||||
window_ = SDL_CreateWindow("anbox", x, y, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
|
|
||||||
if (!window_) {
|
|
||||||
const auto message = utils::string_format("Failed to create window: %s", SDL_GetError());
|
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SysWMinfo info;
|
|
||||||
SDL_VERSION(&info.version);
|
|
||||||
SDL_GetWindowWMInfo(window_, &info);
|
|
||||||
switch (info.subsystem) {
|
|
||||||
case SDL_SYSWM_X11:
|
|
||||||
DEBUG("Running on X11");
|
|
||||||
native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
|
|
||||||
native_window_ = static_cast<EGLNativeWindowType>(info.info.x11.window);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR("Unknown subsystem (%d)", info.subsystem);
|
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not suported"));
|
|
||||||
}
|
|
||||||
|
|
||||||
int actual_width = 0, actual_height = 0;
|
|
||||||
int actual_x = 0, actual_y = 0;
|
|
||||||
SDL_GetWindowSize(window_, &actual_width, &actual_height);
|
|
||||||
SDL_GetWindowPosition(window_, &actual_x, &actual_y);
|
|
||||||
DEBUG("Window created {%d,%d,%d,%d}", actual_x, actual_y, actual_width, actual_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
|
|
@ -129,8 +93,10 @@ void Window::update_position(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::process_event(const SDL_Event &event) {
|
void Window::process_event(const SDL_Event &event) {
|
||||||
switch (event.window.type) {
|
switch (event.window.event) {
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||||
|
if (observer_)
|
||||||
|
observer_->window_wants_focus(id_);
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual ~Observer();
|
virtual ~Observer();
|
||||||
virtual void window_deleted(const Id &id) = 0;
|
virtual void window_deleted(const Id &id) = 0;
|
||||||
|
virtual void window_wants_focus(const Id &id) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Window(const Id &id, const wm::Task::Id &task, const std::shared_ptr<Observer> &observer, const graphics::Rect &frame);
|
Window(const Id &id, const wm::Task::Id &task, const std::shared_ptr<Observer> &observer, const graphics::Rect &frame);
|
||||||
Window(int x, int y, int width, int height);
|
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
void process_event(const SDL_Event &event);
|
void process_event(const SDL_Event &event);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue