Synergy Advance progress report
-
Greg Hurrell
I am pleased to report that tonight I hit the first major milestone in the Synergy Advance development roadmap.
Up until now I have been working on application design and a framework called WOBase that is common to Synergy Advance and other future Wincent apps, such as GetSmart Pro. (WinHex, which is already out, is the first product using the framework to be released to the public.)
Tonight I started work on the first code specific to Synergy Advance (ie. custom code, that won't be reusable in any other app). This means I'm on the road to the first public beta release (version 0.1). Please, don't ask for predictions about a release date, because it's still too early to say. But it is good to know that progress is being made...
-
Krypton
I look forward to seeing what this app offers
-
Greg Hurrell
Out of interest, as of right now, the Synergy Advance codebase contains 5,286 lines of code. Thought I'd post this here because it will be interesting to see the rate it grows over the coming months...
(To give you some idea of what this means, this compares with the 40,000 to 50,000 that are in Synergy.)
-
Krypton
Hmmmm that's a lot of lines.... or not very many compared to Office.
Might we see some screenshots as things progress?
-
Greg Hurrell
Quote: Might we see some screenshots as things progress?
I don't have any plans to post screenshots, because I'll be releasing early (at version 0.1) so you'll be able to see it for yourself.
One reason why I will be remaining tight-lipped about forthcoming features is that I am aware of how much copying occurs in the industry. It's a somewhat painful lesson that I learnt with Synergy: that every good idea I had would be immediately copied by a number of competitors. So, basically, I have no intention of talking about future features because it will only give these people a "to do" list to start working on. I'd rather they be totally surprised when the feature comes to market and then they're forced to play "catch up" and implement their own copy if they want to continue to be seen to be "innovating".
I've come to realise that one of the most valuable resources a software outfit can have is ideas, so I'll be doing my best to protect that resource from here on in.
So that's why I am happy to let people know that development on Synergy Advance is occurring, but that I am not making specific comments about what its capabilities will be. All I can do right now is make vagues statements along the lines of, "Synergy Advance will be able to do all the things that, for technical reasons, are just not practical to implement in Synergy". There will be some feature overlap between the two programs, but as Synergy Advance development continues the gap is only going to widen. Hopefully you'll agree with me that it'll be worth the wait.
-
Krypton
As long as there's a playlist menu generated from the xml file I shall be very happy
Although it may be bad for you, having plagiarising competitors is good for us (users) as it forces you to think about better features.
-
Greg Hurrell
Quote: Although it may be bad for you, having plagiarising competitors is good for us (users) as it forces you to think about better features.
Unfortunately, I've never had any trouble coming up with ideas; it's finding the time to implement them that's the problem...
But making good progress right now: total after another day's work: 5,781 lines of code in WOBase, and 598 in the Synergy Advance-specific stuff.
-
Greg Hurrell
Almost done for the day (12:10 AM): 6,120 framework lines, 747 Synergy Advance-specific lines.
updated multi-threading locking mechanisms to use the new Objective-C @synchronized directive where appropriate instead of the old NSLock class. updated and expanded accessor macros, now supplying a "fast", "default", and "thread-safe" variants. wrote up plenty of notes, documentation, and did quite a bit of research. secret stuff...
-
Greg Hurrell
Went away for the day on Sunday, and ended up getting back after lunchtime today (Monday), so didn't get a lot of coding done. I did, however, have an idea or two while I was away, and I'm in the process of implementing it now.
I've made a new NSObject subclass and inserted it into the object hierarchy throughout the entire project so that every class is a direct or eventual descendent of my new (WOObject) class. I'm in the process of adding all sorts of nifty stuff in this class which will enable me to elegantly and transparently do some handy memory debugging and unit testing. This complements and extends all the unit testing stuff I wrote the other day.
[Remember how some of the less well-informed Mac enthusiasts used to speculate that the reason why certain versions of Mac OS X were so slow was that Apple had "forgotten to turn off the debug code"... well, the debug code I am talking about here is definitely the sort of code that could slow your app down if you shipped it with it all "turned on"; but the flip side of the coin is that when it is "turned off" it is completely omitted from the project and doesn't add any baggage at all. And I have no intention of "forgetting to turn it off"...]
At the end of the day this kind of thing doesn't translate directly into a shiny button in the UI that the user can press and say, "Wow!", but it does make it easier to produce reliable, bug-free, well-tested, robust code. And a little bit of time spent laying this groundwork now could pay off greatly later on in terms of time saved, time that would otherwise have been spent chasing bugs.
-
Greg Hurrell
Work continues... just finished setting up automated build numbering which embeds a build number and a time stamp in the build in the WOBase framework; this will come in handy when it comes time to do troubleshooting or bug reporting. As in the past, achieving this involved battling with both AppleScript and sed, neither of which I am very enamoured with (especially in the case of sed), but this time I actually managed to bend them to my will without any swearing. This must be a first for me.
Other low level stuff I've been working on lately includes retain/release, alloc/dealloc tracking (once again for debugging), more unit testing stuff, some useful extensions to NSDictionary, and some macros which should enable me to churn out quicker code with less scope for making clumsy typing errors.
High level stuff I've been working on, and will continue with tomorrow, mostly revolves around the preferences system. The new system will allow me to cram a lot more options in, and I'll be using the same basis in GetSmart Pro as well.
Next up: a custom table view which will allow me to really pack in the options under the "Advanced" section without losing readability and clearness.
-
Greg Hurrell
Lots of ground covered on the preferences system today; making it as close as I can to Apple's own System Preferences. Testing, testing, testing... and much to my delight everything works. Along the way made some more macros that should save me a bit of time and make it easier to write more robust code.
-
Greg Hurrell
Preferences window now remembers its position across runs, also handles the fact that the window size can vary depending on which prefPane is being displayed; more work on the "Show all" view; and the system now handles the case where only a single pane is provided.
-
Greg Hurrell
Worked on various things today to make the preferences window behave more like Apple's System Preferences: draggable buttons for the "Show all" view; when dragging, both the labels and the button graphics move together; creating NSImages from NSViews, and more... basically just being perfectionistic.
This is one job I want to do only once, and do it right. It makes sense to do it well because I should be able to use it with every other product I release in the future.
-
Greg Hurrell
"Show all" view now available alphabetically, or organized by categories like Apple's System Preferences. Switching between views implemented, and I am about to add a caching mechanism. Like Apple's System Preferences, launch time is kept to a minimum because panes are only loaded when the user clicks on them; but loaded panes are kept in memory to speed up subsequent accesses. Next up: the toolbar.
-
Greg Hurrell
When switching between panes, a dissolve transition is used just like that in Apple's System Preferences application on 10.3. Now that I've written the code for this, I might see if I can find other creative uses for it in other places (specifically, I am thinking of some windows in GetSmart Pro which could also use the effect). Very happy with the appearance of it.
Needless to say, I've also implemented the older 10.2-style switching, where the window animates but does not do a cross-dissolve. Like just about everything else in Synergy Advance and GetSmart Pro I'll make it possible for the user to specify a preference for which transition style they prefer.
Now, back to that toolbar!
-
Greg Hurrell
Ok... the toolbar is now basically done. You can show or hide the toolbar and drag items around on it just like in the Apple System Preferences application. Active panes are highlighted with a tinted rectangle just like they are in System Preferences on 10.3. Again, like the Apple app, you can't drag the "Show all" item around, nor can you get a contextual menu on the toolbar. Customizations made to the toolbar are remembered across runs.
The only thing left to do tomorrow, and this should be very easy to knock off, is making it possible to drag icons from the "Show all" view to the toolbar, and then it's done; an almost pixel-perfect replication of the System Preferences application for use as a preferences window within all of my future apps. The only thing I haven't replicated is the striped shading you see across categories in 10.3; instead I've just used normal separator lines.
The whole system is about 2,000 lines of source code -- including the main class I've developed and the categories I've written to support the class -- but tomorrow I'll go over it and see if I can trim it down a bit. After that, more work on the Synergy Advance core!
-
Greg Hurrell
Created
,
edited
Ok, the preferences window is, as far as I can tell, done (screenshot below). I still have to write the individual panes, but the overall architecture for managing them is complete. The screenshot is a bit boring, I know; you have to imagine it with proper icons, and with more of them... I am looking at using Cocoa Bindings for writing the panes, something I can do because Synergy Advance and GetSmart Pro are both for 10.3 and up only... The idea is to eliminate a heap of glue code between your Models and your Views; unfortunately though, this glue code is replaced with a morass of clicking and binding down in Interface Builder. I guess I won't know if I prefer it until I've tried it, and mastered it. This will be the first time I've used Cocoa Bindings, you see.
[screenshot temporarily deleted due to server reorganization]
-
Ben
Heya Wincent,
Just wandering if there's been much progress on Synergy Advance of late?
Not that we're waiting with baited breath...
Ben
-
Greg Hurrell
Quote: Heya Wincent,
Just wandering if there's been much progress on Synergy Advance of late?
Not that we're waiting with baited breath...
Ben
Erm... in this very thread if you look over the last seven days you'll see that I've posted a daily progress report detailing what I've done each day... Hehe...
Today: hot key code. The hot key code in Synergy is pretty much welded into the program; much like your spine is an inseparable part of your skeleton. Today I've been working on a much improved, elegant, and reusable implementation of the hot key technology that can be re-used in Synergy Advance, GetSmart Pro, and every other app I release in the future. Without going into details, the code is much more flexible and will allow me to do much more with hot keys...
I'm working full time on this now, getting as much as 10 hours of coding done per day. But the bank account is dwindling rapidly, so I am not sure how much longer I can keep this up for, living off savings. I am making the most of it while I can though!
-
Ben
LOL (at me) for some reason last night where it said "Mar" I was reading "Nov" I didn't that that I'd had THAT much Whisky!!!
Anyway still waiting with baited breath
Ben
-
Greg Hurrell
It's been an extremely busy few days for me. WinSwitch is out (first 1.0 and now 1.1), and I've released two updates to Install and one for Synergy...
But now, back to work on Synergy Advance (and GetSmart Pro... all this stuff I am working on now is common code between both apps). More hot key work today: serialization etc.
-
Greg Hurrell
More hot key work today, put in place a more consistent error logging mechanism, added some wrappers for some more Carbon calls, and I've improved my preference pane cross-dissolve effect by using a more accurate timing mechanism.
[Later today (Monday) you'll also see a WinSwitch 1.2 release, which is a major update.]
-
Greg Hurrell
Improved copy protection. These are some major components and I will probably be spending quite a few days on them. I'm also writing up an article to help people understand why I'm doing this...
-
Krypton
Quote: Improved copy protection. These are some major components and I will probably be spending quite a few days on them. I'm also writing up an article to help people understand why I'm doing this...
Is that piracy protection, or something else?
-
Greg Hurrell
Quote: Is that piracy protection, or something else?
Yes, I used "copy protection" as a synonym for "piracy protection". What else would it be?
-
Krypton
Maybe for album covers, I don't know. Having not explicitly said 'piracy' I thought that your use of copy meant something else...
-
Greg Hurrell
For the past couple of days have been working on a revamp of the website. I will be migrating all of my sites over to the new look and using a consistent nav bar across all the sites for easier navigation. For example, some people wind up at the dot-org when they're really looking for the dot-com and vice versa. I will be trying to make navigation as straightforward as possible, across all the domains I control, including these forums, the bug-tracking website and the product websites. I've now got some nice PHP that automates the dynamic elements in the nav bar.
-
Greg Hurrell
Have set up a secure subdomain using SSL to provide an additional degree of security when interacting with customers, for example, during product activation, or when retrieving lost serial numbers etc.
-
anonymous
It's now May 6th (PST time zone, at least). I thought you were posting regular day-to-day reports, yet your last report was the 15th! What happened?
-
Greg Hurrell
Quote: It's now May 6th (PST time zone, at least). I thought you were posting regular day-to-day reports, yet your last report was the 15th! What happened?
I will shortly be rolling out new versions of Synergy and WinSwitch. More on progress that's been made with Synergy Advance (and GetSmart Pro) later...
-
Greg Hurrell
More work on hot keys.
-
anonymous
Any more news on Synergy Advance progress? Or anything new happening with Synergy?
-
zerock
any news on new synergy or synergy advance, i cant wait
-
Greg Hurrell
Synergy 1.0 is almost ready to go out the door.
-
Greg Hurrell
Quote: Synergy 1.0 is almost ready to go out the door.
And out the door it did go...
Apart from that, today I've been working on a bunch of code for working with the "iTunes Music Library.xml" file which will allow me to make a lot of shortcuts by operating directly on an internal representation of the music library instead of having to do everything via iTunes (using AppleScript and Apple Events).
-
Greg Hurrell
More work on parsing the XML file and leveraging it. To speed up development, I've split the code up into two parts: "the app", and "the Synergy Advance framework". This is in addition to the base framework that I've already put a lot of work into and which is used in a couple of my other apps. The idea is that by having the code in the framework I can reuse it if the project ends up heading in a direction that I hadn't originally anticipated.
I was originally planning an App/PrefPane combination (just like Synergy), but I think that things will be simpler if Synergy Advance is just a straight App.
In any case, did a bit of work on the Synergy Advance framework (called Synergy Core) in the area of error handling, exception handling, and Apple Events.
Did a bit more work on WinSwitch today too. I know I just released a new version, but based on feedback I've received I've already added a couple more features.
And over the past couple of days I've been in discussions with some other developers who manipulate album art in their apps; looks like we could arrive at a standard for storing album art (for people who don't like to embed it in their audio files) and which all these apps could access.
-
anonymous
Quote: And over the past couple of days I've been in discussions with some other developers who manipulate album art in their apps; looks like we could arrive at a standard for storing album art (for people who don't like to embed it in their audio files) and which all these apps could access.
This is great, I'm glad you're open to using a standard album art location. As more and more apps make use of album art it would be really nice not to have hundreds of megabytes duplicated in different places on the hard drive. And it makes it more likely that other apps will take advantage of artwork not stored in iTunes.
-
Greg Hurrell
Worked on extracting useful information from the iTunes library file and storing it in memory in various formats for quick access. Given that the library in question could be huge, all of this is done in a separate thread, so I've spent a bit of time ensure that this info can be accessed in a thread-safe manner even in the middle of a refresh. The other thing I've done is use an additional, periodically released NSAutoreleasePool inside the tight loops so that the memory footprint won't swell too much if the user has thousands upon thousands of tracks.
-
Greg Hurrell
I've been replicating some of the iTunes interface within Synergy Advance. Ok, I tell a lie: I'm actually doing the groundwork for that replication.
Apparently Donald Knuth said that "premature optimization is the root of all evil" (although I don't know where he actually said this), but even so, I've been engaging in some sensible design practices to makes sure it's fast. In fact, it's more just commonsense design rather than optimization. iTunes is fast even with a 10,000-song library, so I want Synergy Advance to be fast too.
So I guess this just means avoid brain-dead attempts at scanning the entire library; if the user is only looking at one album, you should be able to work only within that subset.
-
Krypton
Quote: Quote: Apart from that, today I've been working on a bunch of code for working with the "iTunes Music Library.xml"
Yay!!!!!
-
Greg Hurrell
Well I've finished the underlying stuff and have started the higher-level GUI elements for allowing the user to browse the entire library quickly.
But, on a bit of a tangent, I've just today started work on a new product. It's something I've wanted to do for a while, and it's something that I can start off nice and small, so it hopefully won't take too long. Why I am doing this?
Well, it's because I want to learn how to use Cocoa Bindings, which are new in 10.3. I've looked at the docs several times since 10.3 came out, read the tutorials, and just haven't been able to "get it". The idea is that you can throw out a huge amount of glue code and replace it with work in Interface Builder. But the documentation was incredibly opaque to me and I couldn't see how I would be more productive by throwing out all that code and replacing with a lot of fiddly clicking and facing a bewildering array of options in Interface Builder.
Nevertheless, I know that this Cocoa Bindings stuff is a "good thing", so I figure the best way to learn it is to start off with a clean slate (a new project) and write it using Cocoa Bindings from the very start rather than trying to graft it onto an existing project.
After one day's work on it (most of it spent scratching my head trying to make sense of the documentation) I'm quite happy with what I've been able to achieve using NSUserDefaultsController. Basically, having written very little code, and doing most of the work in Interface Builder, I know have a fully functioning preferences window with quite a few interconnections and live updates going on, default (initial values) are working, and everything is getting nicely flushed to disk. All of this in addition to the usual stuff you can do in Interface Builder in the way of hooking up delegates and connecting windows to menu items etc.
The project (which for now will remain a secret!) will be making use of NSTableViews and NSSearchFields, so it should allow me to come to grips with quite a few aspects of Cocoa Bindings that I can then leverage in Synergy Advance and GetSmart Pro. And not only that, the project I am working on is designed to boost productivity, so the sooner I finish it, the sooner I can start reaping the benefits.
This is also my first chance to roll the new, improved hot key code that I've been working on in the WOBase framework into an app, so that will be a good test for it too.
-
anonymous
sounds interesting. i like these progress reports btw, so keep them up. it's interesting to hear what you're working on.
-
Greg Hurrell
The communication between Synergy Advance and iTunes is performing really well under testing. Even if iTunes stalls and blocks Apple Event requests, the Synergy Advance UI remains responsive. I am very happy with it; not only from a performance perspective, but in terms of robustness and flexibility, it handles CD tracks, shared playlist tracks, radio tuner tracks, and I suspect even iPod tracks (I don't have an iPod to test it on, but the support is in there). I'm spending a lot of time making sure that I can process just about anything that iTunes can throw back, so there should never be times when Synergy Advance doesn't know what to do with the reply from iTunes.
I've been able to design in support for all these sources from the beginning, rather than layering them on one by one at a later time, so it means that the whole thing can be more elegant and work more efficiently. I can basically get more information from iTunes, and update with increased frequency, without causing any "stuttering" in the visualizer like some users with slow machines have reported under Synergy.
-
Greg Hurrell
More work on Synergy Advance/iTunes comms, and more work on my "mystery app" (hehe).
I've got to say, I am still far from comfortable with Cocoa Bindings, but I am gradually getting it to do what I want: so far I have two windows with NSTableViews in them, dynamically updating item counts, working add/remove buttons, and they're automatically updating as new data arrives.
So far just sticking with basic text-only content, but the next items to cross on the learning curve will be: implementing drag-and-drop to re-order within each NSTableView, implementing drag-and-drop between the two windows, supporting the delete key in the NSTableViews, and hooking up the search fields that I've already got in each window.
The cursor keys already work in the NSTableViews, but I want to add type-ahead incremental search. Looks like all of this stuff means I'm going to have to subclass NSTableView.
Once I've got those basics working I'll add support for non-text content.
This things are minor UI details from the end-user perspective, but I think they make all the difference when it comes to the perceived quality of the user experience. UI polish! The app should behave intuitively. The user shouldn't have to consult the menu. They should be able to look at something and think, "I wonder if I can drag that to rearrange it", or, "I wonder if I can navigate everything from the keyboard" etc and it should all "just work".
All of this will most likely take a day or two (or more) while I get to grips with Cocoa Bindings, but hopefully it will pay off in the long run because I'll be able to apply the techniques in other apps.
-
Greg Hurrell
Drag-and-drop to re-order now working (still have to handle dragging between windows). Search fields hooked up. Status text now says stuff like "Showing 14 of 25 items, 1 selected".
I've just learned how to simulate keyboard events in other applications, which I need to be able to insert things into other apps (as though the user had pressed Command-V). Good.
-
Greg Hurrell
I've worked out how to do hardware-independent keycode mapping.
The problem with the keycodes generated by your keyboard is that they are dependent on the hardware you're using and/or the keymap that's active. What this means is there's no way I could provide a set of standard hot keys that would work "out of the box" on all systems for Synergy. Amazingly, the letter "A" (for example) doesn't have the same keycode on all systems.
To get around this problem, Synergy ships with very few pre-set hotkeys (just a few function keys for play/pause, previous and next). The idea is that the user then configures the hot keys for other functions to taste. Because the keys get configured on the machine, the hardware/keymap dependency doesn't matter, because you capture the hotkeys on the same machine that you use the program.
Well, I know that it should be possible to get around this hardware dependency because Apple can and does do it. For example, the default keys used to control Expos
-
Krypton
How close are you (roughly) to a release now Wincent? Not only would I love to have all these features you've been describing, but I'd quite happily send the upgrade fee etc
-
Greg Hurrell
I can only say "when it's done" because I am don't want to make any predictions and then have people disappointed... working particularly hard on things this month because I finished the course I was doing and have more time available now. Won't be starting another course until October.
-
zerock
looking forward to this app , cheers.
-
Greg Hurrell
Arghh. I've been pulling my hair out of the last few days trying to replicate the key-binding interface in Xcode, and correcting a couple of inconsistencies and UI problems in the Apple implementation. You know the drill: spending days trying to reverse engineer, trouble-shoot and account for mysterious, undocumented behaviour etc.
I've spent a lot of time trying to troubleshoot stuff that should be incredibly straight-forward, but isn't... but at least now am making some progress. I'm now into the meat of it, working on implementing the functionality I want rather than trying to work out what Apple is doing behind the scenes.
Another little issue to solve is how to use Cocoa bindings with my custom classes. They are subclasses of stuff for which you can configure the bindings in IB, but in the Bindings inspector nothing shows up. I would like to think that I could somehow set it up so that the Bindings options are just inherited, as they should be! I haven't made any changes in the subclasses which would break Bindings...
-
Greg Hurrell
One by one I go crossing items of my "to do" list with respect to my new hot key capture classes. I'm a perfectionist, so I'm trying to replicate the Apple Xcode behaviour where it's good, and eliminate or improve bad behaviours.
Stuff I've been able to cross off the list today: text appearance in the custom field editor matches that used by the default field editor associated with NSTextFields; drag and drop refused (as recipient); drag and drop refused (as source); ghosted image suppressed if user attempts to initiate drag; contextual menu suppressed; inappropriate menu items invalidated (cut, copy, print etc); don't end editing on tab, enter, return, shift-tab etc.
Next problem to solve is to get the focus ring showing again. For some reason it isn't...
-
Greg Hurrell
Quote: Next problem to solve is to get the focus ring showing again. For some reason it isn't...
I just want to complain a bit about one of the less publicized Cocoa "Design Patterns". The focus ring problem is fixed, but at the cost of hours of headache-inducing problem solving, trying to work out the undocumented, unexplained, mystery behaviour that Apple is engaging in behind the scenes.
One of my favourite things about Object-Oriented programming is inheritance. You want to customize the behaviour of a class, so you subclass it. Inheritance means that you don't have to rewrite the entire class; you only need to surpress the behaviours you don't want, add the behaviour you do want, or modify the existing behaviours according to taste. It's a wonderful time saver and very efficient. In my opinion it could well be the single best thing about OO programming (that, and encapsulation).
Thanks to Apple's trickiness, however, I have now spent several days extending a group of classes that interrelate in complex, undocumented and mysterious ways. In fact, sometimes we're not only talking about an absence of documentation, but of actual behaviour that flies in the face of what the docs promise.
I don't want to waste any more time on this than I already have, so I'll be brief. In short, I've been working on a group of three subclasses: an NSTextField subclass, an NSTextFieldCell subclass, and an NSTextView subclass.
The most obvious thing to do when you make this kind of subclass is to start with an empty subclass. It literally does nothing different than the parent class; all the behaviours are identical (inherited), only the name is different.
The idea is that you add or subtract functionality line by line, testing along the way.
But what happens when even the empty subclasses don't work?
Let's just give one example. Names simplified for the purposes of illustration. You drop your NSTextFieldSubclass into your nib and find it won't work as expected because it's using the NSTextFieldCell instead of your NSTextFieldCell subclass. You can "trick" IB into doing what you want by telling it that your NSTextFieldSubclass is really a custom view.
That's the easy part, although you can waste a lot of time on it if you don't know the trick.
Next up you try to supply your custom NSTextViewSubclass as a custom field editor instead of the default one provided by Cocoa. You do this in the setUpFieldEditorAttributes method of your NSTextFieldCellSubclass because you want your group of classes to be a neatly contained cluster and you don't want to break the OO paradigm and start messing with your NSWindow delegate. The Cocoa docs explicitly say you can do this. So you do it.
Even though your NSTextViewSubclass is identical to the NSTextView subclass in all but name, you find that once you start using it things are horribly broken. You can't tab between text fields. There are no focus rings. etc. This is the case even if you painstakingly analyse the attributes of the default field editor and replicate them in your subclass.
At this point you break out the debugger, start single-stepping through the code, and peppering your source with log statements to help you figure out what's going on and why your code doesn't work despite the Apple sample code which claims it should.
You begin to suspect that somewhere in the parent classes, Cocoa is doing something nasty, something secret, and is somehow checking for the existence of the non-subclasses NSTextView object and basing its behaviour on that.
Turns out that the drawWithFrame:inView: method is the first culprit. The super class is doing some kind of test. If it gets an object other than the one it expects, it doesn't draw a focus ring. Now, as I don't have access to the Cocoa source code, I can't say whether it's checking for an object of the NSTextView class, or if it's actually expecting the shared instance of the default field editor.
So this means that instead of leveraging the behaviour of the parent class, you have to rewrite it, and you have to rewrite it without access to the source code. It is a horrible, wasteful effort, and if Apple decides to change the behaviour in the future you will have to change your code to match rather than automatically inheriting the changes.
I won't go into further detail here, but this is a "Design Pattern" I've seen time and time again in Cocoa. Cocoa works great if you don't ever want to extend it. The trouble is, if you want your apps to be like Apple's apps, you have no choice but to extend, because they are constantly introducing non-standard widgets that use private APIs.
It's just a shame that "extend" here actually means "rewrite", and the end result somehow always ends up feeling like a fragile kludge. Sometimes I just love Cocoa; other times I just hate it. Now is one of the latter times. I've spent about four solid days so far battling against this beast. I've so far spent less than 10% of my time doing what I would call productive work (ie. implementing custom functionality that provides me with an end-user UI widget which meets the special requirements I have in mind) and the other more than 90% of the time fighting tooth and nail against Cocoa, reverse engineering things that I shouldn't have to reverse engineer, and constructing fragile, verbose replications of functionality I should be able to easily inherit.
It's times like this that I wish a little bit more of Mac OS X was open source. At least then I could look inside and see what hideous shenanigans they're getting up to behind the scenes.
Urggh... Anyway, time to get back to the hell hole...
-
Greg Hurrell
Ok, made some real progress last night/today, and so I'm a little more calm... hehe... I managed to solve most of the problems I was having by zeroing right in on the methods for which the Apple documentation is incomplete or downright misleading (the culprits:
-
Greg Hurrell
Quote: As a "reward", I am going to distract myself and spend a bit of time learning about Subversion.
And this is the result.
-
Krypton
Could we have a screenshot of your latest work (like you used to do with Synergy)? Provided that there's something to take a picture of of course
-
Greg Hurrell
Created
,
edited
Quote: Could we have a screenshot of your latest work (like you used to do with Synergy)? Provided that there's something to take a picture of of course
I am sure this isn't what you were hoping for, but here it goes anyway:
[screenshot temporarily deleted due to server reorganization]
This is a sneaky glimpse into the glamorous process of software development...
I've now polished this hot key code so much that I've got it working better than even Apple's own. I've been using the Key Binding preferences in Xcode as my bench mark, and now I can correctly detect keys that even Xcode fails to see. I've got a Spanish keyboard too, so those strange looking characters you see correspond to keys on that (like
-
anonymous
It sounds like you have enough on your plate already, but it's occurred to me that the knowledge you've gained developing Synergy, Synergy Advance, etc. could make for some really valuable articles. It sounds like you have a lot of knowledge about areas where Cocoa falls (far) short of what it promises. Not only do you know how it fails, but you've figured out workarounds. If you ever have spare time, or want a break after SA 1.0 is out the door, I think a couple articles detailing these things that Apple glosses over, or is misleading about in its own documentation, would be really valuable for the Mac developer community.
-
anonymous
Maybe you could even freelance for MacTech or O'Reilly or something...
-
zerock
so whats next?
-
Greg Hurrell
Quote: so whats next?
I've just gotten back to Spain after being in Australia for a couple of weeks. While over there, I continued working on my hot key classes, and also did some more work on security stuff; eg. binary signing, I also came up with a modified base-32 notation system which will be used for registration and should make it much easier for customers to enter their serial numbers.
I also wrote lots of unit tests, and am pleased to report that they really helped in both catching bugs and also confirming when the implementation was where it should be.
There are a lot of people who base their entire coding practice around unit testing. They write the tests before they begin the rest of the code. When the tests pass, you know you're done.
I don't work that way because it doesn't suit the way I think. I start with a general idea of what the code should do, and I have a few specific sub-goals. I can generally write the unit tests for those sub-goals straight away (basically, as soon as I've decided on the class and method names that I'll use in solving the problem). But along the way, I think of other sub-goals that need to be met, or I become aware of subsidiary problems that need to be solved as stepping stones towards the big problem, and so I'll write more unit tests as I go along.
Basically, I'm not using the unit tests as an integral part of the development process (in the sense of using them to drive code production); rather I am largely using them for quality control. It's great to know that if you introduce a bug somewhere down the track you're unit tests will pick it up, and that means you write better software with fewer bugs, and the users wind up having a better experience.
-
Greg Hurrell
Today I finally put the finishing touches on the modified base-32 system and I now have it handling all the edge cases. I've thrown a lot of unit tests at it, including getting it to round trip massive hunks of pseudo-random data from NSData to a string representations and back again, and it passes with flying colors. It's now officially "done", and thanks to all the unit tests I am quite confident that it's likely to be bug free.
-
Greg Hurrell
Today's accomplishments so far: an NSObject category, and made sure that the "+" and "-" buttons in my custom field editor (used for capturing hot keys) aren't displayed when the window is not the key window.
-
Greg Hurrell
Quote: 6,120 framework lines, 747 Synergy Advance-specific lines.
It's been a while since I posted a source code line count. Quite a bit of progress has been made since then. Just ran another count and now I've produced 12,506 framework lines and another 3,390 lines in the Synergy Advance-specific part of the codebase.
My next, super-secret, mystery app (ha), which uses the framework is 659 lines so far. Needless to say, most of the work occurs in the framework at the moment. Thanks to Cocoa Bindings, the amount of code in the actual app itself is vastly reduced.
Now that Xcode 1.5 is out, I noticed that they've ironed out a couple of glitches in their keybindings UI. In previous versions you could assign multiple key combinations per item. Now they limit you to one. I've designed my own hot key stuff to match the Xcode UI, and originally intended to allow you to set multiple key combinations, just like Xcode. Now that the Xcode behaviour has changed, I am thinking about whether or not I should match it. I'm thinking that perhaps it would be best to keep the added functionality in there rather than strip it out.
One question remaining to be solved, however, is what to do when the user defines so many combinations that the field editor needs to scroll to provide access/show them all. Yesterday I implemented the code that prevents the "+" and "-" buttons from getting overwritten by text (or more accurately "underwritten"; in the older versions of Xcode you could enter so many combinations that they spread across and eventually started to slide "under" the buttons). But what's the best way to implement scrolling within the field editor? You can't scroll with the cursor keys (after all, the field editor needs to be able to capture the cursor keys if the user wants to set them as hot keys). I am thinking it'll have to be a mouse-only affair. And I am thinking also that I am going to suppress display of the cursor and do it all with highlight rectangles (basically matching the Xcode behaviour). That will be another nice mystery to solve... how, or where, does Cocoa (and NSTextView) display that cursor? One thing I am sure of is that it's not being drawn in the view's -drawRect: method, because the cursor flashes on and off and the -drawRect: method doesn't get called. I suspect it's getting drawing into a tiny subview that gets inserted on top of the NSTextView...
-
Greg Hurrell
Made lots of progress on finishing off and polishing my hot key capture user interface.
Deleting single or multiple combinations now works, adding, replacing single or multiple combinations, clicking to select, dragging to select forwards or backwards, the add and remove buttons work etc.
All in all it's come along very nicely. Hopefully will be able to finish it today. Things still to do include handling the case where the user switches windows or text fields and a blank "place holder" is in place (need to clean up the place holder)...
-
Greg Hurrell
Spent a few hours today trying to get a certain behaviour and in the end it looks like I am going to have to give up. There are simply too many problems with the approach.
I wanted to make it so that a user could end a hot key capture session by clicking anywhere outside of the active text field. The standard Cocoa behaviour for all such widgets is that they only lose their active status if you click on something which can take over the active status (or become "first responder", to use the Cocoa parlance).
With the hot key capture text field, whenever you enter a new hot key combination, it's highlighed (try it in Xcode and you'll see what I mean). If you type another key it immediately replaces the previous combination.
I wanted to allow the user to click elsewhere in the window to end editing and thus prevent accidental erasure. Once again, you can see this in Xcode: the only way to end editing is to click on another object in the UI which can take over first responder. Merely clicking elsewhere (on something that can't assume first responder) in the window won't do it.
This is a trickier task than it sounds. By definition, the active text field gets "mouse down" events only if they occur inside it. You need to work out a way to be notified of such events outside the text field.
My first attempt was to set up a tracking rectangle which enabled me to detect whenever the mouse left the field. On leaving, I would use NSApplication's nextEventMatchingMask:untilDate:inMode:dequeue: method to watch for mouse down events.
This worked in the sense that I could pick up the events, but it broke some things too. For example, the cursor in the active editor stopped flashing, and I didn't get any key down events (which defeats the purpose of the text field). Also, it would only work if the mouse left the confines of the text field. If it started outside of them (as could be the case if the user used the tab key to get into the text field) then no tracking could be performed.
I was able to fix a couple of these problems by using the NSDefaultRunLoopMode instead of the NSEventTrackingRunLoopMode (this meant that timers could fire and my cursor would continue flashing), and by listening for and appropriately forwarding the other events that I was interested in (such as key down events) so that I could continue to handle them even while tracking.
To cure the "mouse starting outside of the text field" problem, I could actually set up a tiny fake tracking rectangle around the mouse pointer (wherever it might be) and start the tracking as soon as the user move the mouse. It seems that there was no reason why the tracking rectangle had to be inside the text field view itself, so I could put it wherever the mouse was.
Even so, there was other breakage. Cursor rectangles didn't work any more because I didn't know where to forward NSCursorUpdate events, and neither did I want to rewrite the functionality already present in Cocoa's cursor rectangles system. Nor do I want to lose the functionality. For one thing I want cursor rectangles to work in the other parts of the window, but I also want them to work inside my text field, where I've got it set up to show an I-Beam cursor over the textual part and an arrow cursor over the "+" and "-" buttons.
Also, the system didn't handle things all that well when my app lost frontmost status (it would still be tracking). On bringing it to the front again the windows wouldn't actually come to the front (because they were still busy tracking). So all this meant that I had to add code for watching for application switched events, and while I was at it, code for handling when the mouse cursor left the active window and/or the user made another window in the app the "key" window.
By the time I got this far I was wondering if it was all worth it to implement this behaviour that was different from the Cocoa norm. I would do it if it could be done elegantly and without breaking other expected behaviour, but it just didn't seem to be a worthwhile trade-off.
Another alternative which gets around all of the problems above is to create a transparent window that perfectly matches the main window in size and watches for clicks. It lets clicks go through to the text field, of course. Any other click it catches and uses it as a signal to stop editing.
Once again, the "not elegant" alarm bells start ringing when I have to do stuff like watching for when the parent window is moved or resized. At present I haven't attempted this solution, although I believe it should be possible. As I said, I've begun to wonder if all this work and machinery is worth it to meet the goal I've got in mind, especially since I am not entirely sure that the goal is a good idea in the first place.
Off course, all this while I am wondering if there's some easy-to-use method somewhere in Cocoa that I've overlooked. You know, an NSView method called, "-setResignFirstResponderOnClickOutsideOfView:" or something like that... If anybody knows of such a method, I almost don't want you to tell me about it...
In any case, I don't feel too bad about wasting the morning, because I've learnt some things about event tracking and run loop emulation that I didn't know before.
-
Greg Hurrell
Latest counts of lines of source code:
WOBase 14,007 + 273 SynergyAdvance 3390 (still) ??? 717
Progressing very quickly indeed now, apart from a few little setbacks that wasted some odd hours here and there (annoying stuff like a glitch with my mailserver...)
-
Greg Hurrell
WOBase now up to 15,266 lines...
-
Greg Hurrell
Very pleased to report that I've finished coding a set of four classes that I have been working on for two days solidly now. Together they weigh in at around 1,500 lines of code. What a relief to get it done: it made my brain hurt, so to speak!
It's a set of classes that provide a nice GUI widget for entering license codes. Yes, exciting stuff. Easy enough to write basic widgets, but to override the Cocoa behaviour to provide a really elegant and polished user experience? It's a bit hard to describe in words, so you'll have to see it when it comes out. But when you do see it, you'll understand what I mean.
It required me to use a custom field editor again. Much easier the second time round that you try it! Admittedly this one was not as complicated as the one I had to write for my hot key capture classes.
So in the 24 hours since I last posted the WOBase code count has actually gone down to 15,230... It just goes to show that hours of work doesn't always translate to lines of code. In this case, however, along with the line count going down, the number of things on my "to do" list also went down!...
-
Greg Hurrell
I've been very busy the last few days, putting in at least 12 hours a day on this stuff. There's not a lot to comment on right now. I've got a few things that are coming together, and they'll all be ready about the same time. We're talking about a new product release, updates to Synergy and WinHex, and a total revamp of the website. Hoping that all this will be out in public by the end of September. It's going to require a lot of work between now and then, but I'll certainly be trying!
So I'm probably not going to post here for the next few weeks... But then there'll be some announcements!
-
zerock
nice!! , looking forward to updates, and for Synergy Advance sometime this fall
-
webmacster87
Hmmm...no updates in almost one month? Is anything new?
Have you ever considered making a blog for this?
-
Greg Hurrell
Quote: Hmmm...no updates in almost one month? Is anything new?
Have you ever considered making a blog for this?
As I just mentioned in another thread, I'm thinking of releasing some of the source code modules for Synergy Advance in the form of tutorials. But that is still some way off, after the release of 1.0.
In any case, lately I've been working on some nice notification bezels. If you want to get a sneak preview of these, you'll see them in the next version of WinSwitch, which I should be releasing with the next week or two.
-
zerock
Quote: Quote: Hmmm...no updates in almost one month? Is anything new?
Have you ever considered making a blog for this?
As I just mentioned in another thread, I'm thinking of releasing some of the source code modules for Synergy Advance in the form of tutorials. But that is still some way off, after the release of 1.0.
In any case, lately I've been working on some nice notification bezels. If you want to get a sneak preview of these, you'll see them in the next version of WinSwitch, which I should be releasing with the next week or two.
have you considered Growl in a way of notifications or is it still too basic? anyways if you dont know about them yet, you can find the growl project at www.growl.info . anyways maybe you will want to include your ownz bezel in synergy advance( i think its the best idea), but you could leave it free(in the future), to use maybe a plugin like a growl module perhaps..
-
Greg Hurrell
It's been a long time between progress reports because I've only had limited access to the Internet. (I had to wait 40 days for an ADSL line to be installed, courtesy of Spanish ISP, ya.com; their customer service is absolutely terrible, and no amount of phone calls or formal letters of complaint could make them lift a finger to get the line installed within what they claim is their typical time span of 2 to 4 weeks. Now I've got the line at least; the connection is exceptionally good, just the opposite of their exceptionally bad customer service!)
Nevertheless, during that time I've been busy at work on a lot of things. It's been very frustrating because without net access I can't access the latest documentation, mailing lists, or do Google searches... but now things are moving very quickly again.
There's been an interesting domino effect, starting with Synergy Advance. Let me explain...
A while ago I decided to have a crack at mastering Cocoa Bindings (new in Panther). I had an idea for a simple project which I could use as a test bed. So I learnt a lot about Cocoa Bindings doing that project, and it's nearly ready for release.
There came a point where I wanted to do something tricky which would come in handy for both that project and also for Synergy Advance, so I figured I would roll the change into WinSwitch. It was like starting with a clean slate, because WinSwitch didn't use any bindings. Thanks to those changes I've got a huge update (version 3.0) almost ready to release.
One of the new features in WinSwitch 3.0 is hot key support. I'd already done a lot of work on hot keys for Synergy Advance, but that was based on intercepting the hot key events at the level of NSApplication.
This wouldn't work in WinSwitch, because WinSwitch is not an application. So I figured out how to do it more elegantly by using a Carbon event handler. I figured I may as well split all this hot key stuff into a separate framework, because I didn't want to include WOBase (the framework into which I was previously putting common code for Synergy Advance, GetSmart Pro etc...) in WinSwitch.
So WOHotKey was born, and did a lot of work polishing it and making it nice and reusable.
A lot of the stuff I was working on required access to docs and online information. Seeing as I couldn't spent too much time in the Internet Cafe every day, I went off on a tangent and made a unit testing framework, WOTest. I'll be releasing this shortly. I wrote it because, as is often the case, none of the offerings currently available behave exactly as I want, and I would rather write my own custom solution than try to beat someone else's solution into shape to fit my preferences. Prior to this I had done all my unit testing with a fairly elaborate set of macros. They worked very well, but there was no flexibility and no integration with Xcode. The new unit testing framework addresses both of those shortcomings, and I'll even be able to ship the tests with my products, for those who are interested in running them, without increasing the memory demands for people who don't want to run the tests. This could come in handy if a user with a strange configuration reports a bug that I can't reproduce here; they can run the unit tests and see exactly what is failing on their machine.
The next domino fell when I realised that getting WOHotKey to work with Cocoa Bindings was a bit beyond me. Time for more learning... So I've started a new project, once again with the idea of getting an ever better grasp of the bindings technology. I've also used it as an excuse to use a plug-in based architecture for the first time. This project is very close to release as well... All this stuff relates directly to Synergy Advance.
The latest step I've done is split out my bezel code into a new framework, WOBezel, which will also be used by the new WinSwitch, and the other new app I'm working on, and Synergy Advance etc... Today I've been wrapping all this up in an Interface Builder palette (another first for me) so that I can set up these bezels using the GUI rather than programmatically.
So basically I have all these dominos falling; one thing leads to another, and the effects flow back up the chain too. I've got two new products extremely close to release, three new frameworks (WOHotKey, WOTest and WOBezel) of which one will be released to the public (WOTest), a huge WinSwitch update just around the corner, and all of this I will be able to use in Synergy Advance.
Although the coding side of things is almost done, there's still all the administrative side (setting up and updating the websites, writing up the docs, FAQs etc). There's also the piracy problem. These two new apps will be 5
-
Greg Hurrell
Lots of work on the Synergy Advance preferences UI. Threw out old comms engine and started a new, highly-efficient one. New Floater classes (much more MVC compliant); the Floater itself is radically different to the one you see in Synergy. Added WOHost class to WOBase. Finished refactoring to distribute code between WOBase, WOBezel and WOHotKey. Swore repeatedly at my machine which is so slow that when I have multiple projects open in Xcode (for example the app I'm working on, its frameworks and its preferencePane bundles), it beachballs so often and becomes so slow that I feel like I am typing in an SSH session over a 300 baud modem to a server in Alaska.
-
Greg Hurrell
Total rewrite of syneryd background daemon; have shaved off every byte of memory use and every CPU cycle possible, so it now runs in about 100k of physical RAM and uses effectively zero (and I mean zero) CPU: Code:sol:~/trabajo/build wincent$ ./synergyd & [1] 22056 sol:~/trabajo/build wincent$ leaks 22056 Process 22056: 1050 nodes malloced for 83 KB Process 22056: 0 leaks for 0 total leaked bytes. Refactoring and cleanup of WOPreferenceWindow class; now named WOPreferencesWindowController to more accurately reflect its purpose. Set up build chain with app, frameworks, custom preference panes etc to produce first running build of Synergy Advance! (previously I've only run segments of code in test apps)
-
Krypton
That's good to hear! (the running build that is)
-
Greg Hurrell
I've been very busy with the site redesign and getting Synergy 1.5b out the door, but now finally have some time to make some more progress on Synergy Advance.
I recently decided on a release date for Synergy Advance. It will come out very close to the time that Apple releases Mac OS X Tiger. Although that date still isn't publicly known, I'll move heaven and earth if necessary to get Synergy Advance out at the same time. So that means first quarter, 2005, most likely.
The reason is that I want to take advantage of some new features in Tiger. I haven't yet made a commitment to whether the app will support Panther or not (the decision was made long ago not to support Jaguar). Clearly I would like to support Panther, if I can. It's certainly the plan, but it all depends on whether any unforeseen difficulties crop up. The idea is that the app would run on either OS, but some of the functionality would only become active on the newer release. I haven't even installed Tiger yet, because I haven't wanted to install anything pre-release on my production machine. But I will be installing it soon and Tiger-centric development will start in earnest.
You know how I was gloating about the first running build of Synergy Advance in my last post. I soon got into some really ugly refactoring work of a very important class which is over a 1,000 lines of code which meant that I couldn't do any working builds until the refactoring was done. Then like I said, the site redesign and Synergy 1.5b came along. It was only last night that I finally finished the refactoring and got the builds working again.
Now I have two little blocking issues that I have to address which are holding me up. Once I have these issues resolved I'll be able to get WinSwitch 3.0 out, as well as another brand new app I have under development soon after that. All of this code is used by Synergy Advance too.
The two issues are:
(1) A set of four small UI bugs in my hot key framework that I want to iron out. They are not show stoppers, but I don't want to deploy it until it's perfect. Hoping to get these squished today.
(2) Getting the hot key frameworks to play nicely with Cocoa Bindings, specifically with respect to writing/reading user preferences to/from disk. Yes, that's right, my love affair with Cocoa Bindings (yes, that is irony) continues. Once again, hoping to get this "burninated" today.
-
Greg Hurrell
Well I did indeed get all those things done that I wanted to get done. A miracle. I'm currently banging my head against the wall trying to get an Interface Builder palette together for my custom classes. The lack of documentation is a bit frustrating, and the mailing list is full of posts saying "it's easy, just do this", but I can't get it to work.
At least there is a fair bit of sample code in /Developer/Examples/, but haven't had any luck yet, even with a simple NSTextField subclass. Hopefully will get it fixed soon, because this has me pulling my hair out.
Once I've got this done the next hurdle is to make a custom palette for my NSWindow subclass. From what I've seen on the mailing list, this is distinctly tricky and requires some kind of unspecified hack, and not an example in sight. Let's hope I lose only one day to this rubbish so that I can get back to the real work.
-
Greg Hurrell
Ok, so I got the Interface Palette working nicely for my custom hot key framework, and it all plays nice with Cocoa Bindings. (A miracle.) I still have to make a palette for my bezel framework, and it could be a little bit tricky from what I've read about putting NSWindow subclasses on IB palettes.
I got a bit distracted these past two days and have come up with a crash catcher/crash reporter framework, much like you see in Omni products (or Mozilla and Camino pre-releases, from memory).
It all started when I was reading about how to print stack traces from within a running app. Never one to do anything by halves, I decided to wrap this up into a framework called WODebug that I can ship with all my applications. The framework provides stack trace functionality and offers an optional Crash Catcher that will step in and catch uncaught exceptions, signals and crashes, and launch an embedded Crash Reporter app to send the details of the crash to me via email.
This is a Panther-and-up framework, only, so you won't see it in Synergy; but you will soon see it in WinSwitch (although the truth is WinSwitch is so stable you'll probably never actually *see* the crash reporter).
I am very pleased with the framework at this point, although I still have a bit more work to do (like rolling in some logging macros and other basic stuff that I've currently got elsewhere). It's not like other crash catchers that I've seen which have to do all sorts of inelegant kludges to obtain crash reports from ~/Library/Logs/CrashReporter/ and then parse them, or worse still, to forcefully kill the Apple-provided crash window that pops up.
It can generate stack traces on demand, and I've got two alternative methods for doing this in place, in case Apple ever changes their APIs. When it catches exceptions, signals and crashes, it really catches them, which means you don't see the Apple crash window popping up alongside the Wincent Crash Reporter. And I'm happy with the UI and I think you will be too. It's very clear about information gets included in the report and it gives you opportunties to review before sending, or to easily turn off the Crash Reporter dialogs if you don't want to be bothered by them, or to relaunch the app immediately.
It doesn't depend on external executables or having the Xcode Tools installed. Support can be rolled into existing apps with a single line of code. The memory footprint of the framework itself is absolutely tiny, so it won't have any impact at all on performance. Most of the material in the framework sits on the disk and never even touches memory, unless there's a crash, by which time it's too late to be worrying about memory anyway. It looks like it's going to add about 220KB to the download size of any product that uses it, but I think the bug-squishing benefits make it a very worthwhile trade-off.
-
Greg Hurrell
Latest source code counts (lines of code):
WODebug: 1,183 WOBase: 13,279 WOHotKey: 4,352 WOBezel: 1,783 WOTest: 3,740 Synergy Advance: 34,183
Total: 57,337
-
Greg Hurrell
I've decided to make the jump to C99 and see what happens, even though GCC doesn't fully support it yet. I just got sick of writing sequences like this: Code:unsigned i; for (i = 0; i < max; i++) {
// do something
} Which would really be better written as: Code:for (unsigned i = 0; i < max; i++) {
// do something
} In these examples the variable "i" serves no purpose whatsoever apart from determining when the loop should stop running. It has always annoyed me that I had to declare it on a separate line.
The GCC Objective-C compiler already supports some of the new features in C99, even when running in C89 mode; things like single line comments starting with "//" and freedom from having to put all variable declarations at the top of function.
What I didn't realise was that GCC's incomplete support for the full feature set -- the thing which was holding me back from trying out C99 sooner -- is actually just about the best support you can get in any compiler (see this Wikipedia entry and this newsgroup summary for more). Given that I always write in pure C or Objective-C (never C++ or Objective-C++), the various incompatibilities between C++ and C99 don't concern me.
I'm pleased to report that on updating my build settings (under "C Language Dialect" in Xcode) that everything pretty much compiles exactly as before with only a few, easily-fixed warnings (that were related to system headers; all I had to do was add a few #import statements to silence the warnings). Will continue to test this over the next few days of coding, but right now it's looking very good.
-
Eerk
Quote: Like just about everything else in Synergy Advance and GetSmart Pro I'll make it possible for the user to specify a preference for which transition style they prefer.
Yes! Optional features and preferences, lots of preferences! You just don't ever know what the end user thinks is his/her prefered way of looking at things and working with parts of the application.
Greetz, Eerk.
-
Greg Hurrell
Instead of keeping separate progress logs for each topic I think I'll just keep one single progress log for all of them. I am putting a lot of work into frameworks that get used by more than one app so it makes some sense to combine the logs. See the new combined log here:
https://wincent.dev/a/support/forums/showflat.php?Number=481
Reply
This topic is now closed.