Compare commits

...

11 Commits

8 changed files with 65 additions and 110 deletions

View File

@@ -15,76 +15,28 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs: jobs:
# Linux amd64 build-linux:
build-linux-amd64: name: Build Linux (${{ matrix.arch }})
name: Build on Ubuntu 22.04 amd64 runs-on: ${{ matrix.runner }}
runs-on: ubuntu-22.04
container:
image: crossdesk/ubuntu20.04:latest
options: --user root
steps:
- name: Extract version number
id: version
run: |
VERSION="${GITHUB_REF##*/}"
VERSION_NUM="${VERSION#v}"
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
- name: Set legal Debian version
shell: bash
id: set_deb_version
run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d)
if [[ ! "${VERSION_NUM}" =~ ^[0-9] ]]; then
LEGAL_VERSION="v0.0.0-${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}"
else
LEGAL_VERSION="v${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}"
fi
echo "LEGAL_VERSION=${LEGAL_VERSION}" >> $GITHUB_ENV
echo "BUILD_DATE=${BUILD_DATE}" >> $GITHUB_ENV
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Build CrossDesk
env:
CUDA_PATH: /usr/local/cuda
XMAKE_GLOBALDIR: /data
run: |
ls -la $XMAKE_GLOBALDIR
xmake f --CROSSDESK_VERSION=${LEGAL_VERSION} --USE_CUDA=true --root -y
xmake b -vy --root crossdesk
- name: Package
run: |
chmod +x ./scripts/linux/pkg_amd64.sh
./scripts/linux/pkg_amd64.sh ${LEGAL_VERSION}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: crossdesk-linux-amd64-${{ env.LEGAL_VERSION }}
path: ${{ github.workspace }}/crossdesk-linux-amd64-${{ env.LEGAL_VERSION }}.deb
# Linux arm64
build-linux-arm64:
name: Build on Ubuntu 22.04 arm64
runs-on: ubuntu-22.04-arm
strategy: strategy:
matrix: matrix:
include: include:
- arch: amd64
runner: ubuntu-22.04
image: crossdesk/ubuntu20.04:latest
package_script: ./scripts/linux/pkg_amd64.sh
- arch: arm64 - arch: arm64
runner: ubuntu-22.04-arm
image: crossdesk/ubuntu20.04-arm64v8:latest image: crossdesk/ubuntu20.04-arm64v8:latest
package_script: ./scripts/linux/pkg_arm64.sh package_script: ./scripts/linux/pkg_arm64.sh
container: container:
image: ${{ matrix.image }} image: ${{ matrix.image }}
options: --user root options: --user root
steps: steps:
- name: Extract version number - name: Extract version number
id: version
run: | run: |
VERSION="${GITHUB_REF##*/}" VERSION="${GITHUB_REF##*/}"
VERSION_NUM="${VERSION#v}" VERSION_NUM="${VERSION#v}"
@@ -92,15 +44,16 @@ jobs:
- name: Set legal Debian version - name: Set legal Debian version
shell: bash shell: bash
id: set_deb_version
run: | run: |
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7) SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d) BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d)
if [[ ! "${VERSION_NUM}" =~ ^[0-9] ]]; then if [[ ! "${VERSION_NUM}" =~ ^[0-9] ]]; then
LEGAL_VERSION="v0.0.0-${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}" LEGAL_VERSION="v0.0.0-${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}"
else else
LEGAL_VERSION="v${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}" LEGAL_VERSION="v${VERSION_NUM}-${BUILD_DATE}-${SHORT_SHA}"
fi fi
echo "LEGAL_VERSION=${LEGAL_VERSION}" >> $GITHUB_ENV echo "LEGAL_VERSION=${LEGAL_VERSION}" >> $GITHUB_ENV
echo "BUILD_DATE=${BUILD_DATE}" >> $GITHUB_ENV echo "BUILD_DATE=${BUILD_DATE}" >> $GITHUB_ENV
@@ -294,7 +247,7 @@ jobs:
run: | run: |
$portableDir = "${{ github.workspace }}\portable" $portableDir = "${{ github.workspace }}\portable"
New-Item -ItemType Directory -Force -Path $portableDir New-Item -ItemType Directory -Force -Path $portableDir
Copy-Item "${{ github.workspace }}\build\windows\x64\release\crossdesk.exe" $portableDir Copy-Item "${{ github.workspace }}\build\windows\x64\release\crossdesk.exe" "$portableDir\CrossDesk.exe"
Compress-Archive -Path "$portableDir\*" -DestinationPath "${{ github.workspace }}\crossdesk-win-x64-portable-${{ env.VERSION_NUM }}.zip" Compress-Archive -Path "$portableDir\*" -DestinationPath "${{ github.workspace }}\crossdesk-win-x64-portable-${{ env.VERSION_NUM }}.zip"
- name: Upload artifact - name: Upload artifact
@@ -313,7 +266,7 @@ jobs:
name: Publish Release name: Publish Release
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
needs: needs:
[build-linux-amd64, build-linux-arm64, build-macos, build-windows-x64] [build-linux, build-macos, build-windows-x64]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@@ -46,7 +46,7 @@ ShowInstDetails show
Section "MainSection" Section "MainSection"
; Check if CrossDesk is running ; Check if CrossDesk is running
StrCpy $1 "crossdesk.exe" StrCpy $1 "CrossDesk.exe"
nsProcess::_FindProcess "$1" nsProcess::_FindProcess "$1"
Pop $R0 Pop $R0
@@ -72,7 +72,7 @@ installApp:
SetOverwrite ifnewer SetOverwrite ifnewer
; Main application executable path ; Main application executable path
File /oname=crossdesk.exe "..\..\build\windows\x64\release\crossdesk.exe" File /oname=CrossDesk.exe "..\..\build\windows\x64\release\crossdesk.exe"
; Write uninstall information ; Write uninstall information
WriteUninstaller "$INSTDIR\uninstall.exe" WriteUninstaller "$INSTDIR\uninstall.exe"
@@ -82,7 +82,7 @@ installApp:
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "DisplayIcon" "$INSTDIR\crossdesk.exe" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "DisplayIcon" "$INSTDIR\CrossDesk.exe"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "NoRepair" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_REG_KEY}" "NoRepair" 1
WriteRegStr HKCU "Software\${PRODUCT_NAME}" "InstallDir" "$INSTDIR" WriteRegStr HKCU "Software\${PRODUCT_NAME}" "InstallDir" "$INSTDIR"
@@ -90,15 +90,15 @@ SectionEnd
Section -AdditionalIcons Section -AdditionalIcons
; Desktop shortcut ; Desktop shortcut
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\crossdesk.exe" "" "$INSTDIR\crossdesk.exe" CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\CrossDesk.exe" "" "$INSTDIR\CrossDesk.exe"
; Start menu shortcut ; Start menu shortcut
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$INSTDIR\crossdesk.exe" "" "$INSTDIR\crossdesk.exe" CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" "$INSTDIR\CrossDesk.exe" "" "$INSTDIR\CrossDesk.exe"
SectionEnd SectionEnd
Section "Uninstall" Section "Uninstall"
; Check if CrossDesk is running ; Check if CrossDesk is running
StrCpy $1 "crossdesk.exe" StrCpy $1 "CrossDesk.exe"
nsProcess::_FindProcess "$1" nsProcess::_FindProcess "$1"
Pop $R0 Pop $R0
@@ -121,7 +121,7 @@ cancelUninstall:
uninstallApp: uninstallApp:
; Delete main executable and uninstaller ; Delete main executable and uninstaller
Delete "$INSTDIR\crossdesk.exe" Delete "$INSTDIR\CrossDesk.exe"
Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\uninstall.exe"
; Recursively delete installation directory ; Recursively delete installation directory
@@ -144,5 +144,5 @@ SectionEnd
; ------ Functions ------ ; ------ Functions ------
Function LaunchApp Function LaunchApp
Exec "$INSTDIR\crossdesk.exe" Exec "$INSTDIR\CrossDesk.exe"
FunctionEnd FunctionEnd

View File

@@ -205,11 +205,10 @@ static std::vector<std::string> browse = {
reinterpret_cast<const char*>(u8"浏览"), "Browse"}; reinterpret_cast<const char*>(u8"浏览"), "Browse"};
static std::vector<std::string> default_desktop = { static std::vector<std::string> default_desktop = {
reinterpret_cast<const char*>(u8"桌面"), "Desktop"}; reinterpret_cast<const char*>(u8"桌面"), "Desktop"};
#if _WIN32
static std::vector<std::string> minimize_to_tray = { static std::vector<std::string> minimize_to_tray = {
reinterpret_cast<const char*>(u8"退出时最小化到系统托盘:"), reinterpret_cast<const char*>(u8"退出时最小化到系统托盘:"),
"Minimize to system tray when exit:"}; "Minimize to system tray when exit:"};
#if _WIN32
static std::vector<LPCWSTR> exit_program = {L"退出", L"Exit"}; static std::vector<LPCWSTR> exit_program = {L"退出", L"Exit"};
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__

View File

@@ -893,7 +893,7 @@ void Render::UpdateInteractions() {
mouse_controller_is_started_ = false; mouse_controller_is_started_ = false;
} }
if (start_keyboard_capturer_ && foucs_on_stream_window_) { if (start_keyboard_capturer_ && focus_on_stream_window_) {
if (!keyboard_capturer_is_started_) { if (!keyboard_capturer_is_started_) {
StartKeyboardCapturer(); StartKeyboardCapturer();
keyboard_capturer_is_started_ = true; keyboard_capturer_is_started_ = true;
@@ -1393,23 +1393,19 @@ int Render::DrawServerWindow() {
LOG_ERROR("Server context is null"); LOG_ERROR("Server context is null");
return -1; return -1;
} }
if (server_window_) {
int w = 0;
int h = 0;
SDL_GetWindowSize(server_window_, &w, &h);
if (w > 0 && h > 0) {
server_window_width_ = (float)w;
server_window_height_ = (float)h;
}
}
ImGui::SetCurrentContext(server_ctx_); ImGui::SetCurrentContext(server_ctx_);
ImGui_ImplSDLRenderer3_NewFrame(); ImGui_ImplSDLRenderer3_NewFrame();
ImGui_ImplSDL3_NewFrame(); ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
ImGuiIO& io = ImGui::GetIO();
server_window_width_ = io.DisplaySize.x;
server_window_height_ = io.DisplaySize.y;
ServerWindow(); ServerWindow();
ImGui::Render(); ImGui::Render();
SDL_SetRenderScale(server_renderer_, io.DisplayFramebufferScale.x,
io.DisplayFramebufferScale.y);
SDL_SetRenderDrawColor(server_renderer_, 255, 255, 255, 255); SDL_SetRenderDrawColor(server_renderer_, 255, 255, 255, 255);
SDL_RenderClear(server_renderer_); SDL_RenderClear(server_renderer_);
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), server_renderer_); ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), server_renderer_);
@@ -2051,7 +2047,8 @@ void Render::UpdateRenderRect() {
(int)(render_area_width * video_ratio_reverse)}; (int)(render_area_width * video_ratio_reverse)};
} else if (render_area_width > render_area_height * video_ratio) { } else if (render_area_width > render_area_height * video_ratio) {
props->stream_render_rect_ = { props->stream_render_rect_ = {
(int)abs(render_area_width - render_area_height * video_ratio) / 2, (int)abs(render_area_width - render_area_height * video_ratio) / 2 +
(int)props->render_window_x_,
(int)props->render_window_y_, (int)(render_area_height * video_ratio), (int)props->render_window_y_, (int)(render_area_height * video_ratio),
(int)render_area_height}; (int)render_area_height};
} else { } else {
@@ -2176,7 +2173,7 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_GAINED:
if (stream_window_ && if (stream_window_ &&
SDL_GetWindowID(stream_window_) == event.window.windowID) { SDL_GetWindowID(stream_window_) == event.window.windowID) {
foucs_on_stream_window_ = true; focus_on_stream_window_ = true;
} else if (main_window_ && } else if (main_window_ &&
SDL_GetWindowID(main_window_) == event.window.windowID) { SDL_GetWindowID(main_window_) == event.window.windowID) {
foucs_on_main_window_ = true; foucs_on_main_window_ = true;
@@ -2186,7 +2183,7 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_FOCUS_LOST:
if (stream_window_ && if (stream_window_ &&
SDL_GetWindowID(stream_window_) == event.window.windowID) { SDL_GetWindowID(stream_window_) == event.window.windowID) {
foucs_on_stream_window_ = false; focus_on_stream_window_ = false;
} else if (main_window_ && } else if (main_window_ &&
SDL_GetWindowID(main_window_) == event.window.windowID) { SDL_GetWindowID(main_window_) == event.window.windowID) {
foucs_on_main_window_ = false; foucs_on_main_window_ = false;
@@ -2200,7 +2197,7 @@ void Render::ProcessSdlEvent(const SDL_Event& event) {
case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_EVENT_MOUSE_WHEEL: case SDL_EVENT_MOUSE_WHEEL:
if (foucs_on_stream_window_) { if (focus_on_stream_window_) {
ProcessMouseEvent(event); ProcessMouseEvent(event);
} }
break; break;

View File

@@ -434,7 +434,7 @@ class Render {
bool show_cursor_ = false; bool show_cursor_ = false;
bool keyboard_capturer_is_started_ = false; bool keyboard_capturer_is_started_ = false;
bool foucs_on_main_window_ = false; bool foucs_on_main_window_ = false;
bool foucs_on_stream_window_ = false; bool focus_on_stream_window_ = false;
bool main_window_minimized_ = false; bool main_window_minimized_ = false;
uint32_t last_main_minimize_request_tick_ = 0; uint32_t last_main_minimize_request_tick_ = 0;
uint32_t last_stream_minimize_request_tick_ = 0; uint32_t last_stream_minimize_request_tick_ = 0;

View File

@@ -331,10 +331,14 @@ int Render::SettingWindow() {
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
} }
#if _WIN32
ImGui::Separator(); ImGui::Separator();
{ {
#ifndef _WIN32
ImGui::BeginDisabled();
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
#endif
settings_items_offset += settings_items_padding; settings_items_offset += settings_items_padding;
ImGui::SetCursorPosY(settings_items_offset); ImGui::SetCursorPosY(settings_items_offset);
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
@@ -350,8 +354,11 @@ int Render::SettingWindow() {
ImGui::Checkbox("##enable_minimize_to_tray_", ImGui::Checkbox("##enable_minimize_to_tray_",
&enable_minimize_to_tray_); &enable_minimize_to_tray_);
} #ifndef _WIN32
ImGui::PopStyleColor();
ImGui::EndDisabled();
#endif #endif
}
ImGui::Separator(); ImGui::Separator();
@@ -365,7 +372,7 @@ int Render::SettingWindow() {
.c_str()); .c_str());
ImGui::SameLine(); ImGui::SameLine();
if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) {
ImGui::SetCursorPosX(title_bar_button_width_ * 2.8f); ImGui::SetCursorPosX(title_bar_button_width_ * 2.82f);
} else { } else {
ImGui::SetCursorPosX(title_bar_button_width_ * 4.3f); ImGui::SetCursorPosX(title_bar_button_width_ * 4.3f);
} }

View File

@@ -117,7 +117,9 @@ int Render::StreamWindow() {
ImGui::SetWindowFontScale(0.6f); ImGui::SetWindowFontScale(0.6f);
ImGui::SetNextWindowSize( ImGui::SetNextWindowSize(
ImVec2(stream_window_width_, stream_window_height_), ImVec2(stream_window_width_,
stream_window_height_ -
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
ImGuiCond_Always); ImGuiCond_Always);
ImGui::SetNextWindowPos( ImGui::SetNextWindowPos(
ImVec2(0, fullscreen_button_pressed_ ? 0 : title_bar_height_), ImVec2(0, fullscreen_button_pressed_ ? 0 : title_bar_height_),
@@ -138,7 +140,7 @@ int Render::StreamWindow() {
UpdateRenderRect(); UpdateRenderRect();
ControlWindow(props); ControlWindow(props);
// Show file transfer window if needed // Show file transfer window if needed
FileTransferWindow(props); FileTransferWindow(props);
@@ -151,12 +153,12 @@ int Render::StreamWindow() {
// std::unique_lock unique_lock(client_properties_mutex_); // std::unique_lock unique_lock(client_properties_mutex_);
auto erase_it = client_properties_.find(remote_id_to_erase); auto erase_it = client_properties_.find(remote_id_to_erase);
if (erase_it != client_properties_.end()) { if (erase_it != client_properties_.end()) {
erase_it = client_properties_.erase(erase_it); // Ensure we flush pending STREAM_REFRESH_EVENT events and
if (client_properties_.empty()) { // clean up peer resources before erasing the entry, otherwise
SDL_Event event; // SDL events may still hold raw pointers to freed
event.type = SDL_EVENT_QUIT; // SubStreamWindowProperties (including video_frame_mutex_),
SDL_PushEvent(&event); // leading to std::system_error when locking.
} CloseTab(erase_it);
} }
} }
// lock.lock(); // lock.lock();
@@ -217,7 +219,9 @@ int Render::StreamWindow() {
if (props->tab_selected_) { if (props->tab_selected_) {
ImGui::SetNextWindowSize( ImGui::SetNextWindowSize(
ImVec2(stream_window_width_, stream_window_height_), ImVec2(stream_window_width_,
stream_window_height_ -
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
ImGuiCond_Always); ImGuiCond_Always);
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
@@ -236,10 +240,10 @@ int Render::StreamWindow() {
UpdateRenderRect(); UpdateRenderRect();
ControlWindow(props); ControlWindow(props);
// Show file transfer window if needed // Show file transfer window if needed
FileTransferWindow(props); FileTransferWindow(props);
ImGui::End(); ImGui::End();
if (!props->peer_) { if (!props->peer_) {
@@ -251,12 +255,7 @@ int Render::StreamWindow() {
// std::unique_lock unique_lock(client_properties_mutex_); // std::unique_lock unique_lock(client_properties_mutex_);
auto erase_it = client_properties_.find(remote_id_to_erase); auto erase_it = client_properties_.find(remote_id_to_erase);
if (erase_it != client_properties_.end()) { if (erase_it != client_properties_.end()) {
client_properties_.erase(erase_it); CloseTab(erase_it);
if (client_properties_.empty()) {
SDL_Event event;
event.type = SDL_EVENT_QUIT;
SDL_PushEvent(&event);
}
} }
} }
// lock.lock(); // lock.lock();