Operasi Clipboard

Salin dan tempel teks dengan clipboard sistem

Operasi Clipboard

Wails menyediakan API clipboard terpadu yang bekerja di semua platform. Salin dan tempel teks dengan metode sederhana dan konsisten di Windows, macOS, dan Linux.

Mulai Cepat

go
// Copy text to clipboard
app.Clipboard.SetText("Hello, World!")

// Get text from clipboard
text, ok := app.Clipboard.Text()
if ok {
    fmt.Println("Clipboard:", text)
}

Selesai! Akses clipboard lintas platform.

Menyalin Teks

Salin Dasar

go
success := app.Clipboard.SetText("Text to copy")
if !success {
    app.Logger.Error("Failed to copy to clipboard")
}

Returns: bool - true if successful, false otherwise

Salin dari Service

go
type ClipboardService struct {
    app *application.App
}

func (c *ClipboardService) CopyToClipboard(text string) bool {
    return c.app.Clipboard.SetText(text)
}

Call from JavaScript:

javascript
import { CopyToClipboard } from './bindings/changeme/clipboardservice'

await CopyToClipboard("Text to copy")

Salin dengan Umpan Balik

go
func copyWithFeedback(text string) {
    if app.Clipboard.SetText(text) {
        app.Dialog.Info().
            SetTitle("Copied").
            SetMessage("Text copied to clipboard!").
            Show()
    } else {
        app.Dialog.Error().
            SetTitle("Copy Failed").
            SetMessage("Failed to copy to clipboard.").
            Show()
    }
}

Menempel Teks

Tempel Dasar

go
text, ok := app.Clipboard.Text()
if !ok {
    app.Logger.Error("Failed to read clipboard")
    return
}

fmt.Println("Clipboard text:", text)

Returns: (string, bool) - Text and success flag

Tempel dari Service

go
func (c *ClipboardService) PasteFromClipboard() string {
    text, ok := c.app.Clipboard.Text()
    if !ok {
        return ""
    }
    return text
}

Call from JavaScript:

javascript
import { PasteFromClipboard } from './bindings/changeme/clipboardservice'

const text = await PasteFromClipboard()
console.log("Pasted:", text)

Tempel dengan Validasi

go
func pasteText() (string, error) {
    text, ok := app.Clipboard.Text()
    if !ok {
        return "", errors.New("clipboard empty or unavailable")
    }
    
    // Validate
    if len(text) == 0 {
        return "", errors.New("clipboard is empty")
    }
    
    if len(text) > 10000 {
        return "", errors.New("clipboard text too large")
    }
    
    return text, nil
}

Contoh Lengkap

Tombol Salin

Go:

go
type TextService struct {
    app *application.App
}

func (t *TextService) CopyText(text string) error {
    if !t.app.Clipboard.SetText(text) {
        return errors.New("failed to copy")
    }
    return nil
}

JavaScript:

javascript
import { CopyText } from './bindings/changeme/textservice'

async function copyToClipboard(text) {
    try {
        await CopyText(text)
        showNotification("Copied to clipboard!")
    } catch (error) {
        showError("Failed to copy: " + error)
    }
}

// Usage
document.getElementById('copy-btn').addEventListener('click', () => {
    const text = document.getElementById('text').value
    copyToClipboard(text)
})

Tempel dan Proses

Go:

go
type DataService struct {
    app *application.App
}

func (d *DataService) PasteAndProcess() (string, error) {
    // Get clipboard text
    text, ok := d.app.Clipboard.Text()
    if !ok {
        return "", errors.New("clipboard unavailable")
    }
    
    // Process text
    processed := strings.TrimSpace(text)
    processed = strings.ToUpper(processed)
    
    return processed, nil
}

JavaScript:

javascript
import { PasteAndProcess } from './bindings/changeme/dataservice'

async function pasteAndProcess() {
    try {
        const result = await PasteAndProcess()
        document.getElementById('output').value = result
    } catch (error) {
        showError("Failed to paste: " + error)
    }
}

Salin Beberapa Format

go
type CopyService struct {
    app *application.App
}

func (c *CopyService) CopyAsPlainText(text string) bool {
    return c.app.Clipboard.SetText(text)
}

func (c *CopyService) CopyAsJSON(data interface{}) bool {
    jsonBytes, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        return false
    }
    return c.app.Clipboard.SetText(string(jsonBytes))
}

func (c *CopyService) CopyAsCSV(rows [][]string) bool {
    var buf bytes.Buffer
    writer := csv.NewWriter(&buf)
    
    for _, row := range rows {
        if err := writer.Write(row); err != nil {
            return false
        }
    }
    
    writer.Flush()
    return c.app.Clipboard.SetText(buf.String())
}

Monitor Clipboard

go
type ClipboardMonitor struct {
    app          *application.App
    lastText     string
    ticker       *time.Ticker
    stopChan     chan bool
}

func NewClipboardMonitor(app *application.App) *ClipboardMonitor {
    return &ClipboardMonitor{
        app:      app,
        stopChan: make(chan bool),
    }
}

func (cm *ClipboardMonitor) Start() {
    cm.ticker = time.NewTicker(1 * time.Second)
    
    go func() {
        for {
            select {
            case <-cm.ticker.C:
                cm.checkClipboard()
            case <-cm.stopChan:
                return
            }
        }
    }()
}

func (cm *ClipboardMonitor) Stop() {
    if cm.ticker != nil {
        cm.ticker.Stop()
    }
    cm.stopChan <- true
}

func (cm *ClipboardMonitor) checkClipboard() {
    text, ok := cm.app.Clipboard.Text()
    if !ok {
        return
    }
    
    if text != cm.lastText {
        cm.lastText = text
        cm.app.Event.Emit("clipboard-changed", text)
    }
}

Salin dengan Riwayat

go
type ClipboardHistory struct {
    app     *application.App
    history []string
    maxSize int
}

func NewClipboardHistory(app *application.App) *ClipboardHistory {
    return &ClipboardHistory{
        app:     app,
        history: make([]string, 0),
        maxSize: 10,
    }
}

func (ch *ClipboardHistory) Copy(text string) bool {
    if !ch.app.Clipboard.SetText(text) {
        return false
    }
    
    // Add to history
    ch.history = append([]string{text}, ch.history...)
    
    // Limit size
    if len(ch.history) > ch.maxSize {
        ch.history = ch.history[:ch.maxSize]
    }
    
    return true
}

func (ch *ClipboardHistory) GetHistory() []string {
    return ch.history
}

func (ch *ClipboardHistory) RestoreFromHistory(index int) bool {
    if index < 0 || index >= len(ch.history) {
        return false
    }
    
    return ch.app.Clipboard.SetText(ch.history[index])
}

Integrasi Frontend

Menggunakan Browser Clipboard API

For simple text, you can use the browser’s clipboard API:

javascript
// Copy
async function copyText(text) {
    try {
        await navigator.clipboard.writeText(text)
        console.log("Copied!")
    } catch (error) {
        console.error("Copy failed:", error)
    }
}

// Paste
async function pasteText() {
    try {
        const text = await navigator.clipboard.readText()
        return text
    } catch (error) {
        console.error("Paste failed:", error)
        return ""
    }
}

Note: Browser clipboard API requires HTTPS or localhost, and user permission.

Menggunakan Clipboard Wails

For system-wide clipboard access:

javascript
import { CopyToClipboard, PasteFromClipboard } from './bindings/changeme/clipboardservice'

// Copy
async function copy(text) {
    const success = await CopyToClipboard(text)
    if (success) {
        console.log("Copied!")
    }
}

// Paste
async function paste() {
    const text = await PasteFromClipboard()
    return text
}

Praktik Terbaik

✅ Lakukan

  • Check return values - Handle failures gracefully
  • Provide feedback - Let users know copy succeeded
  • Validate pasted text - Check format and size
  • Use appropriate method - Browser API vs Wails API
  • Handle empty clipboard - Check before using
  • Trim whitespace - Clean pasted text

❌ Jangan

  • Don’t ignore failures - Always check success
  • Don’t copy sensitive data - Clipboard is shared
  • Don’t assume format - Validate pasted data
  • Don’t poll too frequently - If monitoring clipboard
  • Don’t copy large data - Use files instead
  • Don’t forget security - Sanitise pasted content

Perbedaan Platform

macOS

  • Uses NSPasteboard
  • Supports rich text (future)
  • System-wide clipboard
  • Clipboard history (system feature)

Windows

  • Uses Windows Clipboard API
  • Supports multiple formats (future)
  • System-wide clipboard
  • Clipboard history (Windows 10+)

Linux

  • Uses X11/Wayland clipboard
  • Primary and clipboard selections
  • Varies by desktop environment
  • May require clipboard manager

Keterbatasan

Versi Saat Ini

  • Text only - Images not yet supported
  • No format detection - Plain text only
  • No clipboard events - Must poll for changes
  • No clipboard history - Implement yourself

Fitur Mendatang

  • Image support
  • Rich text support
  • Multiple formats
  • Clipboard change events
  • Clipboard history API

Langkah Selanjutnya

Bindings

Call Go functions from JavaScript.

Pelajari Selengkapnya →

Events

Use events for clipboard notifications.

Pelajari Selengkapnya →

dialogs

Show copy/paste feedback.

Pelajari Selengkapnya →

Services

Organise clipboard code.

Pelajari Selengkapnya →


Pertanyaan? Tanyakan di Discord or lihat clipboard examples.

Edit page

Last updated: