Input Method (IMKit) setup trouble - macos

I'm trying to create a new input method using Input Method Kit. The documentation is very lacking, but I believe I'm setting the project up correctly and I place the input method into ~/Library/Input Methods after building it. However, I see strange behavior when looking at the list of input sources in Language & Text preferences.
The NumberInput sample seems to work fine for me, and there are no differences in my new input method that I can find, aside from the values for tsInputMethodIconFileKey, InputMethodConnectionName, InputMethodServerControllerClass, and CFBundleIdentifier in Info.plist. But I'm seeing these issues:
When I use my desired bundle identifier for the app, nothing shows up in the list. (This bundle ID doesn't exist anywhere else on my system.)
Changing the bundle identifier to be the same as the NumberInput sample makes it show up in the list, but when I select it, it sometimes duplicates entries in the list, and generally behaves weirdly.
As I make slight modifications to the bundle identifier, it seems to behave normally, but once I change it back to the original identifier (the desired one) it disappears from the list.
If I quit the process associated with my input method, selecting it in the menu again doesn't relaunch it.
Does anyone have any idea what's going on? Apple's documentation for IMKit is nearly nonexistant and it doesn't seem like many people have documented their own attempts at making input methods. Is there something I'm missing?
Thanks in advance!
P.S. Yes I've tried logging out and back in and even restarting my computer, nothing seems to significantly change the behavior I mentioned above.

This worked for me. Try this: make sure your bundle identifier contains "inputmethod" somewhere in the path. Example "com.blugs.inputmethod.IPAPalette". Yes AFAIK it's totally undocumented. Yes the documentation is awful. Hope this helps! Cheers.

The accepted answer here is very useful, adding .inputmethod. to your Bundle ID.
I'll add that I found a bit of documentation for this in TextInputSources.h, which contains a large number of comments and documentation not found in the Input Method Kit overview docs. Worth a read.
Carbon > Frameworks > HIToolbox > TextInputSources.h
In the Info.plist file, the value for the CFBundleIdentifier key must be a string that includes ".keyboardlayout."; typically this might be something like "com.companyname.keyboardlayout.MyKeyboardLayouts" (Before Leopard, it was required to be a string that began "com.apple.keyboardlayout", even for keyboard layouts not supplied by Apple).
and
If this key is not specified, an InputSourceID will be constructed by combining the BundleID with an InputModeID suffix formed by deleting any prefix that matches the BundleID or that ends in ".inputmethod."

Related

Object name becoming lowercase

I have some code which has worked in multiple installations for about a year. Today im doing a small change to a control and then another control seems to have developed an issue. When at runtime im getting a 91 error object variable or with block variable not set.
I therefore looked at the problem line which is: -
If Screen.ActiveForm.name = "frmFoutmelding" Then Exit Sub
so I noticed the name was lowercase. if i delete .name and rehit the "dot" then it shows me i can use .Name but as soon as i move from this line it drops back to .name
I've checked for instances of name and it appears everywhere in the code in different modules but i cant find if i have accidentally defined this lowercase name anywhere?
Googling doesn't seem to show much but i feel Im googling the wrong terms
chaps - thanks for your suggestions - this was the first instance of the lowercase name and searching as Jim suggested didn't reveal anything I'm afraid. What I did discover was that this was suddenly being run before any forms had actually been displayed and so the count was 0. I therefore, did an on error to check the form count and exit the sub if it =0 then if not to carry on with the line I thought I was having issues with.
It's likely that you did create a new variable or property called (lower case) name, or that some included reference did the same. It's possible to use reserved words as variable names in some cases, but it requires taking specific steps.
I would first search your code for instances of name As to see if you created a variable (this assumes you use Option Explicit, which is a must IMO). Then search for Property*name with * as a wildcard.
If those fail you could try unchecking references or components to see if any of them define name. If none of that finds anything, please post back here.
Jim Mack covers a lot of the potential issues. I think another is if you typed a lower case '.name' in association with Activeform at some point earlier in the same code module - the VB6 IDE checks in the current module and uses that to define what case to use. Look further up the same code module (sub or function).
Ultimately, check what changes you made by comparing the old source to the new in a file comparison tool like windiff - you do have backups, right?

Creating a new snip% with Racket

I am trying to create a new GUI element within DrRacket's text window, like picts or syntax objects. As far as I can tell, the most standard way of doing this is with a snip%.1
Unfortunately, the documentation for creating new snips, while comprehensive, is a bit impenetrable and leaves some questions to be answered.
For starters, what is the difference between a snip% and a snip-class%? Why do these need to be separated out into two classes, rather than simply being combined into one class? Is it because multiple snips will use one snip class?
Second off, what is snip-reader<%>? Not only why does it need to be a separate class, but why is the module providing it supposed to be installed?2 If it does need to be a new class, why can't it just be referred to directly. Why go through this whole process of constructing and then parsing a string of the form: "(lib ...)\n(lib ...)"?
I mean, there might now be any reason for this design, and it might just be a remnant of an old API. If so, has anyone thought of making a new more consistent API? Or if there is a reason for this design, can you please tell me what it is, as the docs don't seem to make that clear.
I mean, as of right now, I can copy/paste the sample given in the docs on creating a new snip. But I'm having a hard time understanding the design going on here, so I can use them properly.
1I know there are other ways to do it, but I also want to have interactive buttons and whatnot.
2I know it doesn't need to be installed as a library per se, but the documentation seems to strongly push you in that direction.
Okay, I think I finally found the answer. Broadly speaking:
The snip% class includes the methods for drawing the snip, telling the editor how much space to reserve for the picture, and handling events such as mouse clicks.
Next, the snip-class% class is used for encoding and decoding snips. This must be a separate class because when saved to a file, the editor needs to encode what type of snip it is, and for obvious reasons it can't just put the literal snip% class in there. The value it stores in the file is the snip-class%'s 'class name'. This can be anything, and as long as the editor has the classname associated to a snip-class%, it can be loaded. Additionally, if it is of the form "(lib ...)" or "(lib ...) (lib ...)" Racket will just automatically load it into the list for you.
Nothing 'needs' to be installed per se, its just the easiest way to go about it. Otherwise you manually need to tell the editor how to handle the snip before actually loading the file.

Writing Spotlight metadata to files on OS X (specifically kMDItemDisplayName)

I see that this has been answered previously by Ken T., but I have a case where the code appears to work, and the call to setxattr() returns 0, but the item I want to modify does not change.
Specifically, I'm trying to change the metadata attribute kMDItemDisplayName, and my call looks like this (modeled after the sample posted by Ken T):
[Note: the "name" param below is an NSString *]
rc = setxattr([pathString cStringUsingEncoding:NSUTF8StringEncoding],
"kMDItemDisplayName",
[name cStringUsingEncoding:NSUTF8StringEncoding],
[name lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
0,
0);
Doing an mdls on the file in question shows that the kMDItemDisplayName attribute is present, but I can't get it to change to anything other than the actual file name (which I assume is the default behavior).
Am I misunderstanding something about how setxattr() is supposed to work?
Any help very much appreciated.
Oh, BTW, why am I trying to do this? It appears (from examining how Bare Bones' Yojimbo does things) that Spotlight uses the kMDItemDisplayName value to list files in the Spotlight search results menu in the finder, which is something I'd like to implement in my app.
Thanks!
Heyyyy... wait a minute...
From the command line, doing xattr -l shows that as far as xattr knows, there is an attribute called kMDItemDisplayName, and it is what I set it to be... However, mdls on the same file still shows the kMDItemDisplayName attribute as the file name.
Do I need to be asking about Launch Services instead of xattr stuff??
OK. After hunting around a bit more and reading more Apple documentation I realized what I need to do. I'm answering my own question in the hope that this information may be of some assistance to someone else down the line.
Because I had to write my own mdimporter to support my app's file format, I thought I'd try adding the kMDItemDisplay name item to the metadata store at metadata import time.
To my amazement and delight, it worked on the first try!
So, the answer is, if you want to overwrite or add custom kMDItem* types, you do so at metadata import time, using a Spotlight importer.
Hope that someone finds this helpful!

What are the build setting modifiers in Xcode called?

I've seen some build settings being used like
$(PRODUCT_NAME:identifier)
Using :upper also makes the setting value uppercase, but I don't know what those are called and can't find any documentation. Does anyone know their name or where the documentation is to use them properly?
The file /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Versions/A/DevToolsCore has a bunch of these:
[ 09:22 root#MacBookPro / ]# strings /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Versions/A/DevToolsCore | egrep "(^:|^[a-z0-9]+$)"
:children.count=%lu
:name='%#'
:File='%#':Line=%lu:RefType=%#
:fileRef=%#:timestamp=%lu
:char-range=%#
:line-range=%#
:<range-type-%lu>=%#
:name='%#'
:name=%#:path='%#'
:name='%#'
:name='%#':buildSettings(%lu)=%#
:path='%#'
:quote
:identifier
:rfc1034identifier
:dir
:abs
:remoteRef='%#'
:File='%#':Head Revision=%#:Active Branch=%#
:scmProprties='%#':sandboxEntry='%#'
.... SNIP ....
upper
environment
diagnostics
type
category
description
path
kind
message
ranges
alternate
start
edges
location
file
Found this as well: DevToolsCore Framework Reference. Looks like an API for the Framework (- (id)initWithName:(id)arg1 productTypeIdentifier:(id)arg2).
Couldn't find any other documentation for it though, just this SO question (xcode-info-plist-build-variable-product-namerfc1034identifier-seems-complete).
Since they are not documented I don't think they have a name. When building Xcode 4 templates I found 3 variable modifiers in the Apple templates that seem to do the following:
identifier: ensures that it is a legal C variable name. It replaces illegal characters with underscores.
bundleIdentifier: ensures that it is a legal bundle identifier.
RFC1034Identifier: ensures that it is a legal domain name.
And thanks to you I know another one:
upper: change the value to uppercase.
The Xcode project templates are not documented. They are defined in plists with an inheritance system. Their elements have a defined structure and use several expansion macros with double underscore like __PACKAGENAME__ (also seen in Xcode 3) that are modified with one of the modifiers mentioned above.
If you want to dig further on this I recommend Documentation: Xcode 4 templates. Learning Apple's template system was painful and slow until I stumbled onto this PDF. It's $10/€7,50 but it's worthy. Writing templates remains very cumbersome, I guess Apple engineers use an internal tool or a great deal of patience.
The build settings are called "build settings" and they are documented in the Xcode Build Setting Reference. The Product Name defaults to your target name, but you can make up your own value if you like. These settings are referenced when writing scripts. Usually you don't need to touch anything while using XCode.

How to detect if an element exists in Watir

I'm relatively new to Watir but can find no good documentation (examples) regarding how to check if an element exists. There are the API specs, of course, but these make precious little sense to me if I don't find an example.
I've tried both combinations but nothing seems to work...
if browser.image (:src "/media/images/icons/reviewertools/editreview.jpg").exists
then...
if browser.image (:src "/media/images/icons/reviewertools/editreview.jpg").exists?
then...
If anyone has a concrete suggestion as per how to implement this, please help! Thanks!
It seems you are missing a comma between parameters.
Should be
if browser.image(:src, "/media/images/icons/reviewertools/editreview.jpg").exists?
Also you can find this page useful in future to know what attributes are supported.
The code you posted should work just fine.
Edit: Oops, wrong. As Katmoon pointed out, there is a missing comma.
browser.image(:src "/media/images/icons/reviewertools/editreview.jpg").exists?
One problem you may get caught up in is if the browser variable you specified is actually an element that doesn't exist.
e.g.
b = Watir::IE.start(ipAddress)
b.frame(:name, "doesntExist).image(:src "/media/images/icons/reviewertools/editreview.jpg").exists?
The above code will throw a Watir::UnknownFrameException. You can get around this by first verifying the frame exists or by surrounding the code in a begin/rescue block.
Seems like you are using it correctly. Here is an old RDoc of Watir.
Does it not work because Watir cannot find it? Hard to tell because there is no source or link to the page that is being tested. I think that I only use image.exists?. In general, errors that come from when the image exists but is not found are:
The how is not compatible with the element type. There is a cheatsheet to help you see which object types can be found with different attributes here.
The what is not correct. You may have to play with that a little bit. Consider trying a regex string to match it such as browser.image(:src, /editreview.jpg/). As a last resort, maybe use element_by_xpath, but there are maintenance costs with that.
The location is not correct. Maybe the element is in a frame or something like that. browser.frame("detail").image(:src, /editreview.jpg/).
Try those, but please let me know what worked. One more thing, what are you checking for? If it's part of the test criteria, you can handle it that way. If you need to click on it, then forget the .exists? and just click on it. Ruby will let you know if it's not there. If you need it to be grace, learn about begin/rescue.
Good luck,
Dave

Resources