/// <summary> /// Sets the clipboard state asynchronously. /// </summary> /// <param name="state">The new clipboard state.</param> /// <returns></returns> public async Task SetStateAsync(ClipboardState state) { // Get the current state, in order to support // reverting to it in case of failure. ClipboardState prevState = await GetStateAsync(); _ignoreNextUpdate = true; try { await _owner.Dispatcher.RetryOnErrorAsync( () => ClipboardHelper.SetState(state), RetryCount, RetryDelay); } catch (Exception e) { await _owner.Dispatcher.RetryOnErrorAsync( () => ClipboardHelper.SetState(prevState), RetryCount, RetryDelay); throw e; } // Update the state reference. UpdateStateRef(state); }
/// <summary> /// Called when the clipboard state has been changed. /// </summary> private async void FormatListener_ClipboardUpdated() { if (_ignoreNextUpdate) { _ignoreNextUpdate = false; return; } ClipboardState newState = null; int updateId = ++_lastUpdateId; try { try { newState = await _owner.Dispatcher.RetryOnErrorAsync( () => ClipboardHelper.GetState(DataConversions.FilterInexpendable), RetryCount, RetryDelay); } catch { await Task.Delay(1000); newState = ClipboardHelper.GetState(DataConversions.FilterInexpendable); } } catch (Exception e) { _logger.LogWarn(LogEvents.ClipbdReadErr, e); e.Notify(); return; } if (_currentStateRef.TryGetTarget(out ClipboardState oldState) && ClipboardParser.WeakEquals(oldState, newState)) { return; } if (updateId != _lastUpdateId) { return; } // Update the state reference. UpdateStateRef(newState); // Notify that the state has been changed. StateChanged?.Invoke(newState); }
public static bool WeakEquals(ClipboardState stateA, ClipboardState stateB) { if (stateA.Items.Count == 0) { return(stateB.Items.Count == 0); } var itemA = GetPreferredItem(stateA.Items, serializable: true); if (itemA != null) { var itemB = stateB.Items.FirstOrDefault(x => x.Format == itemA.Format); return(itemA.Equals(itemB)); } else { if (stateA.Items.Count != stateB.Items.Count || stateA.Items.Any(x => !stateB.Items.Any(y => x.Equals(y)))) { return(false); } return(true); } }
/// <summary> /// Updates the weak reference to the current clipboard state. /// </summary> private void UpdateStateRef(ClipboardState state) { _currentStateRef = new WeakReference <ClipboardState>(state, trackResurrection: false); }
/// <summary> /// Writes the state to the system clipboard state. /// </summary> /// <param name="state">The new clipboard state.</param> public static void SetState(ClipboardState state) { IntPtr hWnd = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle(); WriteState(hWnd, state); }