Merge pull request #10584 from akallabeth/client-minimize-shortcut

Client minimize shortcut
This commit is contained in:
akallabeth 2024-09-10 14:26:36 +02:00 committed by GitHub
commit 64438a4028
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 199 additions and 122 deletions

View File

@ -1025,6 +1025,14 @@ static int sdl_run(SdlContext* sdl)
window->fullscreen(enter);
}
break;
case SDL_USEREVENT_WINDOW_MINIMIZE:
{
for (auto& window : sdl->windows)
{
window.second.minimize();
}
}
break;
case SDL_USEREVENT_POINTER_NULL:
SDL_ShowCursor(SDL_DISABLE);
break;
@ -1581,58 +1589,6 @@ static void SDLCALL winpr_LogOutputFunction(void* userdata, int category, SDL_Lo
category2str(category), message);
}
static void print_config_file_help()
{
#if defined(WITH_WINPR_JSON)
std::cout << "CONFIGURATION FILE" << std::endl;
std::cout << std::endl;
std::cout << " The SDL client supports some user defined configuration options." << std::endl;
std::cout << " Settings are stored in JSON format" << std::endl;
std::cout << " The location is a per user file. Location for current user is "
<< SdlPref::instance()->get_pref_file() << std::endl;
std::cout
<< " The XDG_CONFIG_HOME environment variable can be used to override the base directory."
<< std::endl;
std::cout << std::endl;
std::cout << " The following configuration options are supported:" << std::endl;
std::cout << std::endl;
std::cout << " SDL_KeyModMask" << std::endl;
std::cout << " Defines the key combination required for SDL client shortcuts."
<< std::endl;
std::cout << " Default KMOD_RSHIFT" << std::endl;
std::cout << " An array of SDL_Keymod strings as defined at "
"https://wiki.libsdl.org/SDL2/SDL_Keymod"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Fullscreen" << std::endl;
std::cout << " Toggles client fullscreen state." << std::endl;
std::cout << " Default SDL_SCANCODE_RETURN." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Resizeable" << std::endl;
std::cout << " Toggles local window resizeable state." << std::endl;
std::cout << " Default SDL_SCANCODE_R." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Grab" << std::endl;
std::cout << " Toggles keyboard and mouse grab state." << std::endl;
std::cout << " Default SDL_SCANCODE_G." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Disconnect" << std::endl;
std::cout << " Disconnects from the RDP session." << std::endl;
std::cout << " Default SDL_SCANCODE_D." << std::endl;
std::cout << " A string as defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
#endif
}
int main(int argc, char* argv[])
{
int rc = -1;
@ -1657,7 +1613,7 @@ int main(int argc, char* argv[])
if (status)
{
rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
print_config_file_help();
SdlPref::print_config_file_help(2);
if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors))
sdl_list_monitors(sdl);
return rc;
@ -1698,6 +1654,14 @@ BOOL SdlContext::update_fullscreen(BOOL enter)
return TRUE;
}
BOOL SdlContext::update_minimize()
{
std::lock_guard<CriticalSection> lock(critical);
if (!sdl_push_user_event(SDL_USEREVENT_WINDOW_MINIMIZE))
return FALSE;
return TRUE;
}
BOOL SdlContext::update_resizeable(BOOL enable)
{
std::lock_guard<CriticalSection> lock(critical);

View File

@ -85,6 +85,7 @@ class SdlContext
BOOL update_resizeable(BOOL enable);
BOOL update_fullscreen(BOOL enter);
BOOL update_minimize();
[[nodiscard]] rdpContext* context() const;
[[nodiscard]] rdpClientContext* common() const;

View File

@ -581,6 +581,11 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
freerdp_abort_connect_context(_sdl->context());
return TRUE;
}
if (ev->keysym.scancode == _hotkeyMinimize)
{
_sdl->update_minimize();
return TRUE;
}
}
}
@ -631,4 +636,5 @@ sdlInput::sdlInput(SdlContext* sdl)
_hotkeyResizable = prefKeyValue("SDL_Resizeable", SDL_SCANCODE_R);
_hotkeyGrab = prefKeyValue("SDL_Grab", SDL_SCANCODE_G);
_hotkeyDisconnect = prefKeyValue("SDL_Disconnect", SDL_SCANCODE_D);
_hotkeyMinimize = prefKeyValue("SDL_Minimize", SDL_SCANCODE_M);
}

View File

@ -71,4 +71,5 @@ class sdlInput
uint32_t _hotkeyResizable;
uint32_t _hotkeyGrab;
uint32_t _hotkeyDisconnect;
uint32_t _hotkeyMinimize;
};

View File

@ -110,6 +110,7 @@ const char* sdl_event_type_str(Uint32 type)
EV_CASE_STR(SDL_USEREVENT_CREATE_WINDOWS);
EV_CASE_STR(SDL_USEREVENT_WINDOW_RESIZEABLE);
EV_CASE_STR(SDL_USEREVENT_WINDOW_FULLSCREEN);
EV_CASE_STR(SDL_USEREVENT_WINDOW_MINIMIZE);
EV_CASE_STR(SDL_USEREVENT_POINTER_NULL);
EV_CASE_STR(SDL_USEREVENT_POINTER_DEFAULT);
EV_CASE_STR(SDL_USEREVENT_POINTER_POSITION);
@ -219,6 +220,7 @@ BOOL sdl_push_user_event(Uint32 type, ...)
event->data1 = va_arg(ap, void*);
event->code = va_arg(ap, int);
break;
case SDL_USEREVENT_WINDOW_MINIMIZE:
case SDL_USEREVENT_QUIT:
case SDL_USEREVENT_POINTER_NULL:
case SDL_USEREVENT_POINTER_DEFAULT:

View File

@ -61,6 +61,7 @@ enum
SDL_USEREVENT_CREATE_WINDOWS,
SDL_USEREVENT_WINDOW_RESIZEABLE,
SDL_USEREVENT_WINDOW_FULLSCREEN,
SDL_USEREVENT_WINDOW_MINIMIZE,
SDL_USEREVENT_POINTER_NULL,
SDL_USEREVENT_POINTER_DEFAULT,
SDL_USEREVENT_POINTER_POSITION,

View File

@ -168,6 +168,11 @@ void SdlWindow::fullscreen(bool enter)
}
}
void SdlWindow::minimize()
{
SDL_MinimizeWindow(_window);
}
bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
auto surface = SDL_GetWindowSurface(_window);

View File

@ -47,6 +47,7 @@ class SdlWindow
void raise();
void resizeable(bool use);
void fullscreen(bool enter);
void minimize();
bool fill(Uint8 r = 0x00, Uint8 g = 0x00, Uint8 b = 0x00, Uint8 a = 0xff);
bool blit(SDL_Surface* surface, SDL_Rect src, SDL_Rect& dst);

View File

@ -147,7 +147,8 @@ bool SDLConnectionDialog::setModal()
return true;
auto parent = sdl->windows.begin()->second.window();
SDL_SetWindowModalFor(_window, parent);
SDL_SetWindowParent(_window, parent);
SDL_SetWindowModal(_window, SDL_TRUE);
SDL_RaiseWindow(_window);
}
return true;

View File

@ -977,6 +977,12 @@ static int sdl_run(SdlContext* sdl)
window->fullscreen(enter);
}
break;
case SDL_EVENT_USER_WINDOW_MINIMIZE:
for (auto& window : sdl->windows)
{
window.second.minimize();
}
break;
case SDL_EVENT_USER_POINTER_NULL:
SDL_HideCursor();
break;
@ -1475,8 +1481,8 @@ static const char* category2str(int category)
return "SDL_LOG_CATEGORY_INPUT";
case SDL_LOG_CATEGORY_TEST:
return "SDL_LOG_CATEGORY_TEST";
case SDL_LOG_CATEGORY_RESERVED1:
return "SDL_LOG_CATEGORY_RESERVED1";
case SDL_LOG_CATEGORY_GPU:
return "SDL_LOG_CATEGORY_GPU";
case SDL_LOG_CATEGORY_RESERVED2:
return "SDL_LOG_CATEGORY_RESERVED2";
case SDL_LOG_CATEGORY_RESERVED3:
@ -1568,58 +1574,6 @@ static void SDLCALL winpr_LogOutputFunction(void* userdata, int category, SDL_Lo
category2str(category), message);
}
static void print_config_file_help()
{
#if defined(WITH_WINPR_JSON)
std::cout << "CONFIGURATION FILE" << std::endl;
std::cout << std::endl;
std::cout << " The SDL client supports some user defined configuration options." << std::endl;
std::cout << " Settings are stored in JSON format" << std::endl;
std::cout << " The location is a per user file. Location for current user is "
<< SdlPref::instance()->get_pref_file() << std::endl;
std::cout
<< " The XDG_CONFIG_HOME environment variable can be used to override the base directory."
<< std::endl;
std::cout << std::endl;
std::cout << " The following configuration options are supported:" << std::endl;
std::cout << std::endl;
std::cout << " SDL_KeyModMask" << std::endl;
std::cout << " Defines the key combination required for SDL client shortcuts."
<< std::endl;
std::cout << " Default KMOD_RSHIFT" << std::endl;
std::cout << " An array of SDL_Keymod strings as defined at "
"https://wiki.libsdl.org/SDL2/SDL_Keymod"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Fullscreen" << std::endl;
std::cout << " Toggles client fullscreen state." << std::endl;
std::cout << " Default SDL_SCANCODE_RETURN." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Resizeable" << std::endl;
std::cout << " Toggles local window resizeable state." << std::endl;
std::cout << " Default SDL_SCANCODE_R." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Grab" << std::endl;
std::cout << " Toggles keyboard and mouse grab state." << std::endl;
std::cout << " Default SDL_SCANCODE_G." << std::endl;
std::cout << " A string as "
"defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
std::cout << std::endl;
std::cout << " SDL_Disconnect" << std::endl;
std::cout << " Disconnects from the RDP session." << std::endl;
std::cout << " Default SDL_SCANCODE_D." << std::endl;
std::cout << " A string as defined at https://wiki.libsdl.org/SDL2/SDLScancodeLookup"
<< std::endl;
#endif
}
int main(int argc, char* argv[])
{
int rc = -1;
@ -1644,7 +1598,7 @@ int main(int argc, char* argv[])
if (status)
{
rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
print_config_file_help();
SdlPref::print_config_file_help(3);
if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors))
sdl_list_monitors(sdl);
return rc;
@ -1685,6 +1639,14 @@ BOOL SdlContext::update_fullscreen(BOOL enter)
return TRUE;
}
BOOL SdlContext::update_minimize()
{
std::lock_guard<CriticalSection> lock(critical);
if (!sdl_push_user_event(SDL_EVENT_USER_WINDOW_MINIMIZE))
return FALSE;
return TRUE;
}
BOOL SdlContext::update_resizeable(BOOL enable)
{
std::lock_guard<CriticalSection> lock(critical);

View File

@ -85,6 +85,7 @@ class SdlContext
BOOL update_resizeable(BOOL enable);
BOOL update_fullscreen(BOOL enter);
BOOL update_minimize();
[[nodiscard]] rdpContext* context() const;
[[nodiscard]] rdpClientContext* common() const;

View File

@ -557,6 +557,11 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev)
freerdp_abort_connect_context(_sdl->context());
return TRUE;
}
if (ev->scancode == _hotkeyMinimize)
{
_sdl->update_minimize();
return TRUE;
}
}
}
@ -606,4 +611,5 @@ sdlInput::sdlInput(SdlContext* sdl)
_hotkeyResizable = prefKeyValue("SDL_Resizeable", SDL_SCANCODE_R);
_hotkeyGrab = prefKeyValue("SDL_Grab", SDL_SCANCODE_G);
_hotkeyDisconnect = prefKeyValue("SDL_Disconnect", SDL_SCANCODE_D);
_hotkeyMinimize = prefKeyValue("SDL_Minimize", SDL_SCANCODE_M);
}

View File

@ -71,4 +71,5 @@ class sdlInput
uint32_t _hotkeyResizable;
uint32_t _hotkeyGrab;
uint32_t _hotkeyDisconnect;
uint32_t _hotkeyMinimize;
};

View File

@ -241,7 +241,7 @@ BOOL sdl_handle_mouse_button(SdlContext* sdl, const SDL_MouseButtonEvent* ev)
WINPR_ASSERT(sdl);
WINPR_ASSERT(ev);
if (ev->state == SDL_PRESSED)
if (ev->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
{
flags |= PTR_FLAGS_DOWN;
xflags |= PTR_XFLAGS_DOWN;

View File

@ -158,6 +158,7 @@ const char* sdl_event_type_str(Uint32 type)
EV_CASE_STR(SDL_EVENT_USER_CREATE_WINDOWS);
EV_CASE_STR(SDL_EVENT_USER_WINDOW_RESIZEABLE);
EV_CASE_STR(SDL_EVENT_USER_WINDOW_FULLSCREEN);
EV_CASE_STR(SDL_EVENT_USER_WINDOW_MINIMIZE);
EV_CASE_STR(SDL_EVENT_USER_POINTER_NULL);
EV_CASE_STR(SDL_EVENT_USER_POINTER_DEFAULT);
EV_CASE_STR(SDL_EVENT_USER_POINTER_POSITION);
@ -265,6 +266,7 @@ BOOL sdl_push_user_event(Uint32 type, ...)
event->data1 = va_arg(ap, void*);
event->code = va_arg(ap, int);
break;
case SDL_EVENT_USER_WINDOW_MINIMIZE:
case SDL_EVENT_USER_QUIT:
case SDL_EVENT_USER_POINTER_NULL:
case SDL_EVENT_USER_POINTER_DEFAULT:

View File

@ -65,6 +65,7 @@ enum
SDL_EVENT_USER_CREATE_WINDOWS,
SDL_EVENT_USER_WINDOW_RESIZEABLE,
SDL_EVENT_USER_WINDOW_FULLSCREEN,
SDL_EVENT_USER_WINDOW_MINIMIZE,
SDL_EVENT_USER_POINTER_NULL,
SDL_EVENT_USER_POINTER_DEFAULT,
SDL_EVENT_USER_POINTER_POSITION,

View File

@ -163,6 +163,11 @@ void SdlWindow::fullscreen(bool enter)
}
}
void SdlWindow::minimize()
{
SDL_MinimizeWindow(_window);
}
bool SdlWindow::fill(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
auto surface = SDL_GetWindowSurface(_window);

View File

@ -47,6 +47,7 @@ class SdlWindow
void raise();
void resizeable(bool use);
void fullscreen(bool enter);
void minimize();
bool fill(Uint8 r = 0x00, Uint8 g = 0x00, Uint8 b = 0x00, Uint8 a = 0xff);
bool blit(SDL_Surface* surface, const SDL_Rect& src, SDL_Rect& dst);

View File

@ -39,6 +39,18 @@
</varlistentry>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>SDL_Minimize</replaceable></term>
<listitem>
<varlistentry>
<listitem>
<para>Minimizes the client window<sbr/>
Default <replaceable>SDL_SCANCODE_M</replaceable>.<sbr/>
A string as defined at <replaceable>https://wiki.libsdl.org/SDL2/SDLScancodeLookup</replaceable></para>
</listitem>
</varlistentry>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>SDL_Resizeable</replaceable></term>
<listitem>

View File

@ -17,6 +17,7 @@
* limitations under the License.
*/
#include <iostream>
#include <fstream>
#if __has_include(<filesystem>)
#include <filesystem>
@ -103,6 +104,65 @@ std::vector<std::string> SdlPref::get_array(const std::string& key,
return values;
}
void SdlPref::print_config_file_help(int version)
{
#if defined(WITH_WINPR_JSON)
const std::string url = "https://wiki.libsdl.org/SDL" + std::to_string(version);
std::cout << "CONFIGURATION FILE" << std::endl;
std::cout << std::endl;
std::cout << " The SDL client supports some user defined configuration options." << std::endl;
std::cout << " Settings are stored in JSON format" << std::endl;
std::cout << " The location is a per user file. Location for current user is "
<< SdlPref::instance()->get_pref_file() << std::endl;
std::cout
<< " The XDG_CONFIG_HOME environment variable can be used to override the base directory."
<< std::endl;
std::cout << std::endl;
std::cout << " The following configuration options are supported:" << std::endl;
std::cout << std::endl;
std::cout << " SDL_KeyModMask" << std::endl;
std::cout << " Defines the key combination required for SDL client shortcuts."
<< std::endl;
std::cout << " Default KMOD_RSHIFT" << std::endl;
std::cout << " An array of SDL_Keymod strings as defined at "
""
<< url << "/SDL_Keymod" << std::endl;
std::cout << std::endl;
std::cout << " SDL_Fullscreen" << std::endl;
std::cout << " Toggles client fullscreen state." << std::endl;
std::cout << " Default SDL_SCANCODE_RETURN." << std::endl;
std::cout << " A string as "
"defined at "
<< url << "/SDLScancodeLookup" << std::endl;
std::cout << std::endl;
std::cout << " SDL_Minimize" << std::endl;
std::cout << " Minimizes client windows." << std::endl;
std::cout << " Default SDL_SCANCODE_M." << std::endl;
std::cout << " A string as "
"defined at "
<< url << "/SDLScancodeLookup" << std::endl;
std::cout << std::endl;
std::cout << " SDL_Resizeable" << std::endl;
std::cout << " Toggles local window resizeable state." << std::endl;
std::cout << " Default SDL_SCANCODE_R." << std::endl;
std::cout << " A string as "
"defined at "
<< url << "/SDLScancodeLookup" << std::endl;
std::cout << std::endl;
std::cout << " SDL_Grab" << std::endl;
std::cout << " Toggles keyboard and mouse grab state." << std::endl;
std::cout << " Default SDL_SCANCODE_G." << std::endl;
std::cout << " A string as "
"defined at "
<< url << "/SDLScancodeLookup" << std::endl;
std::cout << std::endl;
std::cout << " SDL_Disconnect" << std::endl;
std::cout << " Disconnects from the RDP session." << std::endl;
std::cout << " Default SDL_SCANCODE_D." << std::endl;
std::cout << " A string as defined at " << url << "/SDLScancodeLookup" << std::endl;
#endif
}
SdlPref::SdlPref(std::string file) : _name(std::move(file)), _config(get())
{
}

View File

@ -37,6 +37,8 @@ class SdlPref
std::vector<std::string> get_array(const std::string& key,
const std::vector<std::string>& fallback = {});
static void print_config_file_help(int version);
private:
using WINPR_JSONPtr = std::unique_ptr<WINPR_JSON, decltype(&WINPR_JSON_Delete)>;

View File

@ -40,6 +40,8 @@ static void xfreerdp_print_help(void)
printf("\t\ttoggles fullscreen state of the application\n");
printf("\t<CTRL>+<ALT>+c\n");
printf("\t\ttoggles remote control in a remote assistance session\n");
printf("\t<CTRL>+<ALT>+m\n");
printf("\t\tminimizes the application\n");
printf("\tAction Script\n");
printf("\t\tExecutes a predefined script on key press.\n");
printf("\t\tShould the script not exist it is ignored.\n");

View File

@ -10,6 +10,10 @@
<listitem><para>toggles fullscreen state of the application</para></listitem>
</varlistentry>
<varlistentry>
<term>&lt;CTRL&gt;+&lt;ALT&gt;+&lt;m&gt;</term>
<listitem><para>Minimizes the application</para></listitem>
</varlistentry>
<varlistentry>
<term>&lt;CTRL&gt;+&lt;ALT&gt;+c</term>
<listitem><para>toggles remote control in a remote assistance session</para></listitem>
</varlistentry>

View File

@ -762,7 +762,7 @@ static void xf_window_free(xfContext* xfc)
void xf_toggle_fullscreen(xfContext* xfc)
{
WindowStateChangeEventArgs e;
WindowStateChangeEventArgs e = { 0 };
rdpContext* context = (rdpContext*)xfc;
rdpSettings* settings = context->settings;
@ -782,6 +782,28 @@ void xf_toggle_fullscreen(xfContext* xfc)
PubSub_OnWindowStateChange(context->pubSub, context, &e);
}
void xf_minimize(xfContext* xfc)
{
WindowStateChangeEventArgs e = { 0 };
rdpContext* context = (rdpContext*)xfc;
WINPR_ASSERT(context);
rdpSettings* settings = context->settings;
WINPR_ASSERT(settings);
/*
when debugging, ungrab keyboard when toggling fullscreen
to allow keyboard usage on the debugger
*/
if (xfc->debug)
xf_ungrab(xfc);
xf_SetWindowMinimized(xfc, xfc->window);
e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
PubSub_OnWindowStateChange(context->pubSub, context, &e);
}
void xf_lock_x11_(xfContext* xfc, const char* fkt)
{

View File

@ -588,24 +588,37 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
if (!xfc->remote_app && xfc->fullscreen_toggle)
{
if (keysym == XK_Return)
switch (keysym)
{
if (mod.Ctrl && mod.Alt)
{
/* Ctrl-Alt-Enter: toggle full screen */
xf_toggle_fullscreen(xfc);
return TRUE;
}
case XK_Return:
if (mod.Ctrl && mod.Alt)
{
/* Ctrl-Alt-Enter: toggle full screen */
xf_toggle_fullscreen(xfc);
return TRUE;
}
break;
default:
break;
}
}
if ((keysym == XK_c) || (keysym == XK_C))
if (mod.Ctrl && mod.Alt)
{
if (mod.Ctrl && mod.Alt)
switch (keysym)
{
/* Ctrl-Alt-C: toggle control */
if (freerdp_client_encomsp_toggle_control(xfc->common.encomsp))
case XK_m:
case XK_M:
xf_minimize(xfc);
return TRUE;
case XK_c:
case XK_C:
/* Ctrl-Alt-C: toggle control */
if (freerdp_client_encomsp_toggle_control(xfc->common.encomsp))
return TRUE;
break;
default:
break;
}
}

View File

@ -312,6 +312,7 @@ struct xf_context
BOOL xf_create_window(xfContext* xfc);
BOOL xf_create_image(xfContext* xfc);
void xf_toggle_fullscreen(xfContext* xfc);
void xf_minimize(xfContext* xfc);
enum XF_EXIT_CODE
{