├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── dependabot.yml ├── stale.yml └── workflows │ ├── merge-dependabot.yml │ └── on-push-do-docs.yml ├── .gitignore ├── license.txt ├── readme.md └── src ├── .editorconfig ├── AndroidApp ├── AndroidApp.csproj ├── MainActivity.cs ├── Properties │ └── AndroidManifest.xml └── Resources │ ├── Resource.designer.cs │ ├── layout │ ├── activity_main.xml │ └── content_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── ic_launcher_background.xml │ ├── strings.xml │ └── styles.xml ├── BlazorSample ├── App.razor ├── BlazorSample.csproj ├── FodyWeavers.xml ├── Pages │ ├── Index.razor │ ├── IndexModel.cs │ └── _ViewImports.razor ├── Program.cs ├── Shared │ └── MainLayout.razor ├── _Imports.razor └── wwwroot │ ├── index.html │ └── site.css ├── Directory.Build.props ├── Directory.Packages.props ├── TestConsole ├── Program.cs └── TestConsole.csproj ├── Tests ├── ClipboardServiceTests.cs ├── ClipboardTests.cs ├── Snippets.cs └── Tests.csproj ├── TextCopy.sln ├── TextCopy.sln.DotSettings ├── TextCopy ├── BashRunner.cs ├── BlazorClipboard.cs ├── Clipboard.cs ├── ClipboardService.cs ├── ClipboardService_GetAndroid.cs ├── ClipboardService_GetStandard.cs ├── ClipboardService_GetiOS.cs ├── ClipboardService_SetAndroid.cs ├── ClipboardService_SetStandard.cs ├── ClipboardService_SetiOS.cs ├── ClsCompliant.cs ├── FodyWeavers.xml ├── IClipboard.cs ├── LinuxClipboard_2.0.cs ├── LinuxClipboard_2.1.cs ├── MockClipboard.cs ├── OsxClipboard.cs ├── ServiceExtensions.cs ├── TextCopy.csproj └── WindowsClipboard.cs ├── UapApp ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── MainPage.xaml ├── MainPage.xaml.cs ├── Package.appxmanifest ├── Properties │ └── Default.rd.xml └── UapApp.csproj ├── Weavers ├── RemoveResource.cs └── Weavers.csproj ├── appveyor.yml ├── build.ps ├── build.ps1 ├── global.json ├── iOSApp ├── AppDelegate.cs ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon1024.png │ │ ├── Icon120.png │ │ ├── Icon152.png │ │ ├── Icon167.png │ │ ├── Icon180.png │ │ ├── Icon20.png │ │ ├── Icon29.png │ │ ├── Icon40.png │ │ ├── Icon58.png │ │ ├── Icon60.png │ │ ├── Icon76.png │ │ ├── Icon80.png │ │ └── Icon87.png ├── Entitlements.plist ├── Info.plist ├── LaunchScreen.storyboard ├── Main.cs ├── Main.storyboard ├── Properties │ └── AssemblyInfo.cs ├── Resources │ └── LaunchScreen.xib ├── SceneDelegate.cs ├── ViewController.cs ├── ViewController.designer.cs └── iOSApp.csproj ├── icon.png ├── key.snk ├── mdsnippets.json └── nuget.config /.github/FUNDING.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/.github/FUNDING.yml -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug fix 3 | about: Create a bug fix to help us improve 4 | --- 5 | 6 | Note: New issues raised, where it is clear the submitter has not read the issue template, are likely to be closed with "please read the issue template". Please don't take offense at this. It is simply a time management decision. If someone raises an issue, and can't be bothered to spend the time to read the issue template, then the project maintainers should not be expected to spend the time to read the submitted issue. Often too much time is spent going back and forth in issue comments asking for information that is outlined in the issue template. 7 | 8 | 9 | #### Preamble 10 | 11 | General questions may be better placed [StackOveflow](https://stackoverflow.com/). 12 | 13 | Where relevant, ensure you are using the current stable versions on your development stack. For example: 14 | 15 | * Visual Studio 16 | * [.NET SDK or .NET Core SDK](https://www.microsoft.com/net/download) 17 | * Any related NuGet packages 18 | 19 | Any code or stack traces must be properly formatted with [GitHub markdown](https://guides.github.com/features/mastering-markdown/). 20 | 21 | 22 | #### Describe the bug 23 | 24 | A clear and concise description of what the bug is. Include any relevant version information. 25 | 26 | A clear and concise description of what you expected to happen. 27 | 28 | Add any other context about the problem here. 29 | 30 | 31 | #### Minimal Repro 32 | 33 | Ensure you have replicated the bug in a minimal solution with the fewest moving parts. Often this will help point to the true cause of the problem. Upload this repro as part of the issue, preferably a public GitHub repository or a downloadable zip. The repro will allow the maintainers of this project to smoke test the any fix. 34 | 35 | #### Submit a PR that fixes the bug 36 | 37 | Submit a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) that fixes the bug. Include in this PR a test that verifies the fix. If you were not able to fix the bug, a PR that illustrates your partial progress will suffice. 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: How to raise feature requests 4 | --- 5 | 6 | 7 | Note: New issues raised, where it is clear the submitter has not read the issue template, are likely to be closed with "please read the issue template". Please don't take offense at this. It is simply a time management decision. If someone raises an issue, and can't be bothered to spend the time to read the issue template, then the project maintainers should not be expected to spend the time to read the submitted issue. Often too much time is spent going back and forth in issue comments asking for information that is outlined in the issue template. 8 | 9 | If you are certain the feature will be accepted, it is better to raise a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/). 10 | 11 | If you are uncertain if the feature will be accepted, outline the proposal below to confirm it is viable, prior to raising a PR that implements the feature. 12 | 13 | Note that even if the feature is a good idea and viable, it may not be accepted since the ongoing effort in maintaining the feature may outweigh the benefit it delivers. 14 | 15 | 16 | #### Is the feature request related to a problem 17 | 18 | A clear and concise description of what the problem is. 19 | 20 | 21 | #### Describe the solution 22 | 23 | A clear and concise proposal of how you intend to implement the feature. 24 | 25 | 26 | #### Describe alternatives considered 27 | 28 | A clear and concise description of any alternative solutions or features you've considered. 29 | 30 | 31 | #### Additional context 32 | 33 | Add any other context about the feature request here. 34 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/src" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 7 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Set to true to ignore issues in a milestone (defaults to false) 6 | exemptMilestones: true 7 | # Comment to post when marking an issue as stale. Set to `false` to disable 8 | markComment: > 9 | This issue has been automatically marked as stale because it has not had 10 | recent activity. It will be closed if no further activity occurs. Thank you 11 | for your contributions. 12 | # Comment to post when closing a stale issue. Set to `false` to disable 13 | closeComment: false 14 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 15 | pulls: 16 | daysUntilStale: 30 17 | exemptLabels: 18 | - Question 19 | - Bug 20 | - Feature 21 | - Improvement -------------------------------------------------------------------------------- /.github/workflows/merge-dependabot.yml: -------------------------------------------------------------------------------- 1 | name: merge-dependabot 2 | on: 3 | push: 4 | branches: 5 | - dependabot* 6 | - master 7 | pull_request: 8 | branches: 9 | - dependabot* 10 | - master 11 | jobs: 12 | automerge: 13 | runs-on: ubuntu-latest 14 | if: github.actor == 'dependabot[bot]' 15 | steps: 16 | - name: Automerge Dependecies 17 | uses: "pascalgn/automerge-action@v0.14.1" 18 | env: 19 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 20 | MERGE_LABELS: "dependencies" -------------------------------------------------------------------------------- /.github/workflows/on-push-do-docs.yml: -------------------------------------------------------------------------------- 1 | name: on-push-do-docs 2 | on: 3 | push: 4 | jobs: 5 | docs: 6 | runs-on: windows-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | - name: Run MarkdownSnippets 10 | run: | 11 | dotnet tool install --global MarkdownSnippets.Tool 12 | mdsnippets ${GITHUB_WORKSPACE} 13 | shell: bash 14 | - name: Push changes 15 | run: | 16 | git config --local user.email "action@github.com" 17 | git config --local user.name "GitHub Action" 18 | git commit -m "Docs changes" -a || echo "nothing to commit" 19 | remote="https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git" 20 | branch="${GITHUB_REF:11}" 21 | git push "${remote}" ${branch} || echo "nothing to push" 22 | shell: bash -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Simon Cropp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # TextCopy 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/35uq76nlt9tl6m3t/branch/master?svg=true)](https://ci.appveyor.com/project/SimonCropp/textcopy) 4 | [![NuGet Status](https://img.shields.io/nuget/v/TextCopy.svg)](https://www.nuget.org/packages/TextCopy/) 5 | 6 | A cross platform package to copy text to and from the clipboard. 7 | 8 | **See [Milestones](../../milestones?state=closed) for release notes.** 9 | 10 | 11 | ## NuGet package 12 | 13 | https://nuget.org/packages/TextCopy/ 14 | 15 | 16 | ## Usage 17 | 18 | 19 | ### SetTextAsync 20 | 21 | 22 | 23 | ```cs 24 | await ClipboardService.SetTextAsync("Text to place in clipboard"); 25 | ``` 26 | snippet source | anchor 27 | 28 | 29 | 30 | ### SetText 31 | 32 | 33 | 34 | ```cs 35 | ClipboardService.SetText("Text to place in clipboard"); 36 | ``` 37 | snippet source | anchor 38 | 39 | 40 | 41 | ### GetTextAsync 42 | 43 | 44 | 45 | ```cs 46 | var text = await ClipboardService.GetTextAsync(); 47 | ``` 48 | snippet source | anchor 49 | 50 | 51 | 52 | ### GetText 53 | 54 | 55 | 56 | ```cs 57 | var text = ClipboardService.GetText(); 58 | ``` 59 | snippet source | anchor 60 | 61 | 62 | 63 | ## Clearing The Clipboard 64 | 65 | 66 | 67 | ```cs 68 | ClipboardService.SetText(""); 69 | ``` 70 | snippet source | anchor 71 | 72 | 73 | 74 | 75 | ```cs 76 | await ClipboardService.SetTextAsync(""); 77 | ``` 78 | snippet source | anchor 79 | 80 | 81 | 82 | ## Instance API 83 | 84 | In addition to the above static API, there is an instance API exposed: 85 | 86 | 87 | 88 | ```cs 89 | Clipboard clipboard = new(); 90 | clipboard.SetText("Text to place in clipboard"); 91 | ``` 92 | snippet source | anchor 93 | 94 | 95 | 96 | ### Dependency Injection 97 | 98 | An instance of `Clipboard` can be injected into `IServiceCollection`: 99 | 100 | 101 | 102 | ```cs 103 | serviceCollection.InjectClipboard(); 104 | ``` 105 | snippet source | anchor 106 | 107 | 108 | The instance should be injected by using `IClipboard`. 109 | 110 | There is also a `InjectMockClipboard` that injects an instance of `MockClipboard` with all methods stubbed out. 111 | 112 | 113 | ## Supported on 114 | 115 | * Windows with .NET Framework 4.6.1 and up 116 | * Windows with .NET Core 2.0 and up 117 | * Windows with Mono 5.0 and up 118 | * OSX with .NET Core 2.0 and up 119 | * OSX with Mono 5.20.1 and up 120 | * Linux with .NET Core 2.0 and up 121 | * Linux with Mono 5.20.1 and up 122 | * Xamarin.Android 9.0 and up 123 | * Xamarin.iOS 10.0 and up 124 | * Blazor WebAssembly 6.0 and up 125 | 126 | 127 | ## Blazor WebAssembly 128 | 129 | Due to the dependency on `JSInterop` the static `ClipboardService` is not supported on Blazor. 130 | 131 | Instead inject an `IClipboard`: 132 | 133 | 134 | 135 | ```cs 136 | var builder = WebAssemblyHostBuilder.CreateDefault(); 137 | var serviceCollection = builder.Services; 138 | serviceCollection.InjectClipboard(); 139 | builder.RootComponents.Add("app"); 140 | ``` 141 | snippet source | anchor 142 | 143 | 144 | Then consume it: 145 | 146 | 147 | 148 | ```cs 149 | public partial class IndexModel : 150 | ComponentBase 151 | { 152 | [Inject] 153 | public IClipboard Clipboard { get; set; } 154 | 155 | public string Content { get; set; } 156 | 157 | public Task CopyTextToClipboard() => 158 | Clipboard.SetTextAsync(Content); 159 | 160 | public async Task ReadTextFromClipboard() => 161 | Content = await Clipboard.GetTextAsync(); 162 | } 163 | ``` 164 | snippet source | anchor 165 | 166 | 167 | Blazor support requires the browser APIs [clipboard.readText](https://caniuse.com/#feat=mdn-api_clipboard_readtext) and [clipboard.writeText](https://caniuse.com/#feat=mdn-api_clipboard_writetext). 168 | 169 | 170 | ## Linux 171 | 172 | Linux uses [xsel](https://github.com/kfish/xsel) to access the clipboard. As such it needs to be installed and callable. 173 | 174 | 175 | ## Icon 176 | 177 | [Clone](https://thenounproject.com/term/Clone/207435/) designed by [Wes Breazell](https://thenounproject.com/wes13/) from [The Noun Project](https://thenounproject.com). 178 | -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | # EditorConfig: http://EditorConfig.org 3 | 4 | # top-most EditorConfig file 5 | 6 | [*] 7 | indent_style = space 8 | 9 | 10 | [*.cs] 11 | indent_size = 4 12 | charset = utf-8 13 | 14 | 15 | # Microsoft .NET properties 16 | csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion 17 | csharp_style_namespace_declarations = file_scoped:error 18 | dotnet_naming_rule.private_constants_rule.import_to_resharper = as_predefined 19 | dotnet_naming_rule.private_constants_rule.severity = warning 20 | dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style 21 | dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols 22 | dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefined 23 | dotnet_naming_rule.private_instance_fields_rule.severity = warning 24 | dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style 25 | dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols 26 | dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined 27 | dotnet_naming_rule.private_static_fields_rule.severity = warning 28 | dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style 29 | dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols 30 | dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined 31 | dotnet_naming_rule.private_static_readonly_rule.severity = warning 32 | dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style 33 | dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols 34 | dotnet_naming_style.lower_camel_case_style.capitalization = camel_case 35 | dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case 36 | dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private 37 | dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field 38 | dotnet_naming_symbols.private_constants_symbols.required_modifiers = const 39 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private 40 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field 41 | dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private 42 | dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field 43 | dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static 44 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private 45 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field 46 | dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly 47 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none 48 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none 49 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none 50 | 51 | # ReSharper properties 52 | resharper_apply_on_completion = true 53 | resharper_csharp_wrap_lines = false 54 | resharper_object_creation_when_type_not_evident = target_typed 55 | 56 | # ReSharper inspection severities 57 | resharper_arrange_object_creation_when_type_evident_highlighting = error 58 | resharper_arrange_object_creation_when_type_not_evident_highlighting = error 59 | resharper_arrange_redundant_parentheses_highlighting = error 60 | resharper_arrange_static_member_qualifier_highlighting = error 61 | resharper_arrange_this_qualifier_highlighting = hint 62 | resharper_arrange_type_member_modifiers_highlighting = none 63 | resharper_built_in_type_reference_style_for_member_access_highlighting = hint 64 | resharper_built_in_type_reference_style_highlighting = hint 65 | resharper_check_namespace_highlighting = none 66 | resharper_convert_to_using_declaration_highlighting = error 67 | resharper_css_not_resolved_highlighting = warning 68 | resharper_field_can_be_made_read_only_local_highlighting = none 69 | resharper_merge_into_logical_pattern_highlighting = warning 70 | resharper_merge_into_pattern_highlighting = error 71 | resharper_method_has_async_overload_highlighting = warning 72 | resharper_partial_type_with_single_part_highlighting = error 73 | resharper_redundant_base_qualifier_highlighting = warning 74 | resharper_redundant_cast_highlighting = error 75 | resharper_redundant_empty_object_creation_argument_list_highlighting = error 76 | resharper_redundant_empty_object_or_collection_initializer_highlighting = error 77 | resharper_redundant_name_qualifier_highlighting = error 78 | resharper_redundant_suppress_nullable_warning_expression_highlighting = error 79 | resharper_redundant_using_directive_highlighting = error 80 | resharper_redundant_verbatim_string_prefix_highlighting = error 81 | resharper_redundant_lambda_signature_parentheses_highlighting = error 82 | resharper_replace_substring_with_range_indexer_highlighting = warning 83 | resharper_suggest_var_or_type_built_in_types_highlighting = hint 84 | resharper_suggest_var_or_type_elsewhere_highlighting = hint 85 | resharper_suggest_var_or_type_simple_types_highlighting = hint 86 | resharper_unnecessary_whitespace_highlighting = error 87 | resharper_use_await_using_highlighting = warning 88 | resharper_use_deconstruction_highlighting = error 89 | 90 | # Sort using and Import directives with System.* appearing first 91 | dotnet_sort_system_directives_first = true 92 | 93 | # Avoid "this." and "Me." if not necessary 94 | dotnet_style_qualification_for_field = false:error 95 | dotnet_style_qualification_for_property = false:error 96 | dotnet_style_qualification_for_method = false:error 97 | dotnet_style_qualification_for_event = false:error 98 | 99 | # Use language keywords instead of framework type names for type references 100 | dotnet_style_predefined_type_for_locals_parameters_members = true:error 101 | dotnet_style_predefined_type_for_member_access = true:error 102 | 103 | # Suggest more modern language features when available 104 | dotnet_style_object_initializer = true:suggestion 105 | dotnet_style_collection_initializer = true:suggestion 106 | dotnet_style_coalesce_expression = false:suggestion 107 | dotnet_style_null_propagation = true:suggestion 108 | dotnet_style_explicit_tuple_names = true:suggestion 109 | 110 | # Prefer "var" everywhere 111 | csharp_style_var_for_built_in_types = true:error 112 | csharp_style_var_when_type_is_apparent = true:error 113 | csharp_style_var_elsewhere = true:error 114 | 115 | # Prefer method-like constructs to have a block body 116 | csharp_style_expression_bodied_methods = true:error 117 | csharp_style_expression_bodied_constructors = true:error 118 | csharp_style_expression_bodied_operators = true:error 119 | csharp_place_expr_method_on_single_line = false 120 | 121 | # Prefer property-like constructs to have an expression-body 122 | csharp_style_expression_bodied_properties = true:error 123 | csharp_style_expression_bodied_indexers = true:error 124 | csharp_style_expression_bodied_accessors = true:error 125 | 126 | # Suggest more modern language features when available 127 | csharp_style_pattern_matching_over_is_with_cast_check = true:error 128 | csharp_style_pattern_matching_over_as_with_null_check = true:error 129 | csharp_style_inlined_variable_declaration = true:suggestion 130 | csharp_style_throw_expression = true:suggestion 131 | csharp_style_conditional_delegate_call = true:suggestion 132 | 133 | # Newline settings 134 | #csharp_new_line_before_open_brace = all:error 135 | max_array_initializer_elements_on_line = 1 136 | csharp_new_line_before_else = true 137 | csharp_new_line_before_catch = true 138 | csharp_new_line_before_finally = true 139 | csharp_new_line_before_members_in_object_initializers = true 140 | csharp_new_line_before_members_in_anonymous_types = true 141 | csharp_place_type_constraints_on_same_line = false:error 142 | csharp_wrap_before_first_type_parameter_constraint = true:error 143 | csharp_wrap_extends_list_style = true:error 144 | csharp_wrap_after_dot_in_method_calls false 145 | csharp_wrap_before_binary_pattern_op false 146 | resharper_csharp_wrap_object_and_collection_initializer_style = chop_always 147 | resharper_csharp_place_simple_initializer_on_single_line = false 148 | 149 | dotnet_style_require_accessibility_modifiers = never:error 150 | resharper_place_type_constraints_on_same_line = false 151 | 152 | #braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces 153 | braces_for_ifelse = required 154 | braces_for_foreach = required 155 | braces_for_while = required 156 | braces_for_dowhile = required 157 | braces_for_lock = required 158 | braces_for_fixed = required 159 | braces_for_for = required 160 | 161 | # Xml files 162 | [*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props}] 163 | indent_size = 2 164 | # https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi 165 | blank_line_after_pi = false 166 | space_before_self_closing = true 167 | 168 | [*.json] 169 | indent_size = 2 -------------------------------------------------------------------------------- /src/AndroidApp/AndroidApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Debug 4 | AnyCPU 5 | 8.0.30703 6 | 2.0 7 | {09F670AA-D49D-4401-99DC-0863C9BB464E} 8 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 9 | {84dd83c5-0fe3-4294-9419-09e7c8ba324f} 10 | Library 11 | Properties 12 | AndroidApp 13 | AndroidApp 14 | 512 15 | True 16 | True 17 | Resources\Resource.designer.cs 18 | Resource 19 | Off 20 | false 21 | v12.0 22 | Properties\AndroidManifest.xml 23 | Resources 24 | Assets 25 | true 26 | true 27 | Xamarin.Android.Net.AndroidClientHandler 28 | 29 | 30 | True 31 | portable 32 | False 33 | bin\Debug\ 34 | DEBUG;TRACE 35 | prompt 36 | 4 37 | True 38 | None 39 | False 40 | 41 | 42 | True 43 | portable 44 | True 45 | bin\Release\ 46 | TRACE 47 | prompt 48 | 4 49 | true 50 | False 51 | SdkOnly 52 | True 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Designer 72 | 73 | 74 | Designer 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | {92e64f4e-6a8e-43c2-9c8d-694e0327bef0} 109 | TextCopy 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/AndroidApp/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.OS; 3 | using Android.Text; 4 | using Android.Widget; 5 | using AndroidX.AppCompat.App; 6 | using Toolbar = AndroidX.AppCompat.Widget.Toolbar; 7 | 8 | namespace AndroidApp 9 | { 10 | [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)] 11 | public class MainActivity : AppCompatActivity 12 | { 13 | EditText input; 14 | TextView clipboardContent; 15 | 16 | protected override void OnCreate(Bundle savedInstanceState) 17 | { 18 | base.OnCreate(savedInstanceState); 19 | Xamarin.Essentials.Platform.Init(this, savedInstanceState); 20 | SetContentView(Resource.Layout.activity_main); 21 | 22 | var toolbar = FindViewById(Resource.Id.toolbar); 23 | SetSupportActionBar(toolbar); 24 | } 25 | 26 | protected override void OnResume() 27 | { 28 | base.OnResume(); 29 | input = FindViewById(Resource.Id.input); 30 | clipboardContent = FindViewById(Resource.Id.clipboardContent); 31 | input.TextChanged += Input_TextChanged; 32 | } 33 | 34 | void Input_TextChanged(object sender, TextChangedEventArgs e) 35 | { 36 | TextCopy.ClipboardService.SetText(e.Text.ToString()); 37 | clipboardContent.Text = TextCopy.ClipboardService.GetText(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/AndroidApp/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 8 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 19 | 24 | 25 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CopyText/TextCopy/3171fc8bd8e83bdb7402425d304028f37582287a/src/AndroidApp/Resources/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /src/AndroidApp/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2c3e50 4 | #1B3147 5 | #3498db 6 | 7 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | 4 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2C3E50 4 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidApp 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /src/AndroidApp/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |