Ticket #9749: 0001-Notification_Server-Added-ability-to-choose-position.patch

File 0001-Notification_Server-Added-ability-to-choose-position.patch, 14.2 KB (added by hrily, 6 years ago)

Patch with fixes for 64bit build

  • headers/private/notification/Notifications.h

    From 69071c4b0afb005458b0ddd1f08eebde8bd0c8d1 Mon Sep 17 00:00:00 2001
    From: Hrishi Hiraskar <hrishihiraskar@gmail.com>
    Date: Mon, 11 Dec 2017 16:24:02 +0530
    Subject: [PATCH] Notification_Server: Added ability to choose position of
     notifications
    
    The feature gives user ability to choose the position of notifications
    out of Follow Deskbar, Lower Right, Lower Left, Upper Right and Upper
    Left. Fixes #9749 - Notification_Server: add the ability to choose the
    position of notifications (easy).
    ---
     headers/private/notification/Notifications.h    |   5 +
     src/preferences/notifications/GeneralView.cpp   |  84 +++++++++++++++
     src/preferences/notifications/GeneralView.h     |   5 +
     src/servers/notification/NotificationWindow.cpp | 136 ++++++++++++++++++------
     src/servers/notification/NotificationWindow.h   |   1 +
     src/servers/notification/Notifications.cpp      |   1 +
     6 files changed, 197 insertions(+), 35 deletions(-)
    
    diff --git a/headers/private/notification/Notifications.h b/headers/private/notification/Notifications.h
    index 18298a4270..2f3ac9ec4f 100644
    a b  
    66#define _NOTIFICATIONS_H
    77
    88#include <Mime.h>
     9#include <View.h>
    910#include <String.h>
    1011
    1112#define kNotificationServerSignature "application/x-vnd.Haiku-notification_server"
    1213
     14#define B_FOLLOW_DESKBAR B_FOLLOW_NONE
     15
    1316// Messages
    1417const uint32 kNotificationMessage = 'nssm';
    1518
    extern const char* kAutoStartName;  
    2124extern const char* kTimeoutName;
    2225extern const char* kWidthName;
    2326extern const char* kIconSizeName;
     27extern const char* kNotificationPositionName;
    2428
    2529// General default settings
    2630const bool kDefaultAutoStart = true;
    const float kMinimumWidth = 300.0f;  
    3236const float kMaximumWidth = 1000.0f;
    3337const int32 kWidthStep = 50;
    3438const icon_size kDefaultIconSize = B_LARGE_ICON;
     39const uint32 kDefaultNotificationPosition = B_FOLLOW_DESKBAR;
    3540
    3641#endif  // _NOTIFICATIONS_H
  • src/preferences/notifications/GeneralView.cpp

    diff --git a/src/preferences/notifications/GeneralView.cpp b/src/preferences/notifications/GeneralView.cpp
    index bbd831f138..bde36889d6 100644
    a b  
    4343const uint32 kToggleNotifications = '_TSR';
    4444const uint32 kWidthChanged = '_WIC';
    4545const uint32 kTimeoutChanged = '_TIC';
     46const uint32 kPositionChanged = '_NPC';
    4647const uint32 kServerChangeTriggered = '_SCT';
    4748const BString kSampleMessageID("NotificationsSample");
    4849
    4950
     51static int32
     52notification_position_to_index(uint32 notification_position) {
     53    if (notification_position == B_FOLLOW_NONE)
     54        return 0;
     55    else if (notification_position == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM))
     56        return 1;
     57    else if (notification_position == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM))
     58        return 2;
     59    else if (notification_position == (B_FOLLOW_RIGHT | B_FOLLOW_TOP))
     60        return 3;
     61    else if (notification_position == (B_FOLLOW_LEFT | B_FOLLOW_TOP))
     62        return 4;
     63    return 0;
     64}
     65
     66
    5067GeneralView::GeneralView(SettingsHost* host)
    5168    :
    5269    SettingsPane("general", host)
    GeneralView::GeneralView(SettingsHost* host)  
    87104        B_TRANSLATE_COMMENT(minLabel.String(), "Slider low text"),
    88105        B_TRANSLATE_COMMENT(maxLabel.String(), "Slider high text"));
    89106
     107    // Notification Position
     108    fPositionMenu = new BPopUpMenu(B_TRANSLATE("Follow Deskbar"));
     109    const char* positionLabels[] = {
     110        B_TRANSLATE_MARK("Follow Deskbar"),
     111        B_TRANSLATE_MARK("Lower right"),
     112        B_TRANSLATE_MARK("Lower left"),
     113        B_TRANSLATE_MARK("Upper right"),
     114        B_TRANSLATE_MARK("Upper left")
     115    };
     116    const uint32 positions[] = {
     117        B_FOLLOW_DESKBAR,                   // Follow Deskbar
     118        B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT,   // Lower right
     119        B_FOLLOW_BOTTOM | B_FOLLOW_LEFT,    // Lower left
     120        B_FOLLOW_TOP    | B_FOLLOW_RIGHT,   // Upper right
     121        B_FOLLOW_TOP    | B_FOLLOW_LEFT     // Upper left
     122    };
     123    for (int i=0; i < 5; i++) {
     124        BMessage* message = new BMessage(kPositionChanged);
     125        message->AddInt32(kNotificationPositionName, positions[i]);
     126
     127        fPositionMenu->AddItem(new BMenuItem(B_TRANSLATE_NOCOLLECT(
     128            positionLabels[i]), message));
     129    }
     130    BMenuField* positionField = new BMenuField(B_TRANSLATE("Position:"),
     131        fPositionMenu);
     132
    90133    box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
    91134        .SetInsets(B_USE_DEFAULT_SPACING)
    92135        .Add(fWidthSlider)
    93136        .Add(fDurationSlider)
     137        .Add(positionField)
    94138        .AddGlue()
    95139        .View());
    96140   
    GeneralView::AttachedToWindow()  
    108152    fNotificationBox->SetTarget(this);
    109153    fWidthSlider->SetTarget(this);
    110154    fDurationSlider->SetTarget(this);
     155    fPositionMenu->SetTargetForItems(this);
    111156}
    112157
    113158
    GeneralView::MessageReceived(BMessage* msg)  
    134179            SettingsPane::SettingsChanged(true);
    135180            break;
    136181        }
     182        case kPositionChanged:
     183        {
     184            int32 position;
     185            if (msg->FindInt32(kNotificationPositionName, &position) == B_OK) {
     186                fNewPosition = position;
     187                SettingsPane::SettingsChanged(true);
     188            }
     189            break;
     190        }
    137191        default:
    138192            BView::MessageReceived(msg);
    139193            break;
    GeneralView::Load(BMessage& settings)  
    163217    else
    164218        fOriginalIconSize = (icon_size)setting;
    165219
     220    int32 position;
     221    if (settings.FindInt32(kNotificationPositionName, &position) != B_OK)
     222        fOriginalPosition = kDefaultNotificationPosition;
     223    else
     224        fOriginalPosition = position;
     225
    166226    _EnableControls();
    167227   
    168228    return Revert();
    GeneralView::Save(BMessage& settings)  
    184244    icon_size iconSize = B_LARGE_ICON;
    185245    settings.AddInt32(kIconSizeName, (int32)iconSize);
    186246
     247    settings.AddInt32(kNotificationPositionName, (int32)fNewPosition);
     248
    187249    return B_OK;
    188250}
    189251
    GeneralView::Revert()  
    196258   
    197259    fWidthSlider->SetValue(fOriginalWidth / 50);
    198260    _SetWidthLabel(fOriginalWidth);
     261
     262    fNewPosition = fOriginalPosition;
     263    BMenuItem* item = fPositionMenu->ItemAt(
     264        notification_position_to_index(fNewPosition));
     265    if (item != NULL)
     266        item->SetMarked(true);
    199267   
    200268    return B_OK;
    201269}
    GeneralView::RevertPossible()  
    212280    if (fOriginalWidth != width)
    213281        return true;
    214282
     283    if (fOriginalPosition != fNewPosition)
     284        return true;
     285
    215286    return false;
    216287}
    217288
    GeneralView::Defaults()  
    225296    fWidthSlider->SetValue(kDefaultWidth / 50);
    226297    _SetWidthLabel(kDefaultWidth);
    227298
     299    fNewPosition = kDefaultNotificationPosition;
     300    BMenuItem* item = fPositionMenu->ItemAt(
     301        notification_position_to_index(fNewPosition));
     302    if (item != NULL)
     303        item->SetMarked(true);
     304
    228305    return B_OK;
    229306}
    230307
    GeneralView::DefaultsPossible()  
    239316    int32 width = fWidthSlider->Value() * 50;
    240317    if (kDefaultWidth != width)
    241318        return true;
     319
     320    if (kDefaultNotificationPosition != fNewPosition)
     321        return true;
    242322   
    243323    return false;
    244324}
    GeneralView::_EnableControls()  
    257337    bool enabled = fNotificationBox->Value() == B_CONTROL_ON;
    258338    fWidthSlider->SetEnabled(enabled);
    259339    fDurationSlider->SetEnabled(enabled);
     340    BMenuItem* item = fPositionMenu->ItemAt(
     341        notification_position_to_index(fOriginalPosition));
     342    if (item != NULL)
     343        item->SetMarked(true);
    260344}
    261345
    262346
  • src/preferences/notifications/GeneralView.h

    diff --git a/src/preferences/notifications/GeneralView.h b/src/preferences/notifications/GeneralView.h
    index 0bd5a084b1..9106cee1b3 100644
    a b  
    1212#include <Menu.h>
    1313#include <MenuField.h>
    1414#include <Mime.h>
     15#include <PopUpMenu.h>
    1516#include <RadioButton.h>
    1617#include <Slider.h>
    1718#include <StringView.h>
    private:  
    4041        BCheckBox*          fNotificationBox;
    4142        BSlider*            fDurationSlider;
    4243        BSlider*            fWidthSlider;
     44        BPopUpMenu*         fPositionMenu;
     45
    4346       
    4447        int32               fOriginalTimeout;
    4548        float               fOriginalWidth;
    4649        icon_size           fOriginalIconSize;
     50        uint32              fOriginalPosition;
     51        uint32              fNewPosition;
    4752
    4853        void                _EnableControls();
    4954        void                _SetWidthLabel(int32 value);
  • src/servers/notification/NotificationWindow.cpp

    diff --git a/src/servers/notification/NotificationWindow.cpp b/src/servers/notification/NotificationWindow.cpp
    index bad3683f98..2f18c05b81 100644
    a b  
    2626#include <NodeMonitor.h>
    2727#include <Notifications.h>
    2828#include <Path.h>
     29#include <Point.h>
    2930#include <PropertyInfo.h>
     31#include <Screen.h>
    3032
    3133#include "AppGroupView.h"
    3234#include "AppUsage.h"
    property_info main_prop_list[] = {  
    5052};
    5153
    5254
     55/**
     56 * Checks if notification position overlaps with
     57 * deskbar position
     58 */
     59static bool
     60is_overlapping(deskbar_location deskbar,
     61        uint32 notification) {
     62    if (deskbar == B_DESKBAR_RIGHT_TOP
     63            && notification == (B_FOLLOW_RIGHT | B_FOLLOW_TOP))
     64        return true;
     65    if (deskbar == B_DESKBAR_RIGHT_BOTTOM
     66            && notification == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM))
     67        return true;
     68    if (deskbar == B_DESKBAR_LEFT_TOP
     69            && notification == (B_FOLLOW_LEFT | B_FOLLOW_TOP))
     70        return true;
     71    if (deskbar == B_DESKBAR_LEFT_BOTTOM
     72            && notification == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM))
     73        return true;
     74    if (deskbar == B_DESKBAR_TOP
     75            && (notification == (B_FOLLOW_LEFT | B_FOLLOW_TOP)
     76            || notification == (B_FOLLOW_RIGHT | B_FOLLOW_TOP)))
     77        return true;
     78    if (deskbar == B_DESKBAR_BOTTOM
     79            && (notification == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)
     80            || notification == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)))
     81        return true;
     82    return false;
     83}
     84
     85
    5386NotificationWindow::NotificationWindow()
    5487    :
    5588    BWindow(BRect(0, 0, -1, -1), B_TRANSLATE_MARK("Notification"),
    NotificationWindow::NotificationWindow()  
    6396    fCachePath.Append("Notifications");
    6497    BDirectory cacheDir;
    6598    result = cacheDir.SetTo(fCachePath.Path());
    66     if(result == B_ENTRY_NOT_FOUND)
     99    if (result == B_ENTRY_NOT_FOUND)
    67100        cacheDir.CreateDirectory(fCachePath.Path(), NULL);
    68101   
    69102    SetLayout(new BGroupLayout(B_VERTICAL, 0));
    NotificationWindow::MessageReceived(BMessage* message)  
    146179                BString sourceName(notification->SourceName());
    147180
    148181                bool allow = false;
    149                 appfilter_t::iterator it =
    150                     fAppFilters.find(sourceSignature.String());
     182                appfilter_t::iterator it = fAppFilters
     183                    .find(sourceSignature.String());
    151184               
    152185                AppUsage* appUsage = NULL;
    153186                if (it == fAppFilters.end()) {
    NotificationWindow::SetPosition()  
    275308   
    276309    float x = Frame().left;
    277310    float y = Frame().top;
    278         // If we can't guess, don't move...
     311        // If we cant guess, don't move...
     312    BPoint location(x, y);
    279313
    280314    BDeskbar deskbar;
    281     BRect frame = deskbar.Frame();
    282315
    283     switch (deskbar.Location()) {
    284         case B_DESKBAR_TOP:
    285             // Put it just under, top right corner
    286             y = frame.bottom + topOffset;
    287             x = frame.right - width + rightOffset;
    288             break;
    289         case B_DESKBAR_BOTTOM:
    290             // Put it just above, lower left corner
    291             y = frame.top - height - bottomOffset;
    292             x = frame.right - width + rightOffset;
    293             break;
    294         case B_DESKBAR_RIGHT_TOP:
    295             x = frame.left - width - rightOffset;
    296             y = frame.top - topOffset + 1;
    297             break;
    298         case B_DESKBAR_LEFT_TOP:
    299             x = frame.right + leftOffset;
    300             y = frame.top - topOffset + 1;
    301             break;
    302         case B_DESKBAR_RIGHT_BOTTOM:
    303             y = frame.bottom - height + bottomOffset;
    304             x = frame.left - width - rightOffset;
    305             break;
    306         case B_DESKBAR_LEFT_BOTTOM:
    307             y = frame.bottom - height + bottomOffset;
    308             x = frame.right + leftOffset;
    309             break;
    310         default:
    311             break;
     316    // If notification and deskbar position are same
     317    // then follow deskbar position
     318    uint32 position = (is_overlapping(deskbar.Location(), fPosition))
     319            ? B_FOLLOW_DESKBAR
     320            : fPosition;
     321
     322
     323    if (position == B_FOLLOW_DESKBAR)
     324    {
     325        BRect frame = deskbar.Frame();
     326        switch (deskbar.Location()) {
     327            case B_DESKBAR_TOP:
     328                // In case of overlapping here or for bottom
     329                // use user's notification position
     330                y = frame.bottom + topOffset;
     331                x = (fPosition == (B_FOLLOW_LEFT | B_FOLLOW_TOP))
     332                    ? frame.left + rightOffset
     333                    : frame.right - width + rightOffset;
     334                break;
     335            case B_DESKBAR_BOTTOM:
     336                y = frame.top - height - bottomOffset;
     337                x = (fPosition == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM))
     338                    ? frame.left + rightOffset
     339                    : frame.right - width + rightOffset;
     340                break;
     341            case B_DESKBAR_RIGHT_TOP:
     342                y = frame.top - topOffset + 1;
     343                x = frame.left - width - rightOffset;
     344                break;
     345            case B_DESKBAR_LEFT_TOP:
     346                y = frame.top - topOffset + 1;
     347                x = frame.right + leftOffset;
     348                break;
     349            case B_DESKBAR_RIGHT_BOTTOM:
     350                y = frame.bottom - height + bottomOffset;
     351                x = frame.left - width - rightOffset;
     352                break;
     353            case B_DESKBAR_LEFT_BOTTOM:
     354                y = frame.bottom - height + bottomOffset;
     355                x = frame.right + leftOffset;
     356                break;
     357            default:
     358                break;
     359        }
     360        location = BPoint(x, y);
     361    } else if (position == (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) {
     362        location = BScreen().Frame().RightBottom();
     363        location -= BPoint(width, height);
     364    } else if (position == (B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)) {
     365        location = BScreen().Frame().LeftBottom();
     366        location -= BPoint(0, height);
     367    } else if (position == (B_FOLLOW_RIGHT | B_FOLLOW_TOP)) {
     368        location = BScreen().Frame().RightTop();
     369        location -= BPoint(width, 0);
     370    } else if (position == (B_FOLLOW_LEFT | B_FOLLOW_TOP)) {
     371        location = BScreen().Frame().LeftTop();
    312372    }
    313373
    314     MoveTo(x, y);
     374    MoveTo(location);
    315375}
    316376
    317377
    NotificationWindow::_LoadDisplaySettings(BMessage& settings)  
    402462    else
    403463        fIconSize = (icon_size)setting;
    404464
     465    int32 position;
     466    if (settings.FindInt32(kNotificationPositionName, &position) != B_OK)
     467        fPosition = kDefaultNotificationPosition;
     468    else
     469        fPosition = position;
     470
    405471    // Notify the views about the change
    406472    appview_t::iterator aIt;
    407473    for (aIt = fAppViews.begin(); aIt != fAppViews.end(); ++aIt) {
  • src/servers/notification/NotificationWindow.h

    diff --git a/src/servers/notification/NotificationWindow.h b/src/servers/notification/NotificationWindow.h
    index f4325a9ae2..8861453c60 100644
    a b private:  
    6363            float                   fWidth;
    6464            icon_size               fIconSize;
    6565            int32                   fTimeout;
     66            uint32                  fPosition;
    6667            bool                    fShouldRun;
    6768            BPath                   fCachePath;
    6869};
  • src/servers/notification/Notifications.cpp

    diff --git a/src/servers/notification/Notifications.cpp b/src/servers/notification/Notifications.cpp
    index 3dfcb1e713..d49f0c3e15 100644
    a b const char* kTimeoutName = "timeout";  
    1717// Display settings
    1818const char* kWidthName = "width";
    1919const char* kIconSizeName = "icon size";
     20const char* kNotificationPositionName = "notification position";