diff options
| author | Jan Djärv | 2014-10-25 15:56:22 +0200 |
|---|---|---|
| committer | Jan Djärv | 2014-10-25 15:56:22 +0200 |
| commit | 3abb316834402a3f72f80bc4826b7bbe296c35e3 (patch) | |
| tree | b03b34e5b6141ff7577eef3b8e3cdb0e5b2c65ac | |
| parent | b5ea86d124f5282992303b0d6d7146659da34026 (diff) | |
| download | emacs-3abb316834402a3f72f80bc4826b7bbe296c35e3.tar.gz emacs-3abb316834402a3f72f80bc4826b7bbe296c35e3.zip | |
* nsselect.m: pasteboard_changecount is new.
(ns_store_pb_change_count, ns_get_pb_change_count)
(ns_get_our_change_count_for): New functions.
(ns_string_to_pasteboard_internal): Correct comment.
type => gtype in eassert, Call ns_store_pb_change_count.
(Fns_own_selection_internal): Remove data, use value.
(Fns_disown_selection_internal, Fns_selection_owner_p): Replace
Vselection_alist check, with change count check.
(Fns_get_selection): Initialize val to Qnil. Only get local
selection if change counts match (Bug#18799).
(nxatoms_of_nsselect): Initialize pasteboard_changecount.
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/nsselect.m | 64 |
2 files changed, 67 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index fb724fb583f..64dabbbfadb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2014-10-25 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * nsselect.m: pasteboard_changecount is new. | ||
| 4 | (ns_store_pb_change_count, ns_get_pb_change_count) | ||
| 5 | (ns_get_our_change_count_for): New functions. | ||
| 6 | (ns_string_to_pasteboard_internal): Correct comment. | ||
| 7 | type => gtype in eassert, Call ns_store_pb_change_count. | ||
| 8 | (Fns_own_selection_internal): Remove data, use value (Bug#18799). | ||
| 9 | (Fns_disown_selection_internal, Fns_selection_owner_p): Replace | ||
| 10 | Vselection_alist check, with change count check. | ||
| 11 | (Fns_get_selection): Initialize val to Qnil. Only get local | ||
| 12 | selection if change counts match (Bug#18799). | ||
| 13 | (nxatoms_of_nsselect): Initialize pasteboard_changecount. | ||
| 14 | |||
| 1 | 2014-10-25 Noam Postavsky <npostavs@users.sourceforget.net> | 15 | 2014-10-25 Noam Postavsky <npostavs@users.sourceforget.net> |
| 2 | 16 | ||
| 3 | * src/w32proc.c (create_child): If calling a quoted batch file, | 17 | * src/w32proc.c (create_child): If calling a quoted batch file, |
diff --git a/src/nsselect.m b/src/nsselect.m index 8a2492127d8..904b3b2e17f 100644 --- a/src/nsselect.m +++ b/src/nsselect.m | |||
| @@ -45,6 +45,7 @@ NSString *NXPrimaryPboard; | |||
| 45 | NSString *NXSecondaryPboard; | 45 | NSString *NXSecondaryPboard; |
| 46 | 46 | ||
| 47 | 47 | ||
| 48 | static NSMutableDictionary *pasteboard_changecount; | ||
| 48 | 49 | ||
| 49 | /* ========================================================================== | 50 | /* ========================================================================== |
| 50 | 51 | ||
| @@ -140,6 +141,29 @@ ns_undeclare_pasteboard (id pb) | |||
| 140 | [pb declareTypes: [NSArray array] owner: nil]; | 141 | [pb declareTypes: [NSArray array] owner: nil]; |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 144 | static void | ||
| 145 | ns_store_pb_change_count (id pb) | ||
| 146 | { | ||
| 147 | [pasteboard_changecount | ||
| 148 | setObject: [NSNumber numberWithLong: [pb changeCount]] | ||
| 149 | forKey: [pb name]]; | ||
| 150 | } | ||
| 151 | |||
| 152 | static NSInteger | ||
| 153 | ns_get_pb_change_count (Lisp_Object selection) | ||
| 154 | { | ||
| 155 | id pb = ns_symbol_to_pb (selection); | ||
| 156 | return pb != nil ? [pb changeCount] : -1; | ||
| 157 | } | ||
| 158 | |||
| 159 | static NSInteger | ||
| 160 | ns_get_our_change_count_for (Lisp_Object selection) | ||
| 161 | { | ||
| 162 | NSNumber *num = [pasteboard_changecount | ||
| 163 | objectForKey: symbol_to_nsstring (selection)]; | ||
| 164 | return num != nil ? (NSInteger)[num longValue] : -1; | ||
| 165 | } | ||
| 166 | |||
| 143 | 167 | ||
| 144 | static void | 168 | static void |
| 145 | ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) | 169 | ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) |
| @@ -164,7 +188,7 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) | |||
| 164 | // FIXME: Why those 2 different code paths? | 188 | // FIXME: Why those 2 different code paths? |
| 165 | if (gtype == nil) | 189 | if (gtype == nil) |
| 166 | { | 190 | { |
| 167 | // Used for ns-store-selection-internal. | 191 | // Used for ns_string_to_pasteboard |
| 168 | [pb declareTypes: ns_send_types owner: nil]; | 192 | [pb declareTypes: ns_send_types owner: nil]; |
| 169 | tenum = [ns_send_types objectEnumerator]; | 193 | tenum = [ns_send_types objectEnumerator]; |
| 170 | while ( (type = [tenum nextObject]) ) | 194 | while ( (type = [tenum nextObject]) ) |
| @@ -173,10 +197,11 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) | |||
| 173 | else | 197 | else |
| 174 | { | 198 | { |
| 175 | // Used for ns-own-selection-internal. | 199 | // Used for ns-own-selection-internal. |
| 176 | eassert (type == NSStringPboardType); | 200 | eassert (gtype == NSStringPboardType); |
| 177 | [pb setString: nsStr forType: gtype]; | 201 | [pb setString: nsStr forType: gtype]; |
| 178 | } | 202 | } |
| 179 | [nsStr release]; | 203 | [nsStr release]; |
| 204 | ns_store_pb_change_count (pb); | ||
| 180 | } | 205 | } |
| 181 | } | 206 | } |
| 182 | 207 | ||
| @@ -340,7 +365,7 @@ anything that the functions on `selection-converter-alist' know about. */) | |||
| 340 | id pb; | 365 | id pb; |
| 341 | NSString *type; | 366 | NSString *type; |
| 342 | Lisp_Object successful_p = Qnil, rest; | 367 | Lisp_Object successful_p = Qnil, rest; |
| 343 | Lisp_Object target_symbol, data; | 368 | Lisp_Object target_symbol; |
| 344 | 369 | ||
| 345 | check_window_system (NULL); | 370 | check_window_system (NULL); |
| 346 | CHECK_SYMBOL (selection); | 371 | CHECK_SYMBOL (selection); |
| @@ -363,11 +388,9 @@ anything that the functions on `selection-converter-alist' know about. */) | |||
| 363 | /* We only support copy of text. */ | 388 | /* We only support copy of text. */ |
| 364 | type = NSStringPboardType; | 389 | type = NSStringPboardType; |
| 365 | target_symbol = ns_string_to_symbol (type); | 390 | target_symbol = ns_string_to_symbol (type); |
| 366 | data = ns_get_local_selection (selection, target_symbol); | 391 | if (STRINGP (value)) |
| 367 | if (!NILP (data)) | ||
| 368 | { | 392 | { |
| 369 | if (STRINGP (data)) | 393 | ns_string_to_pasteboard_internal (pb, value, type); |
| 370 | ns_string_to_pasteboard_internal (pb, data, type); | ||
| 371 | successful_p = Qt; | 394 | successful_p = Qt; |
| 372 | } | 395 | } |
| 373 | 396 | ||
| @@ -391,7 +414,10 @@ Disowning it means there is no such selection. */) | |||
| 391 | id pb; | 414 | id pb; |
| 392 | check_window_system (NULL); | 415 | check_window_system (NULL); |
| 393 | CHECK_SYMBOL (selection); | 416 | CHECK_SYMBOL (selection); |
| 394 | if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil; | 417 | |
| 418 | if (ns_get_pb_change_count (selection) | ||
| 419 | != ns_get_our_change_count_for (selection)) | ||
| 420 | return Qnil; | ||
| 395 | 421 | ||
| 396 | pb = ns_symbol_to_pb (selection); | 422 | pb = ns_symbol_to_pb (selection); |
| 397 | if (pb != nil) ns_undeclare_pasteboard (pb); | 423 | if (pb != nil) ns_undeclare_pasteboard (pb); |
| @@ -450,7 +476,8 @@ On Nextstep, TERMINAL is unused. */) | |||
| 450 | CHECK_SYMBOL (selection); | 476 | CHECK_SYMBOL (selection); |
| 451 | if (EQ (selection, Qnil)) selection = QPRIMARY; | 477 | if (EQ (selection, Qnil)) selection = QPRIMARY; |
| 452 | if (EQ (selection, Qt)) selection = QSECONDARY; | 478 | if (EQ (selection, Qt)) selection = QSECONDARY; |
| 453 | return (NILP (Fassq (selection, Vselection_alist))) ? Qnil : Qt; | 479 | return ns_get_pb_change_count (selection) |
| 480 | == ns_get_our_change_count_for (selection); | ||
| 454 | } | 481 | } |
| 455 | 482 | ||
| 456 | 483 | ||
| @@ -472,12 +499,15 @@ On Nextstep, TIME-STAMP and TERMINAL are unused. */) | |||
| 472 | (Lisp_Object selection_name, Lisp_Object target_type, | 499 | (Lisp_Object selection_name, Lisp_Object target_type, |
| 473 | Lisp_Object time_stamp, Lisp_Object terminal) | 500 | Lisp_Object time_stamp, Lisp_Object terminal) |
| 474 | { | 501 | { |
| 475 | Lisp_Object val; | 502 | Lisp_Object val = Qnil; |
| 476 | 503 | ||
| 477 | check_window_system (NULL); | 504 | check_window_system (NULL); |
| 478 | CHECK_SYMBOL (selection_name); | 505 | CHECK_SYMBOL (selection_name); |
| 479 | CHECK_SYMBOL (target_type); | 506 | CHECK_SYMBOL (target_type); |
| 480 | val = ns_get_local_selection (selection_name, target_type); | 507 | |
| 508 | if (ns_get_pb_change_count (selection_name) | ||
| 509 | == ns_get_our_change_count_for (selection_name)) | ||
| 510 | val = ns_get_local_selection (selection_name, target_type); | ||
| 481 | if (NILP (val)) | 511 | if (NILP (val)) |
| 482 | val = ns_get_foreign_selection (selection_name, target_type); | 512 | val = ns_get_foreign_selection (selection_name, target_type); |
| 483 | if (CONSP (val) && SYMBOLP (Fcar (val))) | 513 | if (CONSP (val) && SYMBOLP (Fcar (val))) |
| @@ -496,6 +526,18 @@ nxatoms_of_nsselect (void) | |||
| 496 | { | 526 | { |
| 497 | NXPrimaryPboard = @"Selection"; | 527 | NXPrimaryPboard = @"Selection"; |
| 498 | NXSecondaryPboard = @"Secondary"; | 528 | NXSecondaryPboard = @"Secondary"; |
| 529 | |||
| 530 | // This is a memory loss, never released. | ||
| 531 | pasteboard_changecount = | ||
| 532 | [[NSMutableDictionary | ||
| 533 | dictionaryWithObjectsAndKeys: | ||
| 534 | [NSNumber numberWithLong:0], NSGeneralPboard, | ||
| 535 | [NSNumber numberWithLong:0], NXPrimaryPboard, | ||
| 536 | [NSNumber numberWithLong:0], NXSecondaryPboard, | ||
| 537 | [NSNumber numberWithLong:0], NSStringPboardType, | ||
| 538 | [NSNumber numberWithLong:0], NSFilenamesPboardType, | ||
| 539 | [NSNumber numberWithLong:0], NSTabularTextPboardType, | ||
| 540 | nil] retain]; | ||
| 499 | } | 541 | } |
| 500 | 542 | ||
| 501 | void | 543 | void |