jacobsalmela / NCutil

Notification Center utility- Add/remove apps, set alert styles, suppress App store notifications
GNU General Public License v2.0
171 stars 18 forks source link

Safer strategy for setting alert style; get current alert style, more #6

Closed gregneagle closed 9 years ago

gregneagle commented 9 years ago

Lots of changes here: hope they aren't too overwhelming.

Biggest: instead of writing out opaque hard-coded flag values when setting alert styles, we read the current flags and then turn on/off the appropriate bits within the flags to set the alert style appropriately. This avoids disturbing the other flag bits and allows us to support the "none" style in 10.8 and 10.9 as well as 10.10.

Once we set the alert style this way, it also made sense to reimplement the remove_system_center() function to do the same thing -- so we find all the bundle_ids like "_SYSTEMCENTER%" and set their alert style to 'none', instead of writing an opaque hard-coded flag value.

Finally, this laid the groundwork for adding a -g/--getalertstyle option. While doing this, I thought it best to check to make sure the bundle_id exists in the database before doing anything else, then added that same check to some of the other operations.

jacobsalmela commented 9 years ago

A colon is missing on line 141:

if (bundle_id == 'com.apple.maspushagent')

jacobsalmela commented 9 years ago

Oops, not a colon, I think it just needs to be on one line.

gregneagle commented 9 years ago

Fixed in https://github.com/gregneagle/NCutil/commit/1db1835225526f3cf1d4e4e17dec1d95cd36ba3a

jacobsalmela commented 9 years ago

I will merge your request as I have been testing it and everything seems to work as expected.

I noticed some of the code you used in the remove_system_center() function was similar to that seen in modifyNotificationCenter.py. In particular, the lines:

SHOW_IN_CENTER = 1 << 0
BADGE_ICONS = 1 << 1
SOUNDS = 1 << 2
BANNER_STYLE = 1 << 3
ALERT_STYLE = 1 << 4
UNKNOWN_5 = 1 << 5
UNKNOWN_6 = 1 << 6
UNKNOWN_7 = 1 << 7
UNKNOWN_8 = 1 << 8
UNKNOWN_9 = 1 << 9
UNKNOWN_10 = 1 << 10
UNKNOWN_11 = 1 << 11
SHOW_ON_LOCKSCREEN = 1 << 12
SHOW_PREVIEWS_ALWAYS = 1 << 13
SHOW_PREVIEWS_WHEN_UNLOCKED = 1 << 14

I don't fully understand the code as you seem to have a better grasp on the language then me--I'm simply a CodeAcademy graduate =). I borrowed the overall structure for this utility from one of my favorites, dockutil. I grasp the concepts of everything since you explained it well, but the syntax eludes me.

But, if those settings work for the _SYSTEM_CENTER_ entries, could they also be used for any other entry so each of those checkboxes could be set via the command line?

modifyNotificationCenter.py seems to be able to do a lot of that stuff. I think the syntax of NCutil.py is more human-friendly and a easier to remember.

gregneagle commented 9 years ago

The flags field in the app_info table appears to be a 16-bit value, which can be viewed as a bunch of binary flags: 0000000000001111

The first flag on the right is binary 1 The second flag from the right is binary 10 (decimal 2). The third flag is binary 100 (decimal 4), and so on. The flags are combined together to make the composite value of all the flags.

In Python, this (1 << 2) can be thought of as a "bit-shift" operator; (1 << 2) moves the one two places to the left, so (1 << 2) = binary 100.

We can clear a specific bit from the flag value like so:

flags & ~(1 << 2)

would clear the third bit from the right. This can be read as "flags binary-and binary-not binary-100"

Setting a flag uses the binary OR operator:

flags | (1 << 2) would set the 100 bit no matter its current state.

This sort of binary bit manipulation was very common and very important many years ago when computers had very little memory and we needed to use every bit (pun intended) so I encountered this sort of thing early on.

We can name many of the flags by making choices in the Notifcation Center preferences pane and observing what bits get switched on or off. About half the flags don't (currently) have a corresponding control in the prefs pane, so we don't really know what they control. Some of them are used, however, so they have some internal meaning to Notification Center. When we change the flags value, we should preserve the values of any of the other flags we don't intend to change, especially the ones we don't know what they do.

And yes, we should be able to set any particular bit we want, so yes, we should be able to add options to turn on/off sounds, icon badges, etc for any Notification Center item.

I do worry about those items that are hidden from the Notification Center prefs pane; I think we should be careful with those. Apple is obviously not expecting users to change any of their preferences (since there is no UI to do so) and so we should be conservative in our approach with them.

jacobsalmela commented 9 years ago

This is very interesting! I appreciate the detailed explanation. I love learning something new.

I understand the concern about modifying the hidden items, which is why I mentioned it in the README. Your explanation is a bit (pun intended) more clear though, so I'll update it again.

gregneagle commented 9 years ago

I'll have a new PR perhaps later today that will lay the groundwork for supporting more options like turning sounds on and off; icon badging, etc. (I personally am not that interested in those options, but others might be)