GUACAMOLE-623: Add support for terminal resize. Redraw Kubernetes container upon connect.

This commit is contained in:
Michael Jumper 2018-09-10 02:50:15 -07:00
parent b7c938c239
commit fe7edce569
3 changed files with 95 additions and 2 deletions

View File

@ -88,7 +88,9 @@ int guac_kubernetes_user_size_handler(guac_user* user, int width, int height) {
/* Resize terminal */
guac_terminal_resize(terminal, width, height);
/* TODO: Update Kubernetes terminal window size if connected */
/* Update Kubernetes terminal window size if connected */
guac_kubernetes_resize(client, terminal->term_height,
terminal->term_width);
return 0;
}

View File

@ -246,6 +246,11 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
case LWS_CALLBACK_CLIENT_ESTABLISHED:
guac_client_log(client, GUAC_LOG_INFO,
"Kubernetes connection successful.");
/* Schedule check for pending messages in case messages were added
* to the outbound message buffer prior to the connection being
* fully established */
lws_callback_on_writable(wsi);
break;
/* Data received via WebSocket */
@ -260,7 +265,6 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
* yet more messages remain */
if (guac_kubernetes_write_pending_message(client))
lws_callback_on_writable(wsi);
break;
/* TODO: Add configure test */
@ -451,6 +455,11 @@ void* guac_kubernetes_client_thread(void* data) {
goto fail;
}
/* Force a redraw of the attached display (there will be no content
* otherwise, given the stream nature of attaching to a running
* container) */
guac_kubernetes_force_redraw(client);
/* As long as client is connected, continue polling libwebsockets */
while (client->state == GUAC_CLIENT_RUNNING) {
@ -485,3 +494,47 @@ fail:
}
void guac_kubernetes_resize(guac_client* client, int rows, int columns) {
char buffer[64];
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
/* Send request only if different from last request */
if (kubernetes_client->rows != rows ||
kubernetes_client->columns != columns) {
kubernetes_client->rows = rows;
kubernetes_client->columns = columns;
/* Construct terminal resize message for Kubernetes */
int length = snprintf(buffer, sizeof(buffer),
"{\"Width\":%i,\"Height\":%i}", columns, rows);
/* Schedule message for sending */
guac_kubernetes_send_message(client, GUAC_KUBERNETES_CHANNEL_RESIZE,
buffer, length);
}
}
void guac_kubernetes_force_redraw(guac_client* client) {
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
/* Get current terminal dimensions */
guac_terminal* term = kubernetes_client->term;
int rows = term->term_height;
int columns = term->term_width;
/* Force a redraw by increasing the terminal size by one character in
* each dimension and then resizing it back to normal (the same technique
* used by kubectl */
guac_kubernetes_resize(client, rows + 1, columns + 1);
guac_kubernetes_resize(client, rows, columns);
}

View File

@ -167,6 +167,18 @@ typedef struct guac_kubernetes_client {
*/
guac_terminal* term;
/**
* The number of rows last sent to Kubernetes in a terminal resize
* request.
*/
int rows;
/**
* The number of columns last sent to Kubernetes in a terminal resize
* request.
*/
int columns;
/**
* The in-progress session recording, or NULL if no recording is in
* progress.
@ -181,5 +193,31 @@ typedef struct guac_kubernetes_client {
*/
void* guac_kubernetes_client_thread(void* data);
/**
* Sends a message to the Kubernetes server requesting that the terminal be
* resized to the given dimensions. This message may be queued until the
* underlying WebSocket connection is ready to send.
*
* @param client
* The guac_client associated with the Kubernetes connection.
*
* @param rows
* The new terminal size in rows.
*
* @param columns
* The new terminal size in columns.
*/
void guac_kubernetes_resize(guac_client* client, int rows, int columns);
/**
* Sends messages to the Kubernetes server such that the terminal is forced
* to redraw. This function should be invoked at the beginning of each
* session in order to restore expected display state.
*
* @param client
* The guac_client associated with the Kubernetes connection.
*/
void guac_kubernetes_force_redraw(guac_client* client);
#endif