Get Do Not Disturb settings - pebble-watch

Is it possible to retrieve the Do Not Disturb settings within a Pebble watch face? I want to know when my watch face should stop notifying the user, but only when DND is on. I assume it's also possible to get the 24/12 hour mode too?

It looks like you cannot currently access the Do Not Disturb setting:
I was wondering if it was possible to access some of the user choices made in the Settings menu of the Pebble.
I'm particularly interested in the Notifications/Do not disturb settings so I can prevent my app to vibrate when the user doesn't want to receive any notification.
Not at present, no. You should suggest it here: http://pages.getpebble.com/pages/suggestions so that Team Pebble know that lots of developers want it.
It might be worthwhile for you to add follow that advice and suggest it to Pebble. If enough of us ask for it we may eventually get it.
As for the 12 / 24 hour preference, you can use bool clock_is_24_style() as shown in the feature_clock_mode sample watchapp:
static void init() {
window = window_create();
window_stack_push(window, true /* Animated */);
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_frame(window_layer);
text_layer = text_layer_create((GRect){ .origin = { 0, 30 }, .size = bounds.size });
// Here you go!
text_layer_set_text(text_layer, clock_is_24h_style() ? "Mode:\n24" : "Mode:\n12");
text_layer_set_font(text_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_LIGHT));
text_layer_set_text_alignment(text_layer, GTextAlignmentCenter);
layer_add_child(window_layer, text_layer_get_layer(text_layer));
}

Related

Wearable DataAPI syncing issue with multiple watches (Looping)

I have a watchface with a companion app for phone. It uses Wearable.DataApi to sync changes between the phone and watch. I have a DataApi.DataListener setup and sync changes made on the watch or phone side. I have no issue with a phone and ONE watch communicating.
The issue is when i have multiple watches using the same watch face if changes on watch or phone side are made quickly it seems to go into a loop and start flashing the changes on all devices. So if im changing the color by tapping watch if I press a few times quickly to do that all devices start cycling through all colors and takes some time before it catches up and stops.
If I change options slowly there is no problem. I put a log in the DataApi listener and I see both uri's making the change but just seems to loop for some reason when changed quickly. Is there anyway to prevent this?
I know this might not seem like a big issue but if a user has 2 watches and accidently changes an option or options quickly it will start with the options and or colors changing. I want to prevent that from happening.
This is how im adding my listener in the onConnected method
Wearable.DataApi.addListener(mGoogleApiClient, dataListener);
And this is my listener method
DataApi.DataListener dataListener = new DataApi.DataListener() {
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.d(TAG, "onDataChanged");
for (DataEvent event : dataEvents) {
Log.d(TAG, "dataEvent.uri: " + event.getDataItem().getUri().toString());
DataMap item = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
/////other code to set data/////
}
updateCanvas();
}
};
You should be able to avoid this by filtering out dataEvents that originated from the local node (i.e., the device that the code is running on).
Get the local node ID with code like this:
NodeApi.GetLocalNodeResult nodeResult = Wearable.NodeApi.getLocalNode(googleApiClient).await();
String localNodeID = getLocalNodeResult.getNode().getId();
Then, put code like this inside your for loop to do the filtering:
Uri uri = item.getUri();
String nodeID = uri.getHost();
if (nodeID.equals(localNodeID)) {
// Skip changes originating on this device
continue;
}

deal with Unity 5 UI in augmented reality app

I'm trying to make an augmented reality application with vuforia and unity.
whenever it recognize the image target, it must tell a story by showing text , and it should enable the user to press next and back to go on reading the different parts of this story, I'm totally new to unity and don't know how to handle with UI throughout scripting, I need some help on how to accomplish the part of "going forward and backward on showing the story by hitting Next and Back buttons", and all these parts of story should be related to the same image target in the same scene.
I appreciate it if you help me with an example code.
You should create some script that attach on trackable object, maybe something like this.
public class DataBook {
string[] dataBook;
string idText;
bool isActive;
}
Then you must create another script to set that trackable object is active or not, this link can help you to get that.
https://developer.vuforia.com/forum/faq/unity-how-do-i-get-list-active-trackables
Then after you get the active trackable object, you can set the dialog from the book by create another controller script for button, example
public void Next() {
DataBook[] books = FindObjectsOfType<DataBook>(); // if the object more than one, it will be more easy if it only the one
foreach (var book in books)
{
if (book.isActive) {
book.idText += 1;
textUI.text = book.dataBook[idText]; //textUI assign to object text on canvas
}
}
}
you can learn about unity UI Button on this :
https://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button
Good luck

How can one detect Mission Control or Command-Tab switcher superseding one's program in OS X?

I'm trying to use CGAssociateMouseAndMouseCursorPosition(NO) in a program. This disconnects the mouse from the on screen cursor when your application is "in the foreground". Unfortunately it also disconnects it when Mission Control or the application switcher or who knows what else comes up.
So far I know:
The application is still active.
The window is still key.
Nothing is sent to the default notification center when these things come up.
The application stops receiving mouse moved events, but an NSEvent addGlobalMonitorForEventsMatchingMask:handler: also does not receive them, which is strange to say the least. It should receive any events not delivered to my application. (I was planning to detect the missing events to know when to associate the mouse again.
So, is there a way to detect when my application is no longer in control, specifically because Mission Control or the switch has taken over? They really expect the mouse to work and I need to restore that association for them.
I share your surprise that a global event monitor isn't seeing the events. In a similar situation, I used a Quartz Event Tap for a similar purpose. The Cocoa global event monitor is quite similar to event taps, so I figured it would work.
I put the tap on kCGAnnotatedSessionEventTap and compared the result from CGEventGetIntegerValueField(event, kCGEventTargetUnixProcessID) to getpid() to determine when the events were going to another app (e.g. Mission Control or Exposé). (I disable the tab when my app resigns active status, so it should only receive events destined for another app when this sort of overlay UI is presented.)
By the way, you mentioned monitoring the default notification center, but, if there's a notification about Mission Control or the like, it's more likely to come to the distributed notification center (NSDistributedNotificationCenter). So, it's worth checking that.
I needed to check for mission control being active and ended up with an approach along the lines of Ken's answer.
Sharing is caring so here is the smallest sensible complete code that worked for me: (Swift 5)
import Foundation
import AppKit
let dockPid = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.dock").first?.processIdentifier
var eventTargetPid: Int32?
let eventTap = CGEvent.tapCreate(
tap: .cgAnnotatedSessionEventTap,
place: .headInsertEventTap,
options: .listenOnly,
eventsOfInterest: CGEventMask(
(1 << CGEventType.mouseMoved.rawValue)
| (1 << CGEventType.keyDown.rawValue)
),
callback: { (tapProxy, type, event, _:UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? in
// Now, each time the mouse moves this var will receive the event's target pid
eventTargetPid = Int32(event.getIntegerValueField(.eventTargetUnixProcessID))
return nil
},
userInfo: nil
)!
// Add the event tap to our runloop
CFRunLoopAddSource(
CFRunLoopGetCurrent(),
CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0),
.commonModes
)
let periodSeconds = 1.0
// Add a timer for periodic checking
CFRunLoopAddTimer(CFRunLoopGetCurrent(), CFRunLoopTimerCreateWithHandler(
kCFAllocatorDefault,
CFAbsoluteTimeGetCurrent() + periodSeconds, periodSeconds, 0, 0,
{ timer in
guard eventTargetPid != dockPid else {
print("Dock")
return
}
print("Not dock")
// Do things. This code will not run if the dock is getting events, which seems to always be the case if mission control or command switcher are active
}), .commonModes)
CFRunLoopRun()
This simply checks whether the dock was the one to receive the last event of interest (here that includes mouse movement and key-downs).
It covers most cases, but will report the wrong value between the command switcher or mission-control hiding and the first event being sent to a non-dock app. This is fine in my use-case but could be an issue for other ones.
Also, of course, when the dock at the bottom is active, this will detect that too.
Have you tried asking NSRunningApplication?

Minimize/restore windows programmatically skipping the animation effect

I need to perform several operations on a list of windows (minimize some of them, restore others) in order to switch between two or more set of windows at once.
The problem with this are those animations you can see when minimizing and restoring a window. The whole process look terrible with all those animations going in and out, up and down.
I cannot, however, disable those animations because this is for other computers and i dont want to change other people's settings, plus those animations are actually useful when you minimize/restore one window only (i.e. when YOU do it manually) because you can see what is happening, but for doing it programmatically on several windows at a time, it's not nice.
I'm currenlty using the SendMessage function to send the WM_SYSCOMMAND message with params SC_MINIMIZE/SC_RESTORE. I dont know whether there is another way.
So, the question:
How can I minimize/restore a window programatically without the animation effect??
PS: The programming language is not important. I can use any language that's nessesary for accomplishing this.
SetWindowPlacement with SW_SHOWMINIMIZED or SW_RESTORE as appropriate for showCmd in WINDOWPLACEMENT seems to bypass window animation. I'd keep an eye on the functionality for future versions of the OS though since documentation does not mention anything about animation.
How about Hide > Minimize > Show ?
You could temporarily disable the animations and then restore the user's original setting.
class WindowsAnimationSuppressor {
public:
WindowsAnimationSuppressor() : m_suppressed(false) {
m_original_settings.cbSize = sizeof(m_original_settings);
if (::SystemParametersInfo(SPI_GETANIMATION,
sizeof(m_original_settings),
&m_original_settings, 0)) {
ANIMATIONINFO no_animation = { sizeof(no_animation), 0 };
::SystemParametersInfo(SPI_SETANIMATION,
sizeof(no_animation), &no_animation,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
m_suppressed = true;
}
}
~WindowsAnimationSuppressor() {
if (m_suppressed) {
::SystemParametersInfo(SPI_SETANIMATION,
sizeof(m_original_settings),
&m_original_settings,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
}
private:
bool m_suppressed;
ANIMATIONINFO m_original_settings;
};
void RearrangeWindows() {
WindowsAnimationSuppressor suppressor;
// Rearrange the windows here ...
}
When the suppressor is constructed, it remembers the user's original setting and turns off the animation. The destructor restores the original settings. By using a c'tor/d'tor, you ensure that the user's settings are restored if your rearranging code throws an exception.
There is a small window of vulnerability here. In theory, the user could change the setting during the operation, and then you'll slam the original setting back. That's extremely rare and not really that bad.

Firefox extension: How can I set the cursor position?

I have a page with possibly several content-editable iframes (editors).
Now I would like to use my custom Firefox extension to do the following:
Setting the cursor to the end (or last HTML element) of the editor the cursor actually is in.
I found many solutions to get the cursor's position, but I need one to set it.
Any suggestions?
XPCOM likely includes such functionality as part of the testing rig. Mochitest at least is capable of this (again, probably though XPCOM).
On the other hand, when a user is on the system this a generally a gross violation of user interaction practices. Be sure you have a good justification for doing it. It may seem convenient but what if they're doing something else whilst using your addon? I usually have various apps open at once, Fx extensions are only part of that. I don't want it taking control of my mouse, EVER.
Is there something wrong with setting the focus? At least that only forces the user's hand at a window level.
It also suspect it make it quite difficult to get past AMO review. You'd have to justify why it was necessary to invoke such low-level functionality. If you interact with a window, for example, the window might be able to affect the input of your functions which in turn control the mouse... and then a random web site has access to the user's window!
Found the solution to my problem myself. This code myself will set the Cursor position to the last Paragraph of my editor:
var frame = window.content.document.getElementsByTagName('iframe')[2];
var win = frame.contentWindow;
var editingSession = Components.classes["#mozilla.org/editor/editingsession;1"].createInstance(Components.interfaces.nsIEditingSession);
var editor = editingSession.getEditorForWindow(win);
selection = window.getSelection();
var body = frame.contentDocument.body;
text = frame.contentDocument.createTextNode(".");
body.lastChild.appendChild(text); // add textnode to be selected
var range = editor.document.createRange();
range.setStartBefore(text);
range.setEndAfter(text);
editor.selection.removeAllRanges();
editor.selection.addRange(range);
body.lastChild.removeChild(text); // remove Child

Resources