NAME
Mac::Pasteboard - Manipulate Mac OS X clipboards/pasteboards.
SYNOPSIS
To acquire text from the system clipboard, replacing it with your own:
use Mac::Pasteboard;
my $old_text = pbpaste();
pbcopy ("Hello, sailor!\n");
or equivalently, using the object-oriented interface,
use Mac::Pasteboard;
my $pb = Mac::Pasteboard->new ();
my $old_text = $pb->paste ();
$pb->clear ();
$pb->copy ("Hello, sailor!\n");
CAVEATS
Note that release [%% next_release %%] is an attempt to properly encode/decode everything going to and from the pasteboard. But this turned into a complete refactor. An approximation of the old factoring (with less chance of getting character encoding/decoding correct) can be had by specifying the -p
option to Makefile.PL or Build.PL.
Beginning with Mac OS 10.6 Snow Leopard, pasteboards could contain multiple items. Until I upgrade, this package can only access the first item. If your interest is in writing a droplet (that is, an application that processes files which are dropped on it), see the droplet documentation.
This module is in general ignorant of the semantics implied by the system-declared flavors, and makes no attempt to enforce them. In plainer English, it is up to the user of this module to ensure that the specified flavor is actually appropriate to the data it is used to describe. For example, if you store some data on the pasteboard as flavor 'public.jpeg', it is up to you to make sure that the data are, in fact, a valid JPEG image.
On the other hand, it is (or at least may be) convenient to get the text types encoded and decoded properly off the pasteboard. This is what the encode attribute is for. It is false by default because it appears not to work as one would hope under older versions of Mac OS. It also does not cover com.apple.traditional-mac-plain-text
because the encoding of this appears to change, and I have been unable to find documentation (or to figure out on my own) which encoding to expect. Caveat user.
Any functionality that involves any character set other than the system's native character set is disabled on versions of Perl before 5.8.4.
Some taint support was added in version 0.015_01
. Specifically, if you are running with taint support turned on, data off the pasteboard will be tainted, and an attempt to create a pasteboard with a tainted name will result in an exception. More such will be added if it seems warranted.
DESCRIPTION
This XS module accesses Mac OS X pasteboards, which can be thought of as clipboards with bells and whistles. Under Mac OS X, the system clipboard is simply a special case of a pasteboard. In the following documentation, 'clipboard' refers to the system clipboard, and 'pasteboard' refers to pasteboards in general.
This module uses the Pasteboard interface, which was introduced in Mac OS 10.3 (a.k.a. 'Panther'), so it requires Mac OS 10.3 or better to run.
The simple case of placing plain text onto and reading it from the system clipboard is accomplished by subroutines pbcopy() and pbpaste() respectively. These correspond roughly to the command-line executables of the same name, and are exported by default. If this is all you are interested in, you can stop reading here. The rest of this section describes the bells and whistles associated with a Mac OS X pasteboard.
A Mac OS X pasteboard contains zero or more data items, each of which is capable of holding one or more flavors of data. The system defines a couple pasteboards, including the system clipboard, named 'com.apple.pasteboard.clipboard'. The system clipboard is the default taken if new() is called without arguments.
Data items are identified by an item id which is provided by the creator of the item, and which (the documentation says) should only be interpreted by the creator. Item flavors may be duplicated between items but not within items. The item id is an attribute of the Mac::Pasteboard object, with the default chosen so that you should not need to worry about it unless you explicitly want more than one item on a pasteboard.
A flavor is a Uniform Type Identifier which describes the semantics of the data with which it is associated. In practice any string can be used, but you probably want to stick to the system-declared flavors if it is important to you that other software understand your data. The "SEE ALSO" section contains a link to a reference for Uniform Type Identifiers which includes a description of all the system-declared UTIs. All methods (or subroutines) that place data on or retrieve data from a pasteboard take the flavor as an argument. This argument defaults to 'com.apple.traditional-mac-plain-text'.
Data may be placed on a pasteboard only by the owner of that pasteboard. Ownership is acquired by clearing the pasteboard. In general, the owner of a pasteboard may either place data directly on to it, or place a promise of data to be generated when the data are actually requested. This module does not support placing a promise onto the pasteboard. It will retrieve data promised by another application, but can not specify a paste location for that data; it is simply returned verbatim.
METHODS
Some of the methods are documented as returning a status. This status is a dualvar, whose numeric value is the Mac OS error encountered, and whose string value is a description of the error similar to that produced by the Mac::Error 'macerror' script. Errors other than the documented pasteboard error will be described as 'Unknown error' unless Mac::Error is installed and the error is known to that module.
Note, however, that by default the fatal attribute is true, which means an error will result in an exception. If fatal is false, the status will be false for success and true for failure.
The following methods are provided:
new
$pb = Mac::Pasteboard->new( $name )
This method creates a new pasteboard object, connected to the pasteboard of the given name, creating the pasteboard if necessary. If called with no argument, you get the system clipboard, a.k.a. "kPasteboardClipboard", a.k.a. 'com.apple.pasteboard.clipboard'
. Passing undef to new() is not equivalent to calling it with no arguments at all, since undef is the encoding for "kPasteboardUniqueName".
If running with taint checking enabled, a tainted pasteboard name will cause an exception.
Note that an error in creating a new pasteboard will cause an exception, since the fatal attribute defaults to 1. If you want to get a status back, you will need to call
Mac::Pasteboard->set( fatal => 0 );
If the attempt to instantiate an object fails, the status is available from
Mac::Pasteboard->get( 'status' );
Starting with version 0.012_01
you can pass desired attributes as arguments -- the same name/value pairs that get passed to set()
. These come after the pasteboard name if any, but there is no need to specify an explicit undef
if you want to default the name but specify attributes; new()
will figure it out based on whether the number of arguments is odd or even.
clear
$status = $pb->clear()
This method clears the pasteboard. You must clear the pasteboard before adding data to it.
clone
$clone = $pb->clone ()
This method clones the pasteboard object.
copy
$status = $pb->copy( $data, $flavor, $flags )
This method puts the given data on the pasteboard, identifying it as being of the given flavor, and assigning the given pasteboard flags, which are the bitwise 'or' (a.k.a. the '|' operator) of the individual flavor flags. If $flags is omitted, kPasteboardFlavorNoFlags is used. If $flavor is omitted, undefined, or the empty string, the default flavor is used.
The pasteboard is not cleared prior to this operation; any other data of other flavors remain on the pasteboard.
If the id attribute is undef, the data are placed in the item whose id is 1. Otherwise, the data are placed in the item with the given id. It is an error to attempt to place a given flavor in a given item more than once.
flavor_encoding
$encoding = $pb->flavor_encoding( $flavor );
This method returns the Unicode encoding of the given flavor, or the default flavor if no flavor is given. If the encoding is unknown, it returns undef
.
You can actually call this as a static method, but if you do so you must provide a defined and non-empty value for $flavor
.
In fact, this is driven by a table of flavors for which the encoding is known. This table is given under encode, below.
flavor_flag_names
@names = $pb->flavor_flag_names( $flags )
This method (or subroutine) interprets its last argument as flavor flags, and returns the names of the flags set. If no recognized flags are set, you get an empty list.
If called in scalar context you get back the names joined with ', ', or 'kPasteboardFlavorNoFlags' if there are none.
flavor_tags
%tags = $pb->flavor_tags( $flavor )
This method (or subroutine) interprets its last argument as a flavor name, and returns the preferred tags associated with the flavor in a hash. The hash will have zero or more of the following keys:
extension: the preferred file name extension for the flavor;
mime: the preferred MIME type for the flavor;
pboard: the preferred NSPBoard type for the flavor;
os: the preferred 4-byte Mac OS document type for the flavor.
If called in scalar context, you get back a reference to the hash.
flavors
@flavors = $pb->flavors( $conforms_to )
This method returns the list of data flavors conforming to the given flavor currently on the pasteboard. If $conforms_to
is omitted or undef
, you get all flavors. If the id attribute is defined, you get only flavors from the corresponding pasteboard item; otherwise you get all conforming flavors. If you turn off the fatal attribute, you will get an empty list if an error occurs, and you will need to check the status attribute so see if the operation actually succeeded.
The return is a list of anonymous hashes, each containing the following keys:
flags: the flavor flags;
flavor: the flavor name;
id: the pasteboard item ID.
If called in scalar context, you get a reference to the list.
The "SEE ALSO" section has a link to the Uniform Type Identifiers Overview, which deals with the notion of type conformance.
get
$value = $pb->get( $name )
This method returns the value of the given attribute. An exception is thrown if the attribute does not exist.
This method can also be called statically (that is, as Mac::Pasteboard->get( $name )
), in which case it returns the static value of the attribute, if any.
paste
( $data, $flags ) = $pb->paste( $flavor )
If the id attribute is defined, this method returns the data of the given flavor from that pasteboard id, and the associated flavor flags; otherwise it returns the data from the last instance of that flavor found, and the associated flavor flags. If no such flavor data is found, an exception is thrown if the missing_ok attribute is false, or undef
is returned for $data if missing_ok is true.
If running with taint checking enabled, $data
will be tainted.
You test the $flags
value for individual flags by using the bitwise 'and' operator ('&'
). For example:
$flags & kPasteboardFlavorSystemTranslated
and print "This data provided by Translation Services\n";
If called in scalar context, you get $data
.
paste_all
@data = $pb->paste_all( $conforms_to )
This method returns all flavors of data on the pasteboard which conform to the given flavor. If $conforms_to
is omitted or undef, all flavors of data are returned. If the id attribute is defined, only data from that pasteboard item are returned; otherwise everything accessible is returned.
The return is a list of anonymous hashes, each having the following keys:
data: the flavor data;
flags: the flavor flags;
flavor: the flavor name;
id: the pasteboard item ID.
If called in scalar context, you get a reference to the list.
If running with taint checking enabled, the {data}
value will be tainted.
The "SEE ALSO" section has a link to the Uniform Type Identifiers Overview, which deals with the notion of type conformance.
pbcopy
pbcopy( $data, $flavor, $flags )
This convenience subroutine (not method) clears the system clipboard and then copies the given data to it. All three arguments are optional (the prototype being (;$$$)
. If $data
is undef, the value of $_
is used. If $flavor
is undef
, the default flavor is used. If $flags
is undef
, kPasteboardFlavorNoFlags is used.
In other words, this subroutine is more-or-less equivalent to the pbcopy
executable.
pbcopy_find
pbcopy_find( $data, $flavor, $flags )
This convenience subroutine (not method) clears the 'find' pasteboard and then copies the given data to it. All three arguments are optional (the prototype being (;$$$)
. If $data
is undef, the value of $_
is used. If $flavor
is undef
, the default flavor is used. If $flags
is undef
, kPasteboardFlavorNoFlags is used.
In other words, this subroutine is more-or-less equivalent to
$ pbcopy -pboard find
pbencode
$encode = pbencode();
$old_encode = pbencode( $new_encode );
This convenience subroutine (not method) returns the encode setting for the system pasteboard. If the argument is defined and not ''
, the argument becomes the new encode setting and the old encode setting is returned.
pbencode_find
$encode = pbencode_find ();
$old_encode = pbencode_find( $new_encode );
This convenience subroutine (not method) returns the encode setting for the 'find' pasteboard. if the argument is defined and not ''
, the argument becomes the new encode setting and the old encode setting is returned.
pbflavor
$default_flavor = pbflavor();
$old_default_flavor = pbflavor( $new_default_flavor );
This convenience subroutine (not method) returns the default data flavor for the system pasteboard. If the argument is defined and not ''
, the argument becomes the new default flavor and the old default flavor is returned.
pbflavor_find
$default_flavor = pbflavor_find();
$old_default_flavor = pbflavor_find( $new_default_flavor );
This convenience subroutine (not method) returns the default data flavor for the 'find' pasteboard. if the argument is defined and not ''
, the argument becomes the new default flavor and the old default flavor is returned.
pbpaste
( $data, $flags ) = pbpaste( $flavor )
This convenience subroutine (not method) retrieves the given flavor of data from the system clipboard, and its associated flavor flags. The flavor is optional, the default being the default flavor. If the given flavor is not found undef
is returned for $data
.
The functionality is equivalent to calling paste()
on an object whose id attribute is undef
.
If called in scalar context, you get $data
.
In other words, this subroutine is more-or-less equivalent to the 'pbpaste' executable.
pbpaste_find
( $data, $flags ) = pbpaste_find( $flavor )
This convenience subroutine (not method) retrieves the given flavor of data from the 'find' pasteboard, and its associated flavor flags. The flavor is optional, the default being the default flavor. If the given flavor is not found undef
is returned for $data
.
The functionality is equivalent to calling paste() on an object whose id attribute is undef.
If called in scalar context, you get $data
.
In other words, this subroutine is more-or-less equivalent to
$ pbpaste -pboard find
set
$pb = $pb->set( $name => $value ...)
This method sets the values of the given attributes. More than one attribute can be set at a time. An exception is thrown if the attribute does not exist, or if the attribute is read-only. The object is returned, so that calls can be chained.
This method can also be called statically (that is, as Mac::Pasteboard->set ($name => $value ...)). If an attribute does something useful when set statically, its description will say so. Setting other attributes statically is unsupported, at least in the sense that the author makes no representation what will happen if you do set them, and does not promise that whatever happens when you do this will not change in the future.
synch
$flags = $pb->synch()
This method synchronizes the local copy of the pasteboard with the global pasteboard, and returns the synchronization flags. This should be called on your behalf when needed, but it is exposed because one of the flags returned says whether the calling process owns the pasteboard. For example:
$pb->synch & kPasteboardClientIsOwner
or $pb->clear();
to take ownership of the pasteboard (by clearing it) if it is not already owned by the process. Note that kPasteboardClientIsOwner is not imported by default.
synch_flag_names
@names = $pb->synch_flag_names( $flags )
This method (or subroutine) interprets its last argument as synchronization flags (i.e. as the return from the synch() method), and returns the names of the flags set. If none are set, you get an empty list.
If called in scalar context you get back the names joined with ', ', or an empty string if there are none, since there is no manifest constant for synchronization flags that corresponds to 'kPasteboardFlavorNoFlags'.
ATTRIBUTES
Boolean attributes are interpreted in the Perl sense - that is, undef
, 0
and ''
are false, and anything else is true.
This class supports the following attributes:
encode
This Boolean attribute specifies whether or not certain flavors are to be encoded into and decoded from the pasteboard. Supported flavors and the encodings used are:
public.utf8-plain-text UTF-8
public.utf16-plain-text UTF-16LE
public.utf16-external-plain-text UTF-16
Flavor com.apple.traditional-mac-plain-text
(the initial default flavor) is not supported by this attribute because the normal encoding is undocumented (ASCII? MacRoman? MacSomething depending on locale?). When it has wide characters to handle it seems to get upgraded to UTF-16LE, but how to tell when this is done is also undocumented.
The default value of this attribute is defaultEncode.
default_flavor
This string attribute stores the name of the default flavor to use if a flavor is not specified in the copy() or paste() call. The default value of this attribute is defaultFlavor()
.
fatal
If this Boolean attribute is true, any pasteboard error throws an exception. If false, error codes are returned to the caller.
This attribute can be set statically, in which case it controls whether static methods throw an exception on a pasteboard error. Currently, only new() is affected by this; pbcopy() and friends are subroutines, not static methods.
Setting this statically does not affect the default value of this attribute in an instantiated object.
The default is 1 (i.e. true).
id
This integer attribute supplies the id for data to be copied to or pasted from the pasteboard. In addition to a non-negative integer, it can be set to undef
. See copy() and paste() for the effects of this attribute on their action. In most cases you will not need to change this.
The default is undef
.
missing_ok
If this Boolean attribute is true, paste() returns undef if the required flavor is missing, rather than throwing an exception if fatal is true. The pbpaste() subroutine sets this true for the object it manufactures to satisfy its request.
The default is 0 (i.e. false).
name
This read-only string attribute reports the actual name assigned to the pasteboard. Under Panther (Mac OS 10.3) or earlier it is the name passed to new(), or the name of the system pasteboard if no name was passed in. Under Tiger (Mac OS 10.4) and above, the actual name is retrieved once the pasteboard is created. If this name cannot be retrieved you get the same result as under Panther.
This name may not be the name you used to create the pasteboard, even if you used one of the built-in names. But unless you created the pasteboard using name kPasteboardUniqueName, the name will be equivalent. That is,
my $pb1 = Mac::Pasteboard->new();
my $pb2 = Mac::Pasteboard->new(
$pb1->get('name'));
gives two handles to the same clipboard.
requested_name
This read-only string attribute reports the name passed to new()
.
status
This dualvar attribute contains the status of the last operation. You can set this with an integer; the dualvar will be generated.
The static attribute contains the status of the last static method to operate on a pasteboard. Currently, this means the last call to new().
EXPORT
The pbcopy(), pbcopy_find(), pbpaste(), and pbpaste_find() subroutines are exported by default. In addition, tag ':all' exports everything, and tag ':const' exports all constants except those which must be exported explicitly (currently only coreFoundationUnknownErr). Constants are also accessible by &Mac::Pasteboard::constant_name. The following constants are defined:
Error codes
badPasteboardFlavorErr
This constant represents the error number returned when a flavor is not found on the pasteboard. It is not a dualvar -- it just represents the number of the error, which is -25133.
duplicatePasteboardFlavorErr
This constant represents the error number returned when an attempt is made to place in a pasteboard item a flavor that is already there. It is not a dualvar -- it just represents the number of the error, which is -25134.
badPasteboardIndexErr
This constant represents the error number returned when the code indexes off the end of the pasteboard. If you get it in use, it probably represents a bug in this module, and should be reported as such. It is not a dualvar -- it just represents the number of the error, which is -25131.
badPasteboardItemErr
This constant represents the error number returned when the user requests data from a non-existent item ID. It is not a dualvar -- it just represents the number of the error, which is -25132.
badPasteboardSyncErr
This constant represents the error returned when the user tries to fetch stale data from the pasteboard. Because this module is supposed to synchronize before fetching, it represents either a bug or a race condition. It is not a dualvar -- it just represents the number of the error, which is -25130.
coreFoundationUnknownErr
This constant represents the unknown error, not just an unknown error. One would think you would never get this from Apple's code, but it appears that you will get this error if the caller does not have access to the desktop. For example, you can get this error in a script running over an ssh connection, or in a cron job.
This constant is not exported with the :const tag, because there are other places it could potentially come from. If you want it, you will need to import it explicitly. It is not a dualvar -- it just represents the number of the error, which is -4960.
noPasteboardPromiseKeeperErr
This constant represents the error returned when the user tries to place promised data on the pasteboard without first registering a promise keeper callback. This package does not support promised data. This constant is not a dualvar -- it just represents the number of the error, which is -25136.
notPasteboardOwnerErr
This constant represents the error returned when the user tries to place data on the pasteboard without first becoming its owner by clearing it. It is not a dualvar -- it just represents the number of the error, which is -25135.
Flavor flags
kPasteboardFlavorNoFlags
This pasteboard flavor flag is really a value, to be used if no flags are set.
kPasteboardFlavorNotSaved
This pasteboard flavor flag indicates that the flavor's data is volatile, and should not be saved.
kPasteboardFlavorPromised
This pasteboard flavor flag indicates that the flavor's data is promised. This module does not support creating promised data.
kPasteboardFlavorRequestOnly
This pasteboard flavor flag indicates that the flavor must be requested explicitly; scanning for available flavors will not find it.
kPasteboardFlavorSenderOnly
This pasteboard flavor flag indicates that the flavor's data are only available to the process that placed it on the pasteboard.
Oddly enough, the 'pbpaste' executable seems to be able to find such data. But the Pasteboard Peeker demo application can not, so I am pretty sure this module is working OK. Unfortunately I was unable to find the source for pbpaste online, so I am unable to verify what's going on.
kPasteboardFlavorSenderTranslated
This pasteboard flavor flag indicates that the flavor's data has been translated in some way by the process that placed it on the clipboard, and it will not be saved by the Finder in clipping files.
kPasteboardFlavorSystemTranslated
This pasteboard flavor flag indicates that the flavor's data must be translated by the Translation Manager. This flag cannot be set programmatically, and the Finder will not save this data in clipping files.
Pasteboard and flavor names
defaultFlavor
This constant represents the name of the default flavor, either 'com.apple.traditional-mac-plain-text'
or 'public.utf8-plain-text'
, depending on what version of macOS you are running and how this module was installed.
kPasteboardClipboard
This constant represents the name of the system clipboard, 'com.apple.pasteboard.clipboard'
.
kPasteboardFind
This constant represents the name of the find pasteboard, 'com.apple.pasteboard.find'
.
kPasteboardUniqueName
This constant specifies that a unique name be generated for the pasteboard. Under Mac OS 10.4 (Tiger) or above, the generated name will be available in the name attribute; under Mac OS 10.3 (Panther), the generated name is unavailable, and the name attribute will be undef
.
The value of this constant is documented as (CFStringRef) NULL
, so it is represented in Perl by undef
.
Synchronization flags
kPasteboardClientIsOwner
This synchronization flag is true if the caller is the owner of the pasteboard.
kPasteboardModified
This synchronization flag indicates that the pasteboard has been modified since the last time this program accessed it, and the local copy of the pasteboard has been synchronized.
Other Exports
defaultEncode
This constant specifies the default value of the encode
attribute. This is true under macOS 10.11 El Capitan and later, and false under earlier versions.
BUGS
Please report bugs through https://rt.cpan.org/Public/Dist/Display.html?Name=Mac-Pasteboard, https://github.com/trwyant/perl-Mac-Pasteboard/issues/, or by mail to the author.
SEE ALSO
The Clipboard module by Ryan King will access text on the clipboard under most operating systems. Under macOS. recent versions use this module; older ones shell out to the pbpaste and pbcopy executables.
The pbpaste and pbcopy executables themselves are available, and described by their respective man pages.
The Pasteboard Manager Reference is available online at https://web.archive.org/web/20090718011220/http://developer.apple.com/documentation/Carbon/Reference/Pasteboard_Reference/Reference/reference.html. See also the Pasteboard Manager Programming Guide at https://web.archive.org/web/20090718063745/http://developer.apple.com/documentation/Carbon/Conceptual/Pasteboard_Prog_Guide/paste_intro/paste_intro.html.
The Uniform Type Identifiers Overview is available online at https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_intro/understand_utis_intro.html
AUTHOR
Thomas R. Wyant, III, wyant at cpan dot org
COPYRIGHT AND LICENSE
Copyright (C) 2008, 2011-2024 by Thomas R. Wyant, III
This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory LICENSES.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.