Date   

Re: Selectable text in NSTableView?

Quincey Morris
 

On May 3, 2019, at 14:52 , Jens Alfke <jens@...> wrote:

If I set the “selectable” property of the NSTextField, nothing happens.

In a similar recent scenario, I found it takes two clicks when the text field is selectable but not editable. (Well, one click and one drag, if you’re actually trying to select text.)

What makes this seem unresponsive is that there’s no I-beam cursor in selectable-but-not-editable mode. It’s there but invisible after a second click (you can even move its — invisibly — with the arrow keys), but your brain resists believing it.

The reality is, it’s probably better to go ahead and subclass NSTableView and force it to pass the first click (or first drag, more likely) to the text field. I haven’t tried to do it yet, but I think there’s no built in behavior that isn’t going to make you angry on an ongoing basis.


Re: Selectable text in NSTableView?

Alex Zavatone
 

Wild guess, but what about the “can” methods.

In the headers is there any hidden secret docs hat might help?

On May 3, 2019, at 4:52 PM, Jens Alfke <jens@mooseyard.com> wrote:

I’ve got a view-based NSTableView that uses NSTextFields. I’d like to be able to select text in some of the columns, mostly so it can be copied to the pasteboard.

If I set the “selectable” property of the NSTextField, nothing happens.
If I set the “editable” property, I can select text … but the text field immediately becomes editable when the row is clicked to select it (i.e. its background changes to white and a focus ring is drawn around it.)

I’d prefer to have the field become editable on a second click, after selecting the row. But I can’t think of a clean way of doing this without a bunch of gnarly AppKit subclassing and method-overriding. Any suggestions?

—Jens

PS: This is *MAC OS*, not iOS.


Selectable text in NSTableView?

 

I’ve got a view-based NSTableView that uses NSTextFields. I’d like to be able to select text in some of the columns, mostly so it can be copied to the pasteboard.

If I set the “selectable” property of the NSTextField, nothing happens.
If I set the “editable” property, I can select text … but the text field immediately becomes editable when the row is clicked to select it (i.e. its background changes to white and a focus ring is drawn around it.)

I’d prefer to have the field become editable on a second click, after selecting the row. But I can’t think of a clean way of doing this without a bunch of gnarly AppKit subclassing and method-overriding. Any suggestions?

—Jens

PS: This is *MAC OS*, not iOS.


Re: Crash in dragImageForSelection

John Brownie
 

Gary L. Wade wrote on 27/4/19 02:07:
The bug in documentation has been reported.

Try forcing layout on the text view after setting the selection; there might be some kind of delay from setting it till it’s renderable, and that might get it refreshed.
Doesn't seem to help.
On Apr 26, 2019, at 11:51 AM, Ben Kennedy <ben-groups@zygoat.ca> wrote:


First of all, you're treating textView as an optional sometimes, and force-unwrapping it elsewhere. Prefacing the whole block with a `guard` or `if let` would clean this up.
Yes, it's a result of various ways of setting the range correctly. I've fixed it so it looks nicer.
More on topic, I looked up the documentation for `setSelectedRange()`, and it is strange:

https://developer.apple.com/documentation/appkit/nstextview/1449256-setselectedrange?language=objc

charRange: A non-nil, non-empty array of objects responding to the NSValue rangeValue method. The ranges in the ranges array must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
The method clearly takes an NSRange argument, but the documentation instead talks about an array of NSValue objects. WTH? I guess this is a documentation error? (Somebody file a radar... crickets)

If you call `selectedRange` immediately after `setSelectionRange(…)`, does it reflect the range you tried to set?
Yes, the range is correct after calling setSelectedRange.

I wonder if the answer is to draw my own drag image...

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland


Re: Crash in dragImageForSelection

Gary L. Wade
 

The bug in documentation has been reported.

Try forcing layout on the text view after setting the selection; there might be some kind of delay from setting it till it’s renderable, and that might get it refreshed.
--
Gary L. Wade
http://www.garywade.com/

On Apr 26, 2019, at 11:51 AM, Ben Kennedy <ben-groups@zygoat.ca> wrote:


On 26 Apr 2019, at 4:26 am, John Brownie <john_brownie@sil.org> wrote:

I have what seems to be a simple operation to perform, but it crashes. I have a custom view which includes an NSTextView called textView. In the mouseDragged(with:) function in my view subclass, I have the following code (leaving out the logic deciding whether it is appropriate as a drag source):

textView?.setSelectedRange(NSMakeRange(0, textView!.textStorage!.length))
let dragImage = textView?.dragImageForSelection(with: event, origin: nil)
I don't have any useful help for you, but a couple of things struck me as odd about this.

First of all, you're treating textView as an optional sometimes, and force-unwrapping it elsewhere. Prefacing the whole block with a `guard` or `if let` would clean this up.

More on topic, I looked up the documentation for `setSelectedRange()`, and it is strange:

https://developer.apple.com/documentation/appkit/nstextview/1449256-setselectedrange?language=objc

charRange: A non-nil, non-empty array of objects responding to the NSValue rangeValue method. The ranges in the ranges array must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
The method clearly takes an NSRange argument, but the documentation instead talks about an array of NSValue objects. WTH? I guess this is a documentation error? (Somebody file a radar... crickets)

If you call `selectedRange` immediately after `setSelectionRange(…)`, does it reflect the range you tried to set?

b


Re: Crash in dragImageForSelection

Ben Kennedy
 

On 26 Apr 2019, at 4:26 am, John Brownie <john_brownie@sil.org> wrote:

I have what seems to be a simple operation to perform, but it crashes. I have a custom view which includes an NSTextView called textView. In the mouseDragged(with:) function in my view subclass, I have the following code (leaving out the logic deciding whether it is appropriate as a drag source):

textView?.setSelectedRange(NSMakeRange(0, textView!.textStorage!.length))
let dragImage = textView?.dragImageForSelection(with: event, origin: nil)
I don't have any useful help for you, but a couple of things struck me as odd about this.

First of all, you're treating textView as an optional sometimes, and force-unwrapping it elsewhere. Prefacing the whole block with a `guard` or `if let` would clean this up.

More on topic, I looked up the documentation for `setSelectedRange()`, and it is strange:

https://developer.apple.com/documentation/appkit/nstextview/1449256-setselectedrange?language=objc

charRange: A non-nil, non-empty array of objects responding to the NSValue rangeValue method. The ranges in the ranges array must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
The method clearly takes an NSRange argument, but the documentation instead talks about an array of NSValue objects. WTH? I guess this is a documentation error? (Somebody file a radar... crickets)

If you call `selectedRange` immediately after `setSelectionRange(…)`, does it reflect the range you tried to set?

b


Crash in dragImageForSelection

John Brownie
 

I have what seems to be a simple operation to perform, but it crashes. I have a custom view which includes an NSTextView called textView. In the mouseDragged(with:) function in my view subclass, I have the following code (leaving out the logic deciding whether it is appropriate as a drag source):

            textView?.setSelectedRange(NSMakeRange(0, textView!.textStorage!.length))
            let dragImage = textView?.dragImageForSelection(with: event, origin: nil)

I've tried a variety of ways to select the whole text, but nothing changes the result. I get a crash in dragImageForSelection, with the message:

Cannot lock focus on image <NSImage 0x6000017f5640 Size={0, 0} Reps=() flipped:YES (flippedness is deprecated)>, because it is size zero.

The text is most often of length one (always in testing), and is often plain ASCII, but is always valid Unicode. Here's a sample of the textView and its textStorage:

(lldb) po textView
▿ Optional<NSTextView>
  - some : <NSTextView: 0x600003327200>
    Frame = {{2.50, 2.50}, {42.50, 42.50}}, Bounds = {{0.00, 0.00}, {42.50, 42.50}}
    Horizontally resizable: NO, Vertically resizable: NO
    MinSize = {34.00, 34.00}, MaxSize = {42.50, 10000000.00}


(lldb) po textView?.textStorage
▿ Optional<NSTextStorage>
  - some : 2{
    NSColor = "Generic Gray Gamma 2.2 Profile colorspace 1 1";
    NSFont = "\"LucidaGrande 22.50 pt. P [] (0x600000d719e0) fobj=0x100f6a270, spc=7.12\"";
    NSParagraphStyle = "Alignment 2, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 1.1, LineBreakMode 0, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n 140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n 308L,\n    336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation YES, HeaderLevel 0";
}

If I leave out the selection line, I don't get a crash, but then I don't get an image to drag.

Searching hasn't turned up anything of use. This was working in an earlier version of the app, written in Objective-C, and I'm unable to spot a significant difference in the code.

Anybody have an idea what is going wrong?

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland


Re: macOS Drag and Drop onto App Icon

Marco S Hyman
 


My problem is finding a correct (App Store approval) method to enable drag and drop to the App Icon.
I thought this was answered earlier. Implement this in your app delegate

// MARK: Open File (UTI support)

/// process files give to us via "Open With..."
///
/// - parameter sender: unused
/// - parameter fileName: path of file to process
/// - returns: true if the file was opened
///
/// If multiple files are specified the function appears to be called once per file.

func application(_ sender: NSApplication,
openFile filename: String) -> Bool {
let url = URL(fileURLWithPath: filename)
/// do something with URL Return true if OK

return false
}

I think that is all that is necessary.

And with that, a caveat. My “do something” code happens to eventually contain this:

updateGroup.enter()
DispatchQueue.global(qos: .userInitiated).async {
// some code
DispatchQueue.main.async {
// more code
updateGroup.leave()
}
}

When I drag a file onto the app icon my app dies with

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't posix_spawn: error 1'
abort() called
terminating with uncaught exception of type NSException

I don’t think it did that before I added the DispatchQueue. I just discovered this. Something else to debug.

Marc


Re: Strange Memory Patterns

Sandor Szatmari
 

Jonathan,

Thanks for the solution of sending events to perturb the main runloop.  With a little googling, I adapted your solution as follows…

Cheers!

double delayInSeconds = 2.0;

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,

0,

0,

dispatch_get_main_queue());

void (^memorySentinel)(void) = ^()

{

NSLog( @"I'm firing!" );

NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined

location:NSZeroPoint

  modifierFlags:0

  timestamp:[NSDate timeIntervalSinceReferenceDate]

windowNumber:0

context:nil

subtype:0

  data1:0

  data2:0];

[NSApp postEvent:event

atStart:YES];

};

if (timer)

{

dispatch_source_set_timer(timer,

  dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC),

  delayInSeconds * NSEC_PER_SEC,

  (1ull * NSEC_PER_SEC) / 10);

dispatch_source_set_event_handler(timer, memorySentinel);

dispatch_resume(timer);

}

else

{

// tell someone?

}


Sandor

On Apr 25, 2019, at 04:44, Jonathan Taylor <jonathan.taylor@...> wrote:

This sounds very similar to problems I have encountered myself.

Issue 1: GCD callbacks are part of an autorelease pool, but you can't rely on it getting drained in a reliable manner, so wrap your callbacks with your own explicit pool.

Issue 2: Background apps do not seem to always have their main thread autorelease pools drained reliably. A snippet of code I've posted a few times over the years:

// Create a periodic timer that "tickles" the main event loop to drain autorelease pools.
// Response from cocoa-dev discussion was that:
//  This is a long-standing problem with AppKit. According to the documentation,
//  "The Application Kit creates an autorelease pool on the main thread at the
//  beginning of every cycle of the event loop, and drains it at the end, thereby
//  releasing any autoreleased objects generated while processing an event."
//  However, this is somewhat misleading. The "end" of the event loop cycle is
//   immediately before the beginning. Thus, for example, if your app is in the background
//   and not receiving events, then the autorelease pool will not be drained. That's why
//   your memory drops significantly when you click the mouse or switch applications.
[JDispatchTimer allocRepeatingTimerOnQueue:dispatch_get_main_queue() atInterval:5.0 withHandler:^{
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDatewindowNumber:0 context:nil subtype:0 data1:0 data2:0];
[NSApp postEvent:event atStart:YES];
}];
 
 


Re: Strange Memory Patterns

Jonathan Taylor
 

> Do you suspect that throwing them on their own queue that you made would be an easy way to solve that?

In terms of my own issue, the work items I'm dealing with are GUI-related so their natural home is on the main queue. I don't know if it's possible to have a dedicated named queue that "lives" on the main thread, and whether that would solve anything here, but it's not something I've tried.


Re: Strange Memory Patterns

Alex Zavatone
 

Nice observation, Jonathan.  Do you suspect that throwing them on their own queue that you made would be an easy way to solve that?

I’d try it out myself, but am not in the best location to do that at the moment.  

Cheers.

Alex Zavatone

On Apr 25, 2019, at 10:44 AM, Jonathan Taylor <jonathan.taylor@...> wrote:

This sounds very similar to problems I have encountered myself.

Issue 1: GCD callbacks are part of an autorelease pool, but you can't rely on it getting drained in a reliable manner, so wrap your callbacks with your own explicit pool.

Issue 2: Background apps do not seem to always have their main thread autorelease pools drained reliably. A snippet of code I've posted a few times over the years:

// Create a periodic timer that "tickles" the main event loop to drain autorelease pools.
// Response from cocoa-dev discussion was that:
//  This is a long-standing problem with AppKit. According to the documentation,
//  "The Application Kit creates an autorelease pool on the main thread at the
//  beginning of every cycle of the event loop, and drains it at the end, thereby
//  releasing any autoreleased objects generated while processing an event."
//  However, this is somewhat misleading. The "end" of the event loop cycle is
//   immediately before the beginning. Thus, for example, if your app is in the background
//   and not receiving events, then the autorelease pool will not be drained. That's why
//   your memory drops significantly when you click the mouse or switch applications.
[JDispatchTimer allocRepeatingTimerOnQueue:dispatch_get_main_queue() atInterval:5.0 withHandler:^{
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDatewindowNumber:0 context:nil subtype:0 data1:0 data2:0];
[NSApp postEvent:event atStart:YES];
}];
 
 


Re: Strange Memory Patterns

Jonathan Taylor
 

This sounds very similar to problems I have encountered myself.

Issue 1: GCD callbacks are part of an autorelease pool, but you can't rely on it getting drained in a reliable manner, so wrap your callbacks with your own explicit pool.

Issue 2: Background apps do not seem to always have their main thread autorelease pools drained reliably. A snippet of code I've posted a few times over the years:

// Create a periodic timer that "tickles" the main event loop to drain autorelease pools.
// Response from cocoa-dev discussion was that:
//  This is a long-standing problem with AppKit. According to the documentation,
//  "The Application Kit creates an autorelease pool on the main thread at the
//  beginning of every cycle of the event loop, and drains it at the end, thereby
//  releasing any autoreleased objects generated while processing an event."
//  However, this is somewhat misleading. The "end" of the event loop cycle is
//   immediately before the beginning. Thus, for example, if your app is in the background
//   and not receiving events, then the autorelease pool will not be drained. That's why
//   your memory drops significantly when you click the mouse or switch applications.
[JDispatchTimer allocRepeatingTimerOnQueue:dispatch_get_main_queue() atInterval:5.0 withHandler:^{
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:[NSDate timeIntervalSinceReferenceDatewindowNumber:0 context:nil subtype:0 data1:0 data2:0];
[NSApp postEvent:event atStart:YES];
}];
 
 


Re: Strange Memory Patterns

Sandor Szatmari
 

It is a standard GUI MacOS app. No special options. It runs in user space like any other user focused Mac app. To be clear, when I say background, I mean it’s menubar is not the menubar being shown in finder, ie. It’s not the ‘frontmost’ application. Or in code speak NSRunningApplication’s -active method would return no for this application. Clicking on the App’s dock icon to bring the app to the foreground, so it’s menubar is displayed in the finder, is what causes the memory to be released.

Sandor

On Apr 24, 2019, at 16:44, Alex Zavatone via Groups.Io <zav=mac.com@groups.io> wrote:

What background options have you enabled in the app? I admit that I am unfamiliar with Mac policy on background apps and only ask with iOS background.
On Apr 24, 2019, at 9:41 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

We have an app that handles incoming server connections. For each connection it opens a window that shows the activity of the connection. When the client is done the window closes. When the activity happens while the app is in the background the application does not release memory and appears to leak. However, when I bring the app to the foreground the backlog of memory is released. It looks like auto release pools that aren’t popped until the app is foregrounded. I can track that down, but I thought I’d ask if anyone could identify this as a known issue before going down that path.

MacOS Sierra
Xcode 8.1
Build SDK 10.9
Deployment Target 10.6

Sandor




Re: Strange Memory Patterns

Alex Zavatone
 

What background options have you enabled in the app? I admit that I am unfamiliar with Mac policy on background apps and only ask with iOS background.

On Apr 24, 2019, at 9:41 PM, Sandor Szatmari <admin.szatmari.net@gmail.com> wrote:

We have an app that handles incoming server connections. For each connection it opens a window that shows the activity of the connection. When the client is done the window closes. When the activity happens while the app is in the background the application does not release memory and appears to leak. However, when I bring the app to the foreground the backlog of memory is released. It looks like auto release pools that aren’t popped until the app is foregrounded. I can track that down, but I thought I’d ask if anyone could identify this as a known issue before going down that path.

MacOS Sierra
Xcode 8.1
Build SDK 10.9
Deployment Target 10.6

Sandor


Strange Memory Patterns

Sandor Szatmari
 

We have an app that handles incoming server connections. For each connection it opens a window that shows the activity of the connection. When the client is done the window closes. When the activity happens while the app is in the background the application does not release memory and appears to leak. However, when I bring the app to the foreground the backlog of memory is released. It looks like auto release pools that aren’t popped until the app is foregrounded. I can track that down, but I thought I’d ask if anyone could identify this as a known issue before going down that path.

MacOS Sierra
Xcode 8.1
Build SDK 10.9
Deployment Target 10.6

Sandor


Re: macOS Drag and Drop onto App Icon

 



On Apr 20, 2019, at 3:31 PM, Bill Pitcher <bill@...> wrote:

My problem is finding a correct (App Store approval) method to enable drag and drop to the App Icon.
I'm fan of this Mac feature and consider it an act of "user intent" but I can't find a override to get the dropped URL.

Same as it ever was — just implement the -application:openFile: method in your app delegate.
You also need to edit your Info.plist to include the document types your app knows how to open.

To my knowledge, none of this is affected by sandboxing. The sandbox allows your app to access any files that the user has explicitly asked it to open, via drag-and-drop or the Open panel.

—Jens


Re: macOS Drag and Drop onto App Icon

Bill Pitcher
 

for archive sake…

As is often the case with my problems, it lay between the keyboard and the seat.

Answer: check the filename before making it into a URL

.expandingTildeInPath
fileURLWithPath:

are your friends. It sure produced some interesting messages in console which put me off the scent.

Also os.log is a great tool to deal with the unruly console log, I remember when you could get that console torrent completely silent.

Thanks
Bill

On 21 Apr 2019, at 8:31 am, Bill Pitcher <bill@ilike.co.nz> wrote:

Hi Folks,

I will dispense with a rant about the eroding freedoms and the pains of sandboxing.


My problem is finding a correct (App Store approval) method to enable drag and drop to the App Icon.

I'm fan of this Mac feature and consider it an act of "user intent" but I can't find a override to get the dropped URL.

Code examples are always good too.

Thanks
Bill


Re: validateUserInterfaceItem not called

Alex Zavatone
 

My guess is that it remembers what the first responder was before, so resigning a first responder would return the responder to the previous one, like popping a value from the the stack. I guess it’s time for me to read up on the responder chain to see how it really tracks this.

On Apr 21, 2019, at 7:21 PM, John Brownie <john_brownie@sil.org> wrote:

Alex Zavatone via Groups.Io wrote on 21/4/19 12:16:
Sorry if this is too late, but isn’t there a resignFirstResponder that you could call on the text field?
That doesn't work, either. I was trying to force it bottom-up (I thought that the next responder would automatically be made first), but it seems to want to be driven from the top, at the window level.

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland



Re: validateUserInterfaceItem not called

John Brownie
 

Alex Zavatone via Groups.Io wrote on 21/4/19 12:16:
Sorry if this is too late, but isn’t there a resignFirstResponder that you could call on the text field?
That doesn't work, either. I was trying to force it bottom-up (I thought that the next responder would automatically be made first), but it seems to want to be driven from the top, at the window level.

John
--
John Brownie
Mussau-Emira language, New Ireland Province, Papua New Guinea
Kouvola, Finland


Re: validateUserInterfaceItem not called

Alex Zavatone
 

Sorry if this is too late, but isn’t there a resignFirstResponder that you could call on the text field?

Cheers,
Alex Zavatone

On Apr 18, 2019, at 11:55 AM, Jeremy Hughes via Groups.Io <moon.rabbit=virginmedia.com@groups.io> wrote:

I think you should be calling (NSWindow) makeFirstResponder.

Jeremy



501 - 520 of 1422