Merge lp:~nik90/ubuntu-clock-app/performance-patch-1 into lp:ubuntu-clock-app/saucy

Proposed by Nekhelesh Ramananthan
Status: Merged
Approved by: Nekhelesh Ramananthan
Approved revision: 350
Merged at revision: 347
Proposed branch: lp:~nik90/ubuntu-clock-app/performance-patch-1
Merge into: lp:ubuntu-clock-app/saucy
Diff against target: 394 lines (+119/-46)
7 files modified
alarm/AlarmPage.qml (+3/-1)
clock/ClockPage.qml (+6/-6)
clock/WorldClock.qml (+2/-2)
common/SettingsPage.qml (+24/-3)
stopwatch/StopwatchPage.qml (+5/-1)
timer/TimerPage.qml (+5/-1)
ubuntu-clock-app.qml (+74/-32)
To merge this branch: bzr merge lp:~nik90/ubuntu-clock-app/performance-patch-1
Reviewer Review Type Date Requested Status
Riccardo Padovani Approve
Alan Pope 🍺🐧🐱 πŸ¦„ (community) Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+207119@code.launchpad.net

Commit message

Improved the IDLE performance of the clock app. Added a settings option to hide/show the seconds hand.

Description of the change

Dynamically loads tabs using QML Loaders ensuring there is only one tab in memory at any time. This has improve the IDLE performance of the clock app significantly. It has resulted in the IDLE CPU usage reduction from 2.6-4.0% to 0%.

It also adds an settings option to show/hide the seconds hand.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
350. By Nekhelesh Ramananthan

Fixed invalid call to clock page

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Looks good.

review: Approve
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

lgtm, great work :-)

review: Approve
Revision history for this message
Colin Ian King (colin-king) wrote :

Thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'alarm/AlarmPage.qml'
--- alarm/AlarmPage.qml 2014-02-13 20:46:28 +0000
+++ alarm/AlarmPage.qml 2014-02-19 09:59:28 +0000
@@ -26,6 +26,7 @@
26 id: alarmPage26 id: alarmPage
27 objectName: "alarmPage"27 objectName: "alarmPage"
2828
29 readonly property real alarmHeaderHeight: units.gu(9.5)
29 property string currentTime30 property string currentTime
30 property alias modelCount: listSavedAlarm.count31 property alias modelCount: listSavedAlarm.count
31 property int enabledAlarmCount: 032 property int enabledAlarmCount: 0
@@ -38,6 +39,7 @@
38 tempPosition = clockAnimationContainer.contentY39 tempPosition = clockAnimationContainer.contentY
39 currentTime = Utils.convertTime(new Date().getHours(), new Date().getMinutes(), new Date().getUTCSeconds(), appSetting.contents.timeFormat)40 currentTime = Utils.convertTime(new Date().getHours(), new Date().getMinutes(), new Date().getUTCSeconds(), appSetting.contents.timeFormat)
40 }41 }
42 Component.onDestruction: Utils.log("AlarmPage unloaded")
4143
42 onModelCountChanged: modelCount == 0 ? clockAnimationContainer.contentY = tempPosition : undefined44 onModelCountChanged: modelCount == 0 ? clockAnimationContainer.contentY = tempPosition : undefined
4345
@@ -173,7 +175,7 @@
173 Column {175 Column {
174 id: listAlarm176 id: listAlarm
175177
176 property int dynamicTopSpacing: alarmPage.height - alarmPage.header.height - alarmFace.height - savedAlarmHeader.height - alarmFace.anchors.topMargin - divider.height;178 property int dynamicTopSpacing: alarmPage.height - alarmHeaderHeight - alarmFace.height - savedAlarmHeader.height - alarmFace.anchors.topMargin - divider.height;
177179
178 height: childrenRect.height180 height: childrenRect.height
179 visible: listSavedAlarm.count != 0 ? true : false181 visible: listSavedAlarm.count != 0 ? true : false
180182
=== modified file 'clock/ClockPage.qml'
--- clock/ClockPage.qml 2014-02-11 11:58:51 +0000
+++ clock/ClockPage.qml 2014-02-19 09:59:28 +0000
@@ -30,6 +30,7 @@
30 id: clockPage30 id: clockPage
3131
32 // Property to hold the formatted time string to show on the screen32 // Property to hold the formatted time string to show on the screen
33 readonly property real clockHeaderHeight: units.gu(9.5)
33 property string currentTimeFormatted34 property string currentTimeFormatted
34 property string currentDate35 property string currentDate
35 property real currentUTCTime36 property real currentUTCTime
@@ -76,6 +77,7 @@
76 Utils.log("Saved Current Location: " + currentLocation.contents.city);77 Utils.log("Saved Current Location: " + currentLocation.contents.city);
77 Utils.log("Saved Current Location Coordinates: " + currentLocation.contents.lng + "," + currentLocation.contents.lat)78 Utils.log("Saved Current Location Coordinates: " + currentLocation.contents.lng + "," + currentLocation.contents.lat)
78 }79 }
80 Component.onDestruction: Utils.log("ClockPage unloaded")
7981
80 actions: [82 actions: [
81 Action {83 Action {
@@ -178,17 +180,15 @@
178 horizontalCenter: parent.horizontalCenter180 horizontalCenter: parent.horizontalCenter
179 }181 }
180182
183 showSecondHand: appSetting.contents.seconds === "true" ? true : false
181 innerLabel.text: currentTimeFormatted184 innerLabel.text: currentTimeFormatted
182 innerLabel.font.pixelSize: appSetting.contents.timeFormat === "12-hour" ? units.dp(31): units.dp(41)185 innerLabel.font.pixelSize: appSetting.contents.timeFormat === "12-hour" ? units.dp(31): units.dp(41)
183186
184 hours: new Date().getHours() * 5
185 minutes: new Date().getMinutes()
186 seconds: new Date().getUTCSeconds()
187
188 function timeChanged(now) {187 function timeChanged(now) {
189 hours = now.getHours() * 5188 hours = now.getHours() * 5
190 minutes = now.getMinutes()189 minutes = now.getMinutes()
191 seconds = now.getUTCSeconds();190 if (appSetting.contents.seconds === "true")
191 seconds = now.getUTCSeconds();
192 }192 }
193193
194 onClicked: {194 onClicked: {
@@ -254,7 +254,7 @@
254 Column {254 Column {
255 id: savedWorldClock255 id: savedWorldClock
256256
257 property int dynamicTopSpacing: clockPage.height - clockPage.header.height - clockFace.height - worldLocationHeader.height - clockFace.anchors.topMargin - divider.height;257 property int dynamicTopSpacing: clockPage.height - clockHeaderHeight - clockFace.height - worldLocationHeader.height - clockFace.anchors.topMargin - divider.height;
258258
259 height: childrenRect.height;259 height: childrenRect.height;
260 anchors { left:parent.left; right:parent.right; top: clockFace.bottom; topMargin: savedWorldClock.dynamicTopSpacing }260 anchors { left:parent.left; right:parent.right; top: clockFace.bottom; topMargin: savedWorldClock.dynamicTopSpacing }
261261
=== modified file 'clock/WorldClock.qml'
--- clock/WorldClock.qml 2014-02-05 14:41:21 +0000
+++ clock/WorldClock.qml 2014-02-19 09:59:28 +0000
@@ -66,9 +66,9 @@
66 onStatusChanged: {66 onStatusChanged: {
67 if(status == XmlListModel.Ready && worldClocks.city != "null") {67 if(status == XmlListModel.Ready && worldClocks.city != "null") {
68 if (isWorldCity)68 if (isWorldCity)
69 clockPage.addWorldLocation(worldClocks.city, getTimeDifference(cityDetailsModel.get(0).time), worldClocks.lng, worldClocks.lat)69 clockLoader.item.addWorldLocation(worldClocks.city, getTimeDifference(cityDetailsModel.get(0).time), worldClocks.lng, worldClocks.lat)
70 else70 else
71 clockPage.updateCurrentLocation(worldClocks.city, worldClocks.lng, worldClocks.lat)71 clockLoader.item.updateCurrentLocation(worldClocks.city, worldClocks.lng, worldClocks.lat)
72 worldClocks.clearUserSearch();72 worldClocks.clearUserSearch();
73 pageStack.pop()73 pageStack.pop()
74 }74 }
7575
=== modified file 'common/SettingsPage.qml'
--- common/SettingsPage.qml 2014-02-01 15:30:26 +0000
+++ common/SettingsPage.qml 2014-02-19 09:59:28 +0000
@@ -18,7 +18,7 @@
1818
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.1 as ListItem21import Ubuntu.Components.ListItems 0.1
2222
23Page {23Page {
24 id: settingsPage24 id: settingsPage
@@ -35,13 +35,34 @@
35 margins: units.gu(2)35 margins: units.gu(2)
36 }36 }
3737
38 Standard {
39 id: secondsOption
40
41 text: "Show Seconds"
42 showDivider: false
43 anchors {
44 left: parent.left
45 right: parent.right
46 margins: units.gu(-2)
47 }
48
49 control: Switch {
50 checked: appSetting.contents.seconds === "true" ? true : false
51 onClicked: {
52 var settings = JSON.parse(JSON.stringify(appSetting.contents))
53 settings.seconds = checked === true ? "true" : "false"
54 appSetting.contents = settings
55 }
56 }
57 }
58
38 OptionSelector {59 OptionSelector {
39 id: timeFormat60 id: timeFormat
40 text: "Time Format"61 text: "Time Format"
41 model: ["12-hour", "24-hour"]62 model: ["12-hour", "24-hour"]
42 selectedIndex: appSetting.contents.timeFormat === "12-hour" ? 0 : 163 selectedIndex: appSetting.contents.timeFormat === "12-hour" ? 0 : 1
43 onSelectedIndexChanged: {64 onSelectedIndexChanged: {
44 var settings = appSetting.contents65 var settings = JSON.parse(JSON.stringify(appSetting.contents))
45 settings.timeFormat = selectedIndex === 0 ? "12-hour" : "24-hour"66 settings.timeFormat = selectedIndex === 0 ? "12-hour" : "24-hour"
46 appSetting.contents = settings67 appSetting.contents = settings
47 }68 }
@@ -55,7 +76,7 @@
55 enabled: false76 enabled: false
56 selectedIndex: appSetting.contents.style === "analogue" ? 0 : 177 selectedIndex: appSetting.contents.style === "analogue" ? 0 : 1
57 onSelectedIndexChanged: {78 onSelectedIndexChanged: {
58 var settings = appSetting.contents79 var settings = JSON.parse(JSON.stringify(appSetting.contents))
59 settings.style = selectedIndex === 0 ? "analogue" : "digital"80 settings.style = selectedIndex === 0 ? "analogue" : "digital"
60 appSetting.contents = settings81 appSetting.contents = settings
61 }82 }
6283
=== modified file 'stopwatch/StopwatchPage.qml'
--- stopwatch/StopwatchPage.qml 2014-02-11 13:27:34 +0000
+++ stopwatch/StopwatchPage.qml 2014-02-19 09:59:28 +0000
@@ -28,9 +28,13 @@
28Page {28Page {
29 id: stopwatchPage29 id: stopwatchPage
3030
31 readonly property real stopwatchHeaderHeight: units.gu(9.5)
31 property alias lapStart: laps.lapStart32 property alias lapStart: laps.lapStart
33 property bool isRunning: analogStopwatch.timerStatus &&
34 analogStopwatch.hours !== 0 || analogStopwatch.minutes !== 0 || analogStopwatch.seconds !== 0 || analogStopwatch.milliseconds !== 0
3235
33 Component.onCompleted: Utils.log("StopwatchPage loaded");36 Component.onCompleted: Utils.log("StopwatchPage loaded");
37 Component.onDestruction: Utils.log("Stopwatch unloaded");
3438
35 // Function to create a lap39 // Function to create a lap
36 function create_lap() {40 function create_lap() {
@@ -166,7 +170,7 @@
166 id: listLap170 id: listLap
167 lapModel: laps171 lapModel: laps
168 anchors { left: parent.left; right: parent.right; top: analogStopwatch.bottom; topMargin: listLap.dynamicTopSpacing }172 anchors { left: parent.left; right: parent.right; top: analogStopwatch.bottom; topMargin: listLap.dynamicTopSpacing }
169 dynamicTopSpacing: stopwatchPage.height - stopwatchPage.header.height - analogStopwatch.height - headerHeight - analogStopwatch.anchors.topMargin - dividerHeight;173 dynamicTopSpacing: stopwatchPage.height - stopwatchHeaderHeight - analogStopwatch.height - headerHeight - analogStopwatch.anchors.topMargin - dividerHeight;
170 }174 }
171 }175 }
172}176}
173177
=== modified file 'timer/TimerPage.qml'
--- timer/TimerPage.qml 2014-02-11 09:48:53 +0000
+++ timer/TimerPage.qml 2014-02-19 09:59:28 +0000
@@ -28,12 +28,14 @@
28Page {28Page {
29 id: timerPage29 id: timerPage
3030
31 readonly property real timerHeaderHeight: units.gu(9.5)
31 property alias minutes: analogTimer.minutes;32 property alias minutes: analogTimer.minutes;
32 property alias seconds: analogTimer.seconds;33 property alias seconds: analogTimer.seconds;
33 property alias totalTime: analogTimer.totalTime;34 property alias totalTime: analogTimer.totalTime;
34 property alias timerOn: analogTimer.timerOn;35 property alias timerOn: analogTimer.timerOn;
35 property real tempPosition36 property real tempPosition
36 property bool setFocus: false37 property bool setFocus: false
38 property bool isRunning: analogTimer.state !== "" || timerPage.state !== "" || analogTimer.minutes !== 0 || analogTimer.seconds !== 0
3739
38 // Default Timer Presets as defined by the design team40 // Default Timer Presets as defined by the design team
39 U1db.Document {41 U1db.Document {
@@ -166,6 +168,7 @@
166 Utils.log("TimerPage loaded");168 Utils.log("TimerPage loaded");
167 tempPosition = timerAnimationContainer.contentY169 tempPosition = timerAnimationContainer.contentY
168 }170 }
171 Component.onDestruction: Utils.log("TimerPage unloaded")
169172
170 Flickable {173 Flickable {
171 id: timerAnimationContainer174 id: timerAnimationContainer
@@ -209,6 +212,7 @@
209 onMinutesChanged: innerLabel.text = setTimerLabel(minutes, seconds);212 onMinutesChanged: innerLabel.text = setTimerLabel(minutes, seconds);
210 onSecondsChanged: if (timerOn == true) seconds_timer.restart()213 onSecondsChanged: if (timerOn == true) seconds_timer.restart()
211 else innerLabel.text = setTimerLabel(minutes, seconds);214 else innerLabel.text = setTimerLabel(minutes, seconds);
215
212 states:[216 states:[
213 State { name: "STOP" },217 State { name: "STOP" },
214 State { name: "PAUSE"},218 State { name: "PAUSE"},
@@ -287,7 +291,7 @@
287 model: timers291 model: timers
288 visible: listCount !== 0292 visible: listCount !== 0
289 anchors { left: parent.left; right: parent.right; top: analogTimer.bottom; topMargin: listPreset.dynamicTopSpacing }293 anchors { left: parent.left; right: parent.right; top: analogTimer.bottom; topMargin: listPreset.dynamicTopSpacing }
290 dynamicTopSpacing: timerPage.height - timerPage.header.height - analogTimer.height - analogTimer.anchors.topMargin - headerHeight - dividerHeight;294 dynamicTopSpacing: timerPage.height - timerHeaderHeight - analogTimer.height - analogTimer.anchors.topMargin - headerHeight - dividerHeight;
291 }295 }
292 }296 }
293297
294298
=== modified file 'ubuntu-clock-app.qml'
--- ubuntu-clock-app.qml 2014-02-11 13:54:38 +0000
+++ ubuntu-clock-app.qml 2014-02-19 09:59:28 +0000
@@ -47,11 +47,11 @@
47 footerColor: "#D75669"47 footerColor: "#D75669"
4848
49 focus: true49 focus: true
50 Keys.onReturnPressed: Keyboard.enterShortcut(event, rootTabs.selectedTabIndex, stopwatchPage)50 Keys.onReturnPressed: Keyboard.enterShortcut(event, rootTabs.selectedTabIndex, stopwatchLoader.item)
51 Keys.onEnterPressed: Keyboard.enterShortcut(event, rootTabs.selectedTabIndex, stopwatchPage)51 Keys.onEnterPressed: Keyboard.enterShortcut(event, rootTabs.selectedTabIndex, stopwatchLoader.item)
52 Keys.onSpacePressed: Keyboard.spaceShortcut(event, rootTabs.selectedTabIndex, stopwatchPage)52 Keys.onSpacePressed: Keyboard.spaceShortcut(event, rootTabs.selectedTabIndex, stopwatchLoader.item)
53 Keys.onEscapePressed: Keyboard.escapeShortcut(event, rootTabs.selectedTabIndex, pagestack, timerPage, stopwatchPage)53 Keys.onEscapePressed: Keyboard.escapeShortcut(event, rootTabs.selectedTabIndex, pagestack, timerLoader.item, stopwatchLoader.item)
54 Keys.onPressed: rootTabs.selectedTabIndex = Keyboard.generalShortcuts(event, rootTabs.count, rootTabs.selectedTabIndex, pagestack, timerPage, stopwatchPage)54 Keys.onPressed: rootTabs.selectedTabIndex = Keyboard.generalShortcuts(event, rootTabs.count, rootTabs.selectedTabIndex, pagestack, timerLoader.item, stopwatchLoader.item)
5555
56 // Property to store the default application dimensions56 // Property to store the default application dimensions
57 readonly property real minimumWidth: units.gu(50)57 readonly property real minimumWidth: units.gu(50)
@@ -98,20 +98,12 @@
9898
99 onTriggered: {99 onTriggered: {
100 now = new Date();100 now = new Date();
101 // FIXME: only send callback to pages that need it101 if(clockLoader.source != "")
102 /* TODO: this timer should probably be changed to fire102 clockLoader.item.onTimerUpdate(now);
103 every minute (max) when the app is in the background,103 if(alarmLoader.source != "")
104 or just be activated when the app is visible in the104 alarmLoader.item.onTimerUpdate(now);
105 switcher105 if(timerLoader.source != "")
106 */106 timerLoader.item.onTimerUpdate(now);
107 clockPage.onTimerUpdate(now);
108 alarmPage.onTimerUpdate(now);
109 timerPage.onTimerUpdate(now);
110
111 /* stopwatchPage.onTimerUpdate(now) is not required since
112 there is an inbuilt stopwatch timer which runs at a
113 higher frequency.
114 */
115 }107 }
116 }108 }
117109
@@ -127,7 +119,7 @@
127 database: db119 database: db
128 docId: "appSettings"120 docId: "appSettings"
129 create: true121 create: true
130 defaults: { "timeFormat": "12-hour", "style": "analogue" }122 defaults: { "timeFormat": "12-hour", "style": "analogue", "seconds": "false" }
131 }123 }
132124
133 ////////////////////////////////////////////////////////////////////////////////125 ////////////////////////////////////////////////////////////////////////////////
@@ -143,51 +135,101 @@
143 objectName: "rootTabs"135 objectName: "rootTabs"
144 anchors.fill: parent136 anchors.fill: parent
145137
138 onSelectedTabChanged: {
139 if(rootTabs.selectedTab === stopwatchTab)
140 stopwatchLoader.source = Qt.resolvedUrl("stopwatch/StopwatchPage.qml")
141 else if(stopwatchLoader.source != "" && !stopwatchLoader.item.isRunning)
142 stopwatchLoader.source = ""
143
144 if(rootTabs.selectedTab === timerTab)
145 timerLoader.source = Qt.resolvedUrl("timer/TimerPage.qml")
146 else if(timerLoader.source != "" && !timerLoader.item.isRunning)
147 timerLoader.source = ""
148
149 if(rootTabs.selectedTab === alarmTab)
150 alarmLoader.source = Qt.resolvedUrl("alarm/AlarmPage.qml")
151 else
152 alarmLoader.source = ""
153
154 if(rootTabs.selectedTab === clockTab)
155 clockLoader.source = Qt.resolvedUrl("clock/ClockPage.qml")
156 else
157 clockLoader.source = ""
158 }
159
146 Tab {160 Tab {
161 id: clockTab
147 objectName: "ClockTab"162 objectName: "ClockTab"
148163
149 title: i18n.tr("Clock")164 title: i18n.tr("Clock")
150165
151 // Tab content begins here166 // Tab content begins here
152 page: ClockPage {167 page: Loader {
153 id: clockPage168 id: clockLoader
169 parent: clockTab
170 anchors {
171 left: parent.left
172 right: parent.right
173 bottom: parent.bottom
174 }
154 }175 }
155 }176 }
156177
157 // Disabled Alarm Tab until the feature is ready for use.178 // Disabled Alarm Tab until the feature is ready for use.
158 Tab {179 Tab {
180 id: alarmTab
159 objectName: "AlarmTab"181 objectName: "AlarmTab"
160182
161 title: i18n.tr("Alarm")183 title: i18n.tr("Alarm")
162184
163 page: AlarmPage {185 AlarmModel {
164 id: alarmPage186 id: alarmModel
187 Component.onCompleted: Utils.log("Alarm Database loaded")
188 onModelReset: if (alarmLoader.source != "") alarmLoader.item.get_next_active_alarm()
189 }
165190
166 AlarmModel {191 page: Loader {
167 id: alarmModel192 id: alarmLoader
168 Component.onCompleted: Utils.log("Alarm Database loaded")193 parent: alarmTab
169 onModelReset: alarmPage.get_next_active_alarm()194 anchors {
195 left: parent.left
196 right: parent.right
197 bottom: parent.bottom
170 }198 }
171 }199 }
172 }200 }
173201
174 Tab {202 Tab {
203 id: timerTab
175 objectName: "TimerTab"204 objectName: "TimerTab"
176205
177 title: i18n.tr("Timer")206 title: i18n.tr("Timer")
178207
179 page: TimerPage {208 page: Loader {
180 id: timerPage209 id: timerLoader
210 parent: timerTab
211 anchors {
212 left: parent.left
213 right: parent.right
214 bottom: parent.bottom
215 }
181 }216 }
182 }217 }
183218
184 Tab {219 Tab {
220 id: stopwatchTab
185 objectName: "StopwatchTab"221 objectName: "StopwatchTab"
186222
187 title: i18n.tr("Stopwatch")223 title: i18n.tr("Stopwatch")
188224
189 page: StopwatchPage {225 page: Loader {
190 id: stopwatchPage226 id: stopwatchLoader
227 parent: stopwatchTab
228 anchors {
229 left: parent.left
230 right: parent.right
231 bottom: parent.bottom
232 }
191 }233 }
192 }234 }
193 }235 }

Subscribers

People subscribed via source and target branches