Bring in GitHub for Mac changes #107

merged 194 commits into from May 11, 2012


None yet

6 participants


This brings in a number of fixes and additions from our work on GitHub for Mac.

joshaber added some commits Aug 3, 2011
@joshaber joshaber Merge remote-tracking branch 'upstream/master' 89d194d
@joshaber joshaber Merge remote-tracking branch 'upstream/master' 15603b6
@joshaber joshaber use the scroll view's contentInset e62e735
@joshaber joshaber Merge remote-tracking branch 'upstream/master' into dev 8f1147a
@joshaber joshaber Merge remote-tracking branch 'upstream/master' 2667f2f
@joshaber joshaber re-add the rootView's layer after the view's added to a window - fixes 1987cab
@joshaber joshaber Merge remote-tracking branch 'upstream/master' 044e5ca
@joshaber joshaber Merge branch 'master' into dev 45e1552
@joshaber joshaber fix formatting 9495b5e
@joshaber joshaber actually call -tableView:willDisplayCell:forRowAtIndexPath: aad325a
@joshaber joshaber added -textView:doCommandBySelector: to TUITextViewDelegate cd77fd3
@joshaber joshaber Merge branch 'master' into dev 5e0bead
@joshaber joshaber a better attempt at calculating the cursor size 74bafe6
@joshaber joshaber clip to bounds, not the dirty rect b881ec1
@joshaber joshaber added a delegate method to get a menu for an event 48afa8a
@joshaber joshaber call super for -rightMouseDown: so that we get sent -menuForEvent: fo…
…r two-finger taps
@joshaber joshaber added a method to TUIView to make it the first responder 312d764
@joshaber joshaber commented out a category method that was unprefixed, unused, and just…
… called the prefixed version
@joshaber joshaber Merge branch 'master' into dev 974b2c8
@joshaber joshaber Merge branch 'master' into dev ec57431
@joshaber joshaber we need TUITableView+Cell to actually be in the project now 0887112
@joshaber joshaber Merge branch 'master' into dev e4f0d99
@joshaber joshaber moved the control event sending into TUIControl e623741
@joshaber joshaber some work on spell checking in tuitextview b76bb49
@joshaber joshaber Merge branch 'master' into dev 270eeea
@joshaber joshaber gotta actually add TUITableViewSectionHeader to the project 616d0e2
@joshaber joshaber expose -stringIndexForEvent: 58236e1
@joshaber joshaber show the replacement contextual menu and actually do the replacement 8ec8a5d
@joshaber joshaber s/strong/retain for people not on Xcode 4.2 ad151f9
@joshaber joshaber do the autocorrect c31343b
@joshaber joshaber a much smarter -[TUITextRenderer sizeConstrainedToWidth:]
Previously we'd call -[NSAttributedString ab_sizeConstrainedToSize:]
which would just use the -size method on a temporary text renderer.
Seems silly to do all that since we ourselves are a text renderer.
@joshaber joshaber cache more index paths 5467288
@joshaber joshaber separate framesetter creation from frame and path creation 628ade3
@joshaber joshaber added support for setting a vertical alignment on TUITextRenderer 2f577d8
@joshaber joshaber convenience method for creating a TUIImage from an NSImage 1b8d8af
@joshaber joshaber use the non-deprecated line height attributes 8263543
@joshaber joshaber use a better line height measurement that takes into account line spa…
@joshaber joshaber gotta adjust the clip rect so we don't clip the tops of the text 9a5bdb2
@joshaber joshaber some work on getting single line to scroll and clip properly ecfa59a
@joshaber joshaber Merge branch 'master' into dev
@joshaber joshaber take the easy way out with -[NSImage CGImageForProposedRect:context:h…
…ints:] for 10.6 and higher
@joshaber joshaber added a method to relayout the table layout 5a672cd
@joshaber joshaber added some delegate methods to text renderer so we know about its res…
…ponder status changes
@joshaber joshaber added delegate methods for text view's responder status a24b186
@joshaber joshaber wait a character before correcting the spelling cb365ef
@joshaber joshaber added contentMode to TUIView 7f51c27
@joshaber joshaber fixed a bug with determining the height of the first line cf4d1c6
@joshaber joshaber export the Core Text additions 356ef55
@joshaber joshaber keep the old path and frame around and restore them once we're done 4ff7c8d
@joshaber joshaber Merge remote-tracking branch 'upstream/master' into dev 396591b
@joshaber joshaber fixed a bug in the vertical positioning property c9184c8
@joshaber joshaber select the table view row regardless of whether it was already selected 7839383
@joshaber joshaber implemented a simple text field scrolling 94aa3f9
@joshaber joshaber when a text view becomes the first responder, the selection should be…
… at the end
@joshaber joshaber Revert "select the table view row regardless of whether it was alread…
…y selected"

This reverts commit 7839383.
@joshaber joshaber clear out the selection when we reloadData 65ae4f9
@joshaber joshaber better indentation dae4c42
@joshaber joshaber added the ability to have -drawRect: be called in the background 19bd867
@joshaber joshaber work on refining the autocorrect results f6c957a
@joshaber joshaber simplified the background drawing stuff 67486e2
@joshaber joshaber eliminate a warning about having multiple drawRect implementations 16b7d20
@joshaber joshaber send -mouseMoved: events down to the TUIView 48c583f
@joshaber joshaber working on adding accessibility support for text renderers 59a6f74
@joshaber joshaber send the enabled accessibility attribute 1afde6f
@joshaber joshaber consider text renderers as subviews for accessibility df61789
@joshaber joshaber only if the point's inside 9af4b86
@joshaber joshaber expose -sortedSubviews ca17bb0
@joshaber joshaber Merge remote-tracking branch 'upstream/master' into dev 685dabb
@joshaber joshaber send -mouseMoved: up the superview chain 81ef480
@joshaber joshaber compensate for replacements that change the string length 0f2fdd2
@joshaber joshaber don't replace contractions prematurely eeb7dd8
@joshaber joshaber slightly less awful if to ignore certain correction results ebadd20
@joshaber joshaber allow people to undo autocorrected results 6dd7b47
@joshaber joshaber gotta back the properties with ivars c5fa02d
@joshaber joshaber a non-deprecated method to set the view's opaqueness 75bca7c
@joshaber joshaber specify whether we want to be made first responder 7b73064
@joshaber joshaber merged in from upstream fb980ed
@joshaber joshaber draw the background color for buttons ad56ffc
@joshaber joshaber default the background color to clear 523aeed
@joshaber joshaber actually call the window movement methods when window movement happens 2f191b5
@joshaber joshaber corrected the height calculation for CTFrame 91f061b
@joshaber joshaber don't need to set the selection twice 82020ec
@joshaber joshaber always update the selection, regardless of whether the index path is …
…the same
@joshaber joshaber cache line rects since they're so fucking expensive to calculate 12ee960
@joshaber joshaber don't try to add a nil associated view 923b6a9
@joshaber joshaber only get the line bounds after we know we want that line e77049c
@joshaber joshaber centralized the line rect caching 4636d25
@joshaber joshaber sometimes the layer's frame gets screwed up after being removed from …
…the window, so make sure it's reset before it gets added back
@joshaber joshaber mouse down should always set it as the first responder c577726
@joshaber joshaber actually render the placeholder text 7e4c540
@joshaber joshaber reset the frame at each call to build the frame e5f2bc0
@joshaber joshaber added an accessor for decelerating 88fe304
@joshaber joshaber probably don't need quite *that* many cached index paths 43b6918
@joshaber joshaber send -performKeyEquivalent: to the first responder too 0d59e92
@joshaber joshaber only return YES from -performKeyEquivalent: if the selector isn't -noop: fe921c5
@joshaber joshaber up and down arrows move to the beginning and end of the line in singl…
…e line mode
@joshaber joshaber just call through to super 05af43b
@joshaber joshaber call super instead of just returning NO 9f66265
@joshaber joshaber just call through to the rootView f1f86f1
@joshaber joshaber -moveDown: shouldn't tab to next 5ed695b
joshaber added some commits Dec 17, 2011
@joshaber joshaber release the temp text renderer b7c58fe
@joshaber joshaber fixed the top content inset 4e5dd0e
@joshaber joshaber remove the tooltip when our window loses its keyness 1b6e19e
@joshaber joshaber clear out the text renders after getting rid of the subviews
that way the text renderer's responder chain gets cleaned up before
they're gone
@joshaber joshaber send rootView -removeFromSuperview
otherwise the responder chain might not be completely cleaned up
@joshaber joshaber also do auto replacement corrections 0ca0ba3
@joshaber joshaber allocate all the line origin arrays in the heap instead of the stack
it's much safer and less likely to smash the stack if you're dealing
with a large frame
@joshaber joshaber stubs for some needed key-binding implementations 0cd9401
@joshaber joshaber keep NSViewControllers in the responder chain 25a7e8c
@joshaber joshaber make sure the header view knows that it should be layed out again
this wasn't a problem in 10.7, but in 10.6 the header view wouldn't get
layed out again
@joshaber joshaber added a method for getting a string's size when constrained to a set …
…number of lines
@joshaber joshaber call through to super like a nice little class d4530c7
@joshaber joshaber implemented some more key bindings 04b2dab
@joshaber joshaber don't bother saving and restoring the old path and frame 63149dd
@joshaber joshaber fixed the positioning of the accent character popup f06c0c6
@joshaber joshaber add the standard text menu items to the text view's contextual menu 250c0cf
@joshaber joshaber added a method for adding the standard Cut / Copy / Paste items to a …
@joshaber joshaber set the frame using the accessor so that it reset the CTFrame 0b16e61
@joshaber joshaber make sure we end our tooltip if we're being removed from the view hie…
@joshaber joshaber extract the selection drawing into its own method for easier customiz…
…ation and subclassing
@joshaber joshaber fixed a bug where the spelling correction would try to correct a word…
… if you were editing it
@joshaber joshaber continue looking for a selectable index path until we find one 17c92bf
@joshaber joshaber don't log missing bindings anymore 377cd05
@joshaber joshaber allow TUINSWindows to become key 37d2b30
@joshaber joshaber don't release our hosting NSView f9b4285
@joshaber joshaber send the scroll event up the responder chain if we're not going to ha…
…ndle it
@joshaber joshaber give the window a shadow add2d1c
@joshaber joshaber release the nsView in dealloc, not right after we create it
that shit cray
@joshaber joshaber don't reuse the wholeLineRange since it might have changed 08a0505
@joshaber joshaber always nil out the unsafe nsView pointer d92f278
@joshaber joshaber nil out the NSView when it's dealloc'd ed86289
@joshaber joshaber support flashing the scroll bars even if the scroll bars are hidden 77a3716

❤️ Only issue now is that the flash looks like it's having a heart attack. I'll clean that up into something less epileptic.

Naituw commented on 6281d17 Mar 10, 2012

Awesome!! Chinese input method works.


Would this shift-click selection support de-selecting selected indexes? (It may need an array of selected indexes to work.)

@galaxas0 I'm not sure I understand your question. This is on TUITextRenderer, not the table view.

Oh, perhaps I didn't make that clear- I meant in the text. Let me explain: (the [] indicates a selection.)

The lazy brown fox jumps over the large black dog.

*press shift and select:
The lazy [brown fox jumps over the large black] dog.

*press shift and select:
[The lazy] brown fox [jumps over the large black] dog.

Notice here that in the second shift-select, the overlapping selection was deselected, and now there are two selections of text.
Would that be possible? It's not Mac-like, but would be useful for an IDE.

Correction: you can do this with command select on mac apps.

Ah, sorry, yes, that's something we should eventually do too.

Don't mean to be pushing bugs on you (i'll try and solve a few as well), but there's also a multi-line text view issue. The text view isn't a scroll view subclass, so it stops working properly after the frame height has been reached. I seem to have fixed the ability to keep text scrolling, but this makes the cursor go haywire. Should I post my half-fix here?

Yes, that's one I haven't bothered to tackle yet. I'd welcome a pull request!

Great! I'll work out the code a little bit and create a pull request!

Oh, and I have also written a fairly decent modal window alert view that uses the same API, but supports blocks, using TUINSWindow. Perhaps after a bit of brushing up, I'll add a pull request for that too.

CGRect cursorFrame = [self _cursorRect];
CGFloat offset = 0.0f;
if(singleLine) {
if(CGRectGetMaxX(cursorFrame) > CGRectGetWidth(textRect)) {
offset = CGRectGetMinX(cursorFrame) - CGRectGetWidth(textRect);
rendererFrame = CGRectMake(-offset, rendererFrame.origin.y, CGRectGetWidth(rendererFrame), CGRectGetHeight(rendererFrame));
cursorFrame = CGRectOffset(cursorFrame, -offset - CGRectGetWidth(cursorFrame) - 5.0f, 0.0f);

        renderer.frame = rendererFrame;
} else if(!singleLine) {
    CGSize z = [renderer sizeConstrainedToWidth:rendererFrame.size.width];
    if(z.height > textRect.size.height) {
        offset = (textRect.size.height - z.height);

        [renderer setFrame:CGRectMake(renderer.frame.origin.x, renderer.frame.origin.y, 
                                      renderer.frame.size.width, renderer.frame.size.height - offset)];
        cursorFrame = CGRectMake(cursorFrame.origin.x, cursorFrame.origin.y - offset, 
                                      cursorFrame.size.width, cursorFrame.size.height);

That's what I had so far for the scrolling text view. It scrolls text when you enter new lines, but not any time else. The cursor also has a tendency to go off-screen.

aroben and others added some commits Mar 21, 2012
@aroben aroben Plug a leak in -[TUITextRenderer sizeConstrainedToWidth:numberOfLines:]
The Clang Static Analyzer spotted the leak and Instruments confirmed it.
@aroben aroben Plug leaks when right-clicking in an editable text view
The leaks were spotted by the Clang Static Analyzer and confirmed by
@joshaber joshaber Merge pull request #1 from github/plug-tuitextrenderer-leak
Plug TUITextRenderer leak
@joshaber joshaber Merge pull request #2 from github/plug-tuitextview-leak
Plug leaks when right-clicking in an editable text view

Can someone enlighten me on how to use autocorrect features here? Please? :D

@galaxas01 see the autocorrectionEnabled property.

Oh! I had no idea this existed all this time.... What was I doing.... =_____= Thank you so much. I'm still working on getting the TUITextView to scroll, to no avail, but I'll try to subclass TUIScrollView and mess with it a little and see how it does.

EDIT: Just tried it, but it doesn't seem to work? I just set '[_log setAutocorrectionEnabled:YES];' and there have been no changes.


I'm at wits end with this issue I have with the TUITableView. I have drag to reorder return YES, but my moveIndexPath: method is completely empty, YET the slightest reorder motion flips the cells from A -> Z to Z -> A.


Oh, I implemented something like this in my private fork, that scales user scale * HiDPI * any other scale factors. And it's all moved to a method call, along with AtleastLion, so the dev doesn't have to set it on launch. Should I post my code?

EDIT: Is this 10.6 compatible?
EDIT 2: Nope, doesn't look like it.

@galaxas0 You're always welcome to open a pull request so we can review the code!

Oh, I'm pretty new to Github, so I'm learning how to do these things one by one, but I have an old issue posted to the original twitter/twui fork...


I can provide neatly formatted code if required? (Looks like code was butchered... more to learn for formatting) :]

@galaxas0 If you want to find out more about how pull requests work, you should take a look here:

Also -- regarding code blocks in the other issue you posted. Typically, you would present code like that in a pull request, but if you want to have it show up nicely in an issue or comment, you can use three backticks followed by the language name to initiate a code block. For example:

<your code goes here>

would generate this:

static BOOL initialized = NO;
static float screen_scale = 0.0;
static BOOL is_lion = NO;

BOOL isAtleastLion() {
  if(!initialized) {
    SInt32 major = 0;
    SInt32 minor = 0;
    Gestalt(gestaltSystemVersionMajor, &major);
    Gestalt(gestaltSystemVersionMinor, &minor);

    if((major == 10 && minor >= 7) || major >= 11) {
      is_lion = YES;
    } else {
      is_lion = NO;
      initialized = YES;

    return is_lion;

Oh wow, that's amazing-- didn't know how to do that... I will read up on it soon :D

In the meantime, let me just post the rest of the code here, very neatly formatted.

float screenScale() {
    if(screen_scale <= CGFLOAT_MIN)
        screen_scale = [[NSScreen mainScreen] userSpaceScaleFactor];

    return screen_scale;

void setScreenScale(float scale) {
    if((scale > CGFLOAT_MIN)) {
        screen_scale = scale;

Hmm... wouldn't you also need to guard the -[CALayer contentScale]? That seems to be 10.7 only as well. Well, it doesn't compile on this end, at least.

EDIT: It is indeed so...
@property CGFloat contentScale is 10.7 only.


Well right now all this does is only scales it if it's on 10.7.... how would we do this for 10.6? The old method wasn't such a good one either- the text renderers were blurry in the end and mouse events sorta died. I will look into CALayer content scaling on 10.6....

Apple won't support scaling on anything less than 10.7.

You have a point there.... alright then.

joshaber added some commits Apr 9, 2012
@joshaber joshaber update the layer's scale when the screen changes 1e6362a
@joshaber joshaber use NSWindowDidChangeBackingPropertiesNotification to watch for scale…
… changes
@joshaber joshaber method name changed 696531d
@joshaber joshaber Merge remote-tracking branch 'upstream/master' into dev
@joshaber joshaber more ARC fixes 3358884
@joshaber joshaber ARC requires 64-bit ABI c9adc20

Is there a way to have full ARC on 10.6? My project is targeting 10.6 as well, but since I'm using your fork, and it's ARC now, I'll need to find a way to add that in....

What do you mean by "full ARC?" ARC works fine on 10.6.

Really? __weak and _objc_release and the like give me compile errors o_o

Oh yes, weak is 10.7+ but TwUI doesn't use it.

Oh.... DERP. Alright, no problems then :D Thanks for the prompt reply! :D

@joshaber joshaber added TUITableViewStyleGrouped
section headers now only stick when using TUITableViewStyleGrouped

wait - this flips the usage: plain now has the header scroll like a cell, while group keeps the thing pinned to the viewport o_o

EDIT: if(_style != UXTableViewStyleGrouped) fixes this issue.


.... now my implementation of this with a modal window seems like overkill. Great job! I'll repurpose mine into an alert view then >:D

BTW, are there any plans to make TwUI UIKit API-compatible? After the ARC changes and 10.7 upgrades you've done on this fork, I kinda demolished and rebuilt my local copy of TwUI and it's far more API compatible with both iOS and Android (element-wise, the Action Bar and the sliding views, but that's only for multitouch).

EDIT: Would you mind also adding a bit of sample code to use this? Or am I just missing some nuts and bolts in my usage? :\

No, no plans to make TwUI UIKit API-compatible. However, that is the mission of Chameleon. TwUI's just trying to be the best damn layer-based UI framework a framework can be.

Oh, I understand that- I mean more API-compatible with what it has (simple things, like change alignment to textAlignment, rename methods, etc) because the way I use it, it's already more than compatible (the only things I need to rewrite from my iOS code is the event handling, but that's not much). Thanks for the answer though. :]

Ah, and is there any sample code for the TUIPopover? I think i'm missing bits here and there and it's not displaying.

Ah, yeah if it benefits the project as a whole I'm not opposed to API changes.

No TUIPopover examples yet.

Alright then. Out of curiosity, is that the new feature in Github for Mac 1.2.5? Just saw the post for it. Just a hunch.

Yep, that uses TUIPopover.

Oooh, cool. Better try to figure this popover out faster then :D Thanks!


I've added some TUIControl additions here: twitter#103
Please do check them out and use them, because otherwise I'd feel like a leech :]


Could you post a small snippet of code on how you set up the autocorrection on a text view? It's not working for me, no matter what I try :\

You should be able to just do:

textView.spellCheckingEnabled = YES;
textView.autocorrectionEnabled = YES;

Well that was..... painless, to say the least. Not sure why it didn't work for me before :\ Thanks!

@joshaber joshaber merged commit cabfe19 into twitter:master May 11, 2012

Jesus christ, this is a mother load of an update! Damn, this is amazing! THANKS! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment