Changeset View
Changeset View
Standalone View
Standalone View
applets/notifications/package/contents/ui/global/Globals.qml
Show All 22 Lines | |||||
23 | import QtQuick.Layouts 1.1 | 23 | import QtQuick.Layouts 1.1 | ||
24 | 24 | | |||
25 | import org.kde.plasma.plasmoid 2.0 | 25 | import org.kde.plasma.plasmoid 2.0 | ||
26 | import org.kde.plasma.core 2.0 as PlasmaCore | 26 | import org.kde.plasma.core 2.0 as PlasmaCore | ||
27 | import org.kde.plasma.components 2.0 as Components | 27 | import org.kde.plasma.components 2.0 as Components | ||
28 | import org.kde.kquickcontrolsaddons 2.0 | 28 | import org.kde.kquickcontrolsaddons 2.0 | ||
29 | 29 | | |||
30 | import org.kde.notificationmanager 1.0 as NotificationManager | 30 | import org.kde.notificationmanager 1.0 as NotificationManager | ||
31 | import org.kde.taskmanager 0.1 as TaskManager | ||||
31 | 32 | | |||
32 | import org.kde.plasma.private.notifications 2.0 as Notifications | 33 | import org.kde.plasma.private.notifications 2.0 as Notifications | ||
33 | 34 | | |||
34 | import ".." | 35 | import ".." | ||
35 | 36 | | |||
36 | // This singleton object contains stuff shared between all notification plasmoids, namely: | 37 | // This singleton object contains stuff shared between all notification plasmoids, namely: | ||
37 | // - Popup creation and placement | 38 | // - Popup creation and placement | ||
38 | // - Do not disturb mode | 39 | // - Do not disturb mode | ||
▲ Show 20 Lines • Show All 305 Lines • ▼ Show 20 Line(s) | 327 | urgencies: { | |||
344 | return urgencies; | 345 | return urgencies; | ||
345 | } | 346 | } | ||
346 | } | 347 | } | ||
347 | 348 | | |||
348 | property QtObject notificationSettings: NotificationManager.Settings { | 349 | property QtObject notificationSettings: NotificationManager.Settings { | ||
349 | onNotificationsInhibitedUntilChanged: globals.checkInhibition() | 350 | onNotificationsInhibitedUntilChanged: globals.checkInhibition() | ||
350 | } | 351 | } | ||
351 | 352 | | |||
353 | property QtObject tasksModel: TaskManager.TasksModel { | ||||
354 | // TODO should we filter by activity or desktop here? | ||||
355 | //virtualDesktop: virtualDesktopInfo.currentDesktop | ||||
356 | //screenGeometry: plasmoid.screenGeometry | ||||
357 | //activity: activityInfo.currentActivity | ||||
358 | | ||||
359 | //filterByVirtualDesktop: plasmoid.configuration.showOnlyCurrentDesktop | ||||
360 | //filterByScreen: plasmoid.configuration.showOnlyCurrentScreen | ||||
361 | //filterByActivity: plasmoid.configuration.showOnlyCurrentActivity | ||||
362 | //filterNotMinimized: plasmoid.configuration.showOnlyMinimized | ||||
363 | | ||||
364 | groupMode: TaskManager.TasksModel.GroupApplications | ||||
365 | groupInline: false | ||||
366 | } | ||||
367 | | ||||
352 | // This periodically checks whether do not disturb mode timed out and updates the "minutes ago" labels | 368 | // This periodically checks whether do not disturb mode timed out and updates the "minutes ago" labels | ||
353 | property QtObject timeSource: PlasmaCore.DataSource { | 369 | property QtObject timeSource: PlasmaCore.DataSource { | ||
354 | engine: "time" | 370 | engine: "time" | ||
355 | connectedSources: ["Local"] | 371 | connectedSources: ["Local"] | ||
356 | interval: 60000 // 1 min | 372 | interval: 60000 // 1 min | ||
357 | intervalAlignment: PlasmaCore.Types.AlignToMinute | 373 | intervalAlignment: PlasmaCore.Types.AlignToMinute | ||
358 | onDataChanged: { | 374 | onDataChanged: { | ||
359 | checkInhibition(); | 375 | checkInhibition(); | ||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | 382 | delegate: NotificationPopup { | |||
423 | replySubmitButtonIconName: model.replySubmitButtonIconName || "" | 439 | replySubmitButtonIconName: model.replySubmitButtonIconName || "" | ||
424 | 440 | | |||
425 | onExpired: popupNotificationsModel.expire(popupNotificationsModel.index(index, 0)) | 441 | onExpired: popupNotificationsModel.expire(popupNotificationsModel.index(index, 0)) | ||
426 | onHoverEntered: model.read = true | 442 | onHoverEntered: model.read = true | ||
427 | onCloseClicked: popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | 443 | onCloseClicked: popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | ||
428 | onDismissClicked: model.dismissed = true | 444 | onDismissClicked: model.dismissed = true | ||
429 | onConfigureClicked: popupNotificationsModel.configure(popupNotificationsModel.index(index, 0)) | 445 | onConfigureClicked: popupNotificationsModel.configure(popupNotificationsModel.index(index, 0)) | ||
430 | onDefaultActionInvoked: { | 446 | onDefaultActionInvoked: { | ||
447 | if (defaultActionFallbackWindowIdx) { | ||||
448 | if (!defaultActionFallbackWindowIdx.valid) { | ||||
449 | console.warn("Failed fallback notification activation as window no longer exists"); | ||||
450 | return; | ||||
451 | } | ||||
452 | | ||||
453 | // When it's a group, activate the window highest in stacking order (presumably last used) | ||||
454 | if (tasksModel.data(defaultActionFallbackWindowIdx, TaskManager.AbstractTasksModel.IsGroupParent)) { | ||||
455 | let highestStacking = -1; | ||||
456 | let highestIdx = undefined; | ||||
457 | | ||||
458 | for (let i = 0; i < tasksModel.rowCount(defaultActionFallbackWindowIdx); ++i) { | ||||
459 | const idx = tasksModel.index(i, 0, defaultActionFallbackWindowIdx); | ||||
460 | | ||||
461 | const stacking = tasksModel.data(idx, TaskManager.AbstractTasksModel.StackingOrder); | ||||
462 | | ||||
463 | if (stacking > highestStacking) { | ||||
464 | highestStacking = stacking; | ||||
465 | highestIdx = tasksModel.makePersistentModelIndex(defaultActionFallbackWindowIdx.row, i); | ||||
466 | } | ||||
467 | } | ||||
468 | | ||||
469 | if (highestIdx && highestIdx.valid) { | ||||
470 | tasksModel.requestActivate(highestIdx); | ||||
471 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)); | ||||
472 | | ||||
473 | } | ||||
474 | return; | ||||
475 | } | ||||
476 | | ||||
477 | tasksModel.requestActivate(defaultActionFallbackWindowIdx); | ||||
478 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)); | ||||
479 | return; | ||||
480 | } | ||||
481 | | ||||
431 | popupNotificationsModel.invokeDefaultAction(popupNotificationsModel.index(index, 0)) | 482 | popupNotificationsModel.invokeDefaultAction(popupNotificationsModel.index(index, 0)) | ||
432 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | 483 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | ||
433 | } | 484 | } | ||
434 | onActionInvoked: { | 485 | onActionInvoked: { | ||
435 | popupNotificationsModel.invokeAction(popupNotificationsModel.index(index, 0), actionName) | 486 | popupNotificationsModel.invokeAction(popupNotificationsModel.index(index, 0), actionName) | ||
436 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | 487 | popupNotificationsModel.close(popupNotificationsModel.index(index, 0)) | ||
437 | } | 488 | } | ||
438 | onReplied: { | 489 | onReplied: { | ||
Show All 9 Lines | |||||
448 | onSuspendJobClicked: popupNotificationsModel.suspendJob(popupNotificationsModel.index(index, 0)) | 499 | onSuspendJobClicked: popupNotificationsModel.suspendJob(popupNotificationsModel.index(index, 0)) | ||
449 | onResumeJobClicked: popupNotificationsModel.resumeJob(popupNotificationsModel.index(index, 0)) | 500 | onResumeJobClicked: popupNotificationsModel.resumeJob(popupNotificationsModel.index(index, 0)) | ||
450 | onKillJobClicked: popupNotificationsModel.killJob(popupNotificationsModel.index(index, 0)) | 501 | onKillJobClicked: popupNotificationsModel.killJob(popupNotificationsModel.index(index, 0)) | ||
451 | 502 | | |||
452 | // popup width is fixed | 503 | // popup width is fixed | ||
453 | onHeightChanged: positionPopups() | 504 | onHeightChanged: positionPopups() | ||
454 | 505 | | |||
455 | Component.onCompleted: { | 506 | Component.onCompleted: { | ||
507 | if (model.type === NotificationManager.Notifications.NotificationType && model.desktopEntry) { | ||||
456 | // Register apps that were seen spawning a popup so they can be configured later | 508 | // Register apps that were seen spawning a popup so they can be configured later | ||
457 | // Apps with notifyrc can already be configured anyway | 509 | // Apps with notifyrc can already be configured anyway | ||
458 | if (model.type === NotificationManager.Notifications.NotificationType && model.desktopEntry && !model.notifyRcName) { | 510 | if (!model.notifyRcName) { | ||
459 | notificationSettings.registerKnownApplication(model.desktopEntry); | 511 | notificationSettings.registerKnownApplication(model.desktopEntry); | ||
460 | notificationSettings.save(); | 512 | notificationSettings.save(); | ||
461 | } | 513 | } | ||
462 | 514 | | |||
515 | // If there is no default action, check if there is a window we could activate instead | ||||
516 | if (!model.hasDefaultAction) { | ||||
517 | for (let i = 0; i < tasksModel.rowCount(); ++i) { | ||||
518 | const idx = tasksModel.index(i, 0); | ||||
519 | | ||||
520 | // TODO is this the right thing to use or rather LauncherUrlWithoutIcon? | ||||
521 | const appId = tasksModel.data(idx, TaskManager.AbstractTasksModel.AppId); | ||||
522 | if (appId == model.desktopEntry + ".desktop") { | ||||
523 | console.log("Associated window titled", tasksModel.data(idx), "of", appId, "with this notification"); | ||||
524 | // Takes a row number, not a QModelIndex | ||||
525 | defaultActionFallbackWindowIdx = tasksModel.makePersistentModelIndex(i); | ||||
526 | hasDefaultAction = true; | ||||
527 | break; | ||||
528 | } | ||||
529 | } | ||||
530 | } | ||||
531 | } | ||||
532 | | ||||
463 | // Tell the model that we're handling the timeout now | 533 | // Tell the model that we're handling the timeout now | ||
464 | popupNotificationsModel.stopTimeout(popupNotificationsModel.index(index, 0)); | 534 | popupNotificationsModel.stopTimeout(popupNotificationsModel.index(index, 0)); | ||
465 | } | 535 | } | ||
466 | } | 536 | } | ||
467 | onObjectAdded: { | 537 | onObjectAdded: { | ||
468 | positionPopups(); | 538 | positionPopups(); | ||
469 | object.visible = true; | 539 | object.visible = true; | ||
470 | } | 540 | } | ||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |