mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-06-10 17:34:57 +08:00
[feat] add a control bar shortcut menu for sending Ctrl+Alt+Del and remote lock commands
This commit is contained in:
@@ -40,7 +40,7 @@ typedef enum {
|
||||
wheel_horizontal
|
||||
} MouseFlag;
|
||||
typedef enum { key_down = 0, key_up } KeyFlag;
|
||||
typedef enum { send_sas = 0 } ServiceCommandFlag;
|
||||
typedef enum { send_sas = 0, lock_workstation } ServiceCommandFlag;
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
@@ -235,4 +235,4 @@ class DeviceController {
|
||||
// virtual int Unhook();
|
||||
};
|
||||
} // namespace crossdesk
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -51,7 +51,9 @@ struct TranslationRow {
|
||||
X(release_mouse, u8"释放", "Release", u8"Освободить") \
|
||||
X(audio_capture, u8"声音", "Audio", u8"Звук") \
|
||||
X(mute, u8" 静音", " Mute", u8"Без звука") \
|
||||
X(send_shortcut, u8"发送组合键", "Send Shortcut", u8"Сочетания клавиш") \
|
||||
X(send_sas, u8"发送SAS", "Send SAS", u8"Отправить SAS") \
|
||||
X(lock_remote, u8"锁定远端", "Lock Remote", u8"Заблокировать") \
|
||||
X(remote_password_box_visible, u8"远端密码框已出现", \
|
||||
"Remote password box visible", u8"Окно ввода пароля видно") \
|
||||
X(remote_lock_screen_hint, u8"远端处于锁屏封面,可发送SAS", \
|
||||
|
||||
@@ -204,11 +204,11 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
props->params_.user_id = props->local_id_.c_str();
|
||||
props->peer_ = CreatePeer(&props->params_);
|
||||
|
||||
props->control_window_width_ = title_bar_height_ * 9.0f;
|
||||
props->control_window_width_ = title_bar_height_ * 10.0f;
|
||||
props->control_window_height_ = title_bar_height_ * 1.3f;
|
||||
props->control_window_min_width_ = title_bar_height_ * 0.65f;
|
||||
props->control_window_min_height_ = title_bar_height_ * 1.3f;
|
||||
props->control_window_max_width_ = title_bar_height_ * 9.0f;
|
||||
props->control_window_max_width_ = title_bar_height_ * 10.0f;
|
||||
props->control_window_max_height_ = title_bar_height_ * 7.0f;
|
||||
|
||||
props->connection_status_ = ConnectionStatus::Connecting;
|
||||
@@ -272,4 +272,4 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace crossdesk
|
||||
} // namespace crossdesk
|
||||
|
||||
+3
-2
@@ -115,6 +115,7 @@ class Render {
|
||||
bool is_control_bar_in_left_ = true;
|
||||
bool control_bar_hovered_ = false;
|
||||
bool display_selectable_hovered_ = false;
|
||||
bool shortcut_selectable_hovered_ = false;
|
||||
bool control_bar_expand_ = true;
|
||||
bool reset_control_bar_pos_ = false;
|
||||
bool control_window_width_is_changing_ = false;
|
||||
@@ -125,10 +126,10 @@ class Render {
|
||||
float sub_stream_window_width_ = 1280;
|
||||
float sub_stream_window_height_ = 720;
|
||||
float control_window_min_width_ = 20;
|
||||
float control_window_max_width_ = 230;
|
||||
float control_window_max_width_ = 300;
|
||||
float control_window_min_height_ = 38;
|
||||
float control_window_max_height_ = 180;
|
||||
float control_window_width_ = 230;
|
||||
float control_window_width_ = 300;
|
||||
float control_window_height_ = 38;
|
||||
float control_bar_pos_x_ = 0;
|
||||
float control_bar_pos_y_ = 30;
|
||||
|
||||
@@ -563,9 +563,9 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
||||
|
||||
const bool file_transfer_window_hovered =
|
||||
props->file_transfer_.file_transfer_window_hovered_;
|
||||
const bool overlay_hovered = props->control_bar_hovered_ ||
|
||||
props->display_selectable_hovered_ ||
|
||||
file_transfer_window_hovered;
|
||||
const bool overlay_hovered =
|
||||
props->control_bar_hovered_ || props->display_selectable_hovered_ ||
|
||||
props->shortcut_selectable_hovered_ || file_transfer_window_hovered;
|
||||
|
||||
const SDL_FRect render_rect = props->stream_render_rect_f_;
|
||||
if (render_rect.w <= 1.0f || render_rect.h <= 1.0f) {
|
||||
@@ -1063,6 +1063,11 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
||||
if (remote_action.c.flag == ServiceCommandFlag::send_sas) {
|
||||
render->pending_windows_service_sas_.store(true,
|
||||
std::memory_order_relaxed);
|
||||
} else if (remote_action.c.flag == ServiceCommandFlag::lock_workstation) {
|
||||
if (!LockWorkStation()) {
|
||||
LOG_WARN("Remote lock workstation request failed, error={}",
|
||||
GetLastError());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
|
||||
@@ -195,6 +195,61 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
text_pos, IM_COL32(0, 0, 0, 255),
|
||||
std::to_string(props->selected_display_ + 1).c_str());
|
||||
|
||||
auto send_service_command = [&](ServiceCommandFlag flag,
|
||||
const char* log_action) {
|
||||
if (props->connection_status_ == ConnectionStatus::Connected &&
|
||||
props->peer_) {
|
||||
RemoteAction remote_action;
|
||||
remote_action.type = ControlType::service_command;
|
||||
remote_action.c.flag = flag;
|
||||
std::string msg = remote_action.to_json();
|
||||
int ret = SendReliableDataFrame(props->peer_, msg.c_str(), msg.size(),
|
||||
props->control_data_label_.c_str());
|
||||
if (ret != 0) {
|
||||
LOG_WARN("Send {} command failed, remote_id={}, ret={}", log_action,
|
||||
props->remote_id_, ret);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string shortcut = ICON_FA_KEYBOARD;
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
if (ImGui::Button(shortcut.c_str(), ImVec2(button_width, button_height))) {
|
||||
ImGui::OpenPopup("shortcut");
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
ImGui::Text(
|
||||
"%s",
|
||||
localization::send_shortcut[localization_language_index_].c_str());
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
props->shortcut_selectable_hovered_ = false;
|
||||
if (ImGui::BeginPopup("shortcut")) {
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
std::string sas_label =
|
||||
"Ctrl+Alt+Del - " +
|
||||
localization::send_sas[localization_language_index_];
|
||||
std::string lock_label =
|
||||
"Win+L - " + localization::lock_remote[localization_language_index_];
|
||||
if (ImGui::Selectable(sas_label.c_str())) {
|
||||
send_service_command(ServiceCommandFlag::send_sas, "SAS");
|
||||
}
|
||||
if (ImGui::Selectable(lock_label.c_str())) {
|
||||
send_service_command(ServiceCommandFlag::lock_workstation,
|
||||
"remote lock");
|
||||
}
|
||||
props->shortcut_selectable_hovered_ =
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
float mouse_x = ImGui::GetCursorScreenPos().x;
|
||||
float mouse_y = ImGui::GetCursorScreenPos().y;
|
||||
|
||||
@@ -55,6 +55,22 @@ bool ExpectResetBeforeDisplayPopup(const std::string& value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExpectResetBeforeShortcutPopup(const std::string& value) {
|
||||
const std::string reset = "props->shortcut_selectable_hovered_ = false;";
|
||||
const std::string popup = "ImGui::BeginPopup(\"shortcut\")";
|
||||
const size_t reset_pos = value.find(reset);
|
||||
const size_t popup_pos = value.find(popup);
|
||||
|
||||
if (reset_pos != std::string::npos && popup_pos != std::string::npos &&
|
||||
reset_pos < popup_pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::cerr << "control_bar.cpp must clear shortcut_selectable_hovered_ before "
|
||||
"checking the shortcut popup\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
@@ -74,5 +90,8 @@ int main() {
|
||||
"ImGui::IsWindowHovered("
|
||||
"ImGuiHoveredFlags_RootAndChildWindows)");
|
||||
ok &= ExpectResetBeforeDisplayPopup(control_bar);
|
||||
ok &= ExpectContains("control_bar.cpp", control_bar,
|
||||
"props->shortcut_selectable_hovered_ =");
|
||||
ok &= ExpectResetBeforeShortcutPopup(control_bar);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user