The agenda part filtered calendars through the search settings and always
collapsed after four rows. It now has its own selection: an exclusion set
(`clockWidgetCalendarPartExcludedCalendars`, empty = all) that is added to the
search settings' exclusions, because the picker only offers calendars those
settings leave enabled.
The row cap is `clockWidgetCalendarPartMaxRows` (1..8, default 4); the agenda
shows that many events and then a "+N more events" row if more are left, so
with the default five events now render as four rows plus "+1 more event"
instead of three plus "+2".
Both are configured in `ConfigureCalendarPart`, shown by the clock sheet while
the Events part is enabled: a slider, a Calendars row that expands into a
colour-tinted checkbox per calendar, and a button to Settings -> Search ->
Calendar (new `ROUTE_SEARCH_CALENDARS`) for calendars the search settings
disable. A missing calendar permission shows a banner with a Grant button.
New setting fields default to the previous behaviour, so no datastore
migration is needed.
Breezy Weather resolves its own location and pushes weather updates, but
WeatherUpdateWorker only looked at autoLocation before requesting a location.
BreezyWeatherProvider.getWeatherData() is a noop that always returns null, so
the worker then returned Result.retry() forever and never set lastUpdate -
which meant the update interval check could never short-circuit it either.
Every attempt called getLastKnownLocation(), which registers GPS *and* network
listeners at a one second interval and held them for up to ten minutes, so the
location stack never idled. On the phone this showed up as ~46k delivered fixes,
`*location*` wakelocks held ~99% of the time and Doze never engaging at all.
- expose the selected provider's managedLocation in WeatherSettingsData
- skip and cancel the weather work for providers that manage their own location
- give up on a fix after two minutes instead of ten
- LocationsRepository: don't collect the location flow when location search is
off or not permitted. As a combineTransform argument it was always collected,
so every search query registered GPS and network listeners for up to 30s.
Bump to 1.40.2-typing.8 (versionCode 2026091201).
The dynamic zone showed exactly one part: the highest ranked of the enabled
ones. It now shows up to `clockWidgetDynamicZoneSlots` of them (default 1),
adjustable with a slider in the clock widget settings whose maximum is the
number of enabled parts. `ClockWidgetVM.getActiveParts()` returns that sorted
list, and both clock layouts render it (stacked under the clock, or next to it
in the horizontal layout).
On top of that the zone has an "Events" part (`clockWidgetCalendarPart`, off by
default) that shows today's agenda: events that are still running or upcoming
today, plus today's all-day events. At most four rows; when there are more, the
last row is a "+N more events" hint that opens the calendar app. Tapping a row
opens the event through `CalendarEvent.launch()`.
A row is three fixed-width columns that are pure layout, not drawn: a dot in the
calendar's colour, the time, and the title (ellipsized when it does not fit).
Times are always times, never dates - an all-day event renders "all-day" - and
the block is centred under the clock. The columns line up across rows, and the
time is left-aligned within its column.
The part ranks 70 when an event is running or starts within half an hour, 30
while events are left today and 0 on an empty day, so the date keeps the slot
when there is nothing to show. It reloads itself through a ContentObserver on
CalendarContract.Events and a 15 minute ticker, because unlike the calendar
widget it is on screen all the time. Tasks (`CalendarEvent.isTask`) are filtered
out for now; a tasks part can reuse this once tasks are configured.
Verified on the Titan 2: with the part enabled and three slots, the home screen
shows the agenda (two all-day events and a timed one) above the date part.
Typing on a physical keyboard while the home screen is shown now opens the
search page and inserts the typed character, so the launcher can be used
without touching the screen. It works for any printable key, appends the
characters in order even when the user types faster than the launcher can
recompose, and the search bar can still be tapped to edit the query with
the on-screen keyboard as usual.
While the search is driven by the keyboard, the search bar's text field is
left unfocused on purpose: a focused text field would make the system show
the on-screen keyboard, which is not wanted when there is a physical
keyboard. The handler therefore inserts and deletes characters itself,
including backspace and enter (to launch the best match).
The behaviour is controlled by a new "Search on typing" preference in
Settings -> Search, which is enabled by default.
Implementation notes:
- The key events are intercepted in SharedLauncherActivity.dispatchKeyEvent,
which is the only place that sees hardware key events while no view has
focus. The scaffold installs the handler while it is shown.
- Key events are not forwarded to the search bar's text field, so the
characters are inserted into the search view model directly.
- SearchBar keeps a TextFieldValue instead of a String so that the cursor
moves to the end of the text when the value is changed from the outside.
Without this the next typed character ended up in front of the text.
* Added "always show battery" toggle
* Newline at end
* Removed comment
* Added newline
* Removed... newline? Github UI, come on now...
Removed unnecessary newline at the end of the file.
* Made setting into a list
* Added migration
---------
Co-authored-by: Valerie <15646950+MM2-0@users.noreply.github.com>
* Initial approach
* Add a new setting so users can choose the amount of widgets screens
* Extract indexed string
* Remove unnecessary Migration6
* Make HomeComponent use the Default widget id
* Add defaultParentId to initial widgets for fresh launch
* Fix migration path
* Feat: grid icon visibility settings and migration support
* fix: remove unnecessary padding
* Feat: Create List View Settings
* fix FavoritesPartProvider
* small fix
* fix favorites
* Remove useless datastore migration
* Change app list default value
* Revert migration 3
* Hide list icon preference if list is not enabled
* Use ListResults for app list
---------
Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>
* ContactRepository: try to deduplicate phoneNumbers in a smart way
* AndroidManifest: use CALL_PHONE permission to allow for making phone calls
* Implement CallOnTap with contact results
- contact activities that require permissions we do not have are not
listed
- add CallOnTap setting for phone number results on search behind
contacts settings
* utilize PhoneNumberUtils
* navroute settings/search/contacts
* queryIntentActivities -> resolveActivity
* localization
* Code formatting
* Wrap contact search settings in preference category
---------
Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>
* Add style to BinaryClock for 24-hour time
* Use global time format preference for all clock widget styles
* Add support for time format preference to remaining clock styles
---------
Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>