x11: Flag flushes despite having less than the element size

If say we want 32bit data, but have 2 bytes stored, we would simply
ignore flush requests. Allow (and don't clear) the needs_flush flag
if we have less than the element size accumulated.

Instead handle this in can_flush(), so it's triggered whenever we
have enough data to fill 1 element, or if the stream is closing
(seems a broken situation, but triggered by the caller).

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 967966cdee)
This commit is contained in:
Carlos Garnacho 2020-04-10 17:24:14 +02:00 committed by Robert Mader
parent 40dc22659b
commit 13a23f16c1

View File

@ -60,6 +60,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaX11SelectionOutputStream,
meta_x11_selection_output_stream, meta_x11_selection_output_stream,
G_TYPE_OUTPUT_STREAM); G_TYPE_OUTPUT_STREAM);
static size_t get_element_size (int format);
static void static void
meta_x11_selection_output_stream_notify_selection (MetaX11SelectionOutputStream *stream) meta_x11_selection_output_stream_notify_selection (MetaX11SelectionOutputStream *stream)
{ {
@ -97,6 +99,9 @@ meta_x11_selection_output_stream_can_flush (MetaX11SelectionOutputStream *stream
if (priv->delete_pending) if (priv->delete_pending)
return FALSE; return FALSE;
if (!g_output_stream_is_closing (G_OUTPUT_STREAM (stream)) &&
priv->data->len < get_element_size (priv->format))
return FALSE;
return TRUE; return TRUE;
} }
@ -241,7 +246,7 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
priv->data->data, priv->data->data,
n_elements); n_elements);
g_byte_array_remove_range (priv->data, 0, n_elements * element_size); g_byte_array_remove_range (priv->data, 0, n_elements * element_size);
if (priv->data->len < element_size) if (priv->data->len == 0)
priv->flush_requested = FALSE; priv->flush_requested = FALSE;
} }
@ -391,7 +396,7 @@ meta_x11_selection_output_request_flush (MetaX11SelectionOutputStream *stream)
g_mutex_lock (&priv->mutex); g_mutex_lock (&priv->mutex);
if (priv->data->len >= get_element_size (priv->format)) if (priv->data->len > 0)
priv->flush_requested = TRUE; priv->flush_requested = TRUE;
needs_flush = meta_x11_selection_output_stream_needs_flush_unlocked (stream); needs_flush = meta_x11_selection_output_stream_needs_flush_unlocked (stream);