- Reorganized directory structure following open source best practices - Created src/ directory for all source code components - Moved build artifacts to build/ subdirectories - Organized documentation into phases/, guides/, and api/ subdirectories - Moved third-party code to vendor/ directory - Moved downloads to downloads/ directory - Updated all build scripts to reference new directory structure - Created comprehensive PROJECT_STRUCTURE.md documentation - Added DEVELOPMENT_GUIDE.md as main entry point - Improved separation of concerns and maintainability - Follows standard open source project conventions
17 KiB
Phase 4: User Interface Layer Development
🎯 Objectives
Create a keyboard-centric, trackpad-optimized graphical user interface that provides an intuitive and efficient user experience for the BlackBerry Classic (Q20).
📋 Detailed Tasks
4.1 Display Server Architecture
4.1.1 Wayland Compositor Selection
Options to Evaluate:
- Sway: i3-compatible Wayland compositor
- Weston: Reference Wayland compositor
- Custom Compositor: Tailored for Q20
- Hyprland: Modern tiling compositor
Selection Criteria:
- Keyboard navigation support
- Trackpad optimization
- Resource efficiency
- Customization flexibility
- Community maintenance
Evaluation Tasks:
- Test keyboard shortcuts in each compositor
- Evaluate trackpad gesture support
- Measure memory and CPU usage
- Assess customization capabilities
- Choose optimal compositor
4.1.2 Custom Compositor Development
Architecture Design:
// Compositor structure
struct q20_compositor {
struct wl_display *display;
struct wl_event_loop *event_loop;
struct wl_listener display_destroy;
// Output management
struct wl_list outputs;
struct q20_output *primary_output;
// Input handling
struct wl_list seats;
struct q20_seat *primary_seat;
// Window management
struct wl_list views;
struct q20_view *focused_view;
// Keyboard shortcuts
struct wl_list shortcuts;
struct q20_shortcut *active_shortcut;
};
// Output management
struct q20_output {
struct wl_list link;
struct wl_output *wl_output;
struct q20_compositor *compositor;
// Display properties
int width, height;
int refresh_rate;
int scale;
// Rendering
struct wl_list views;
struct q20_view *fullscreen_view;
};
// Input handling
struct q20_seat {
struct wl_list link;
struct wl_seat *wl_seat;
struct q20_compositor *compositor;
// Input devices
struct wl_list keyboards;
struct wl_list pointers;
struct wl_list touch;
// Focus management
struct q20_view *focused_view;
struct wl_listener view_destroy;
};
Development Tasks:
- Design compositor architecture
- Implement output management
- Create input handling system
- Add window management
- Implement keyboard shortcuts
4.2 Application Framework
4.2.1 UI Framework Selection
Options:
- Qt 6: Modern, feature-rich framework
- GTK 4: GNOME-based framework
- EFL: Enlightenment Foundation Libraries
- Custom Framework: Tailored for Q20
Selection Criteria:
- Wayland support
- Keyboard navigation
- Resource efficiency
- Development productivity
- Community support
Qt 6 Implementation:
// Main application class
class Q20Application : public QApplication
{
Q_OBJECT
public:
Q20Application(int &argc, char **argv);
~Q20Application();
// Keyboard shortcuts
void registerShortcut(const QString &key, const QString &action);
void handleShortcut(const QString &key);
// Window management
void showHomeScreen();
void showAppLauncher();
void showSettings();
private:
// UI components
Q20HomeScreen *homeScreen;
Q20AppLauncher *appLauncher;
Q20Settings *settings;
// Keyboard handling
QHash<QString, QString> shortcuts;
QShortcut *shortcutHandler;
};
// Home screen implementation
class Q20HomeScreen : public QWidget
{
Q_OBJECT
public:
Q20HomeScreen(QWidget *parent = nullptr);
public slots:
void showNotifications();
void showQuickSettings();
void launchApp(const QString &appName);
private:
// UI elements
QVBoxLayout *mainLayout;
QHBoxLayout *topBar;
QHBoxLayout *bottomBar;
// Widgets
QLabel *timeLabel;
QLabel *batteryLabel;
QLabel *signalLabel;
QPushButton *menuButton;
QPushButton *backButton;
QPushButton *callButton;
QPushButton *endButton;
// App shortcuts
QList<QPushButton*> appButtons;
private slots:
void updateTime();
void updateBattery();
void updateSignal();
void handleMenuClick();
void handleBackClick();
void handleCallClick();
void handleEndClick();
};
4.2.2 Application Launcher
Launcher Design:
// App launcher class
class Q20AppLauncher : public QWidget
{
Q_OBJECT
public:
Q20AppLauncher(QWidget *parent = nullptr);
public slots:
void showAllApps();
void showFavorites();
void searchApps(const QString &query);
void launchApp(const QString &appName);
private:
// UI layout
QVBoxLayout *mainLayout;
QHBoxLayout *searchBar;
QScrollArea *appGrid;
QWidget *appContainer;
QGridLayout *appGridLayout;
// App management
QList<Q20AppInfo> installedApps;
QList<Q20AppInfo> favoriteApps;
// Search functionality
QLineEdit *searchInput;
QList<Q20AppInfo> searchResults;
private slots:
void populateAppGrid();
void filterApps(const QString &query);
void handleAppClick(const QString &appName);
void toggleFavorite(const QString &appName);
};
// App information structure
struct Q20AppInfo {
QString name;
QString displayName;
QString description;
QString iconPath;
QString executable;
QStringList categories;
bool isFavorite;
bool isSystem;
};
4.3 Core Applications
4.3.1 Phone Dialer
Dialer Implementation:
// Phone dialer class
class Q20Dialer : public QWidget
{
Q_OBJECT
public:
Q20Dialer(QWidget *parent = nullptr);
public slots:
void dialNumber(const QString &number);
void answerCall();
void endCall();
void muteCall();
void speakerToggle();
void showContacts();
void showCallHistory();
private:
// UI components
QVBoxLayout *mainLayout;
QHBoxLayout *numberDisplay;
QGridLayout *keypadLayout;
QHBoxLayout *callControls;
// Display
QLineEdit *numberInput;
QLabel *callerName;
QLabel *callDuration;
// Keypad
QList<QPushButton*> numberButtons;
QPushButton *starButton;
QPushButton *hashButton;
QPushButton *deleteButton;
// Call controls
QPushButton *callButton;
QPushButton *endButton;
QPushButton *muteButton;
QPushButton *speakerButton;
QPushButton *contactsButton;
QPushButton *historyButton;
// Call state
bool inCall;
QString currentNumber;
QTimer *callTimer;
private slots:
void handleNumberClick(const QString &number);
void handleDeleteClick();
void handleCallClick();
void handleEndClick();
void updateCallDuration();
void handleIncomingCall(const QString &number);
};
4.3.2 SMS Application
SMS Implementation:
// SMS application class
class Q20SMS : public QWidget
{
Q_OBJECT
public:
Q20SMS(QWidget *parent = nullptr);
public slots:
void sendMessage(const QString &number, const QString &message);
void receiveMessage(const QString &number, const QString &message);
void showConversation(const QString &number);
void showAllConversations();
void deleteConversation(const QString &number);
private:
// UI layout
QVBoxLayout *mainLayout;
QHBoxLayout *topBar;
QSplitter *mainSplitter;
// Conversation list
QListWidget *conversationList;
QList<Q20Conversation> conversations;
// Message view
QVBoxLayout *messageLayout;
QTextEdit *messageDisplay;
QHBoxLayout *inputLayout;
QLineEdit *messageInput;
QPushButton *sendButton;
// Current conversation
QString currentNumber;
QList<Q20Message> currentMessages;
private slots:
void populateConversationList();
void handleConversationSelect(const QString &number);
void handleSendClick();
void handleMessageReceived(const QString &number, const QString &message);
void updateConversationList();
};
// Message structure
struct Q20Message {
QString id;
QString number;
QString content;
QDateTime timestamp;
bool isIncoming;
bool isRead;
};
// Conversation structure
struct Q20Conversation {
QString number;
QString name;
QString lastMessage;
QDateTime lastTimestamp;
int unreadCount;
};
4.3.3 Settings Application
Settings Implementation:
// Settings application class
class Q20Settings : public QWidget
{
Q_OBJECT
public:
Q20Settings(QWidget *parent = nullptr);
public slots:
void showGeneralSettings();
void showDisplaySettings();
void showSoundSettings();
void showNetworkSettings();
void showSecuritySettings();
void showAbout();
private:
// UI layout
QVBoxLayout *mainLayout;
QHBoxLayout *navigationLayout;
QStackedWidget *settingsStack;
// Navigation
QListWidget *settingsCategories;
QList<QString> categoryNames;
// Settings pages
Q20GeneralSettings *generalSettings;
Q20DisplaySettings *displaySettings;
Q20SoundSettings *soundSettings;
Q20NetworkSettings *networkSettings;
Q20SecuritySettings *securitySettings;
Q20AboutPage *aboutPage;
private slots:
void handleCategorySelect(int index);
void saveSettings();
void loadSettings();
};
// Display settings
class Q20DisplaySettings : public QWidget
{
Q_OBJECT
public:
Q20DisplaySettings(QWidget *parent = nullptr);
private:
QVBoxLayout *mainLayout;
// Brightness control
QHBoxLayout *brightnessLayout;
QLabel *brightnessLabel;
QSlider *brightnessSlider;
QLabel *brightnessValue;
// Backlight timeout
QHBoxLayout *timeoutLayout;
QLabel *timeoutLabel;
QComboBox *timeoutCombo;
// Keyboard backlight
QHBoxLayout *keyboardLayout;
QLabel *keyboardLabel;
QSlider *keyboardSlider;
QLabel *keyboardValue;
// Auto-rotate
QHBoxLayout *rotateLayout;
QLabel *rotateLabel;
QCheckBox *rotateCheck;
private slots:
void handleBrightnessChange(int value);
void handleTimeoutChange(const QString &timeout);
void handleKeyboardChange(int value);
void handleRotateChange(bool enabled);
};
4.4 Keyboard Navigation System
4.4.1 Keyboard Shortcuts
Shortcut Configuration:
// Keyboard shortcut manager
class Q20ShortcutManager : public QObject
{
Q_OBJECT
public:
Q20ShortcutManager(QObject *parent = nullptr);
void registerShortcut(const QString &key, const QString &action);
void unregisterShortcut(const QString &key);
void handleKeyPress(const QString &key);
private:
QHash<QString, QString> shortcuts;
QHash<QString, QShortcut*> shortcutObjects;
void setupDefaultShortcuts();
void handleShortcutAction(const QString &action);
};
// Default shortcuts
void Q20ShortcutManager::setupDefaultShortcuts()
{
// Navigation shortcuts
registerShortcut("Alt+Tab", "switch_app");
registerShortcut("Alt+F4", "close_app");
registerShortcut("Alt+Enter", "fullscreen");
registerShortcut("Alt+Space", "menu");
// Phone shortcuts
registerShortcut("Call", "dialer");
registerShortcut("End", "end_call");
registerShortcut("Menu", "app_launcher");
registerShortcut("Back", "go_back");
// System shortcuts
registerShortcut("Ctrl+Alt+Del", "task_manager");
registerShortcut("Ctrl+Alt+Backspace", "restart_ui");
registerShortcut("Ctrl+Alt+T", "terminal");
registerShortcut("Ctrl+Alt+S", "settings");
}
4.4.2 Focus Management
Focus System:
// Focus manager
class Q20FocusManager : public QObject
{
Q_OBJECT
public:
Q20FocusManager(QObject *parent = nullptr);
void setFocusWidget(QWidget *widget);
QWidget* getFocusedWidget();
void moveFocus(Qt::Key key);
void cycleFocus();
private:
QWidget *currentFocus;
QList<QWidget*> focusableWidgets;
void updateFocusableWidgets();
QWidget* findNextFocusable(QWidget *current, Qt::Key direction);
void highlightFocus(QWidget *widget);
};
// Focus movement implementation
void Q20FocusManager::moveFocus(Qt::Key key)
{
QWidget *nextWidget = nullptr;
switch (key) {
case Qt::Key_Tab:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Tab);
break;
case Qt::Key_Backtab:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Backtab);
break;
case Qt::Key_Left:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Left);
break;
case Qt::Key_Right:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Right);
break;
case Qt::Key_Up:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Up);
break;
case Qt::Key_Down:
nextWidget = findNextFocusable(currentFocus, Qt::Key_Down);
break;
}
if (nextWidget) {
setFocusWidget(nextWidget);
}
}
4.5 Trackpad Optimization
4.5.1 Trackpad Gestures
Gesture Recognition:
// Trackpad gesture manager
class Q20TrackpadManager : public QObject
{
Q_OBJECT
public:
Q20TrackpadManager(QObject *parent = nullptr);
void handleTrackpadEvent(const QPointF &position, int buttons);
void handleTrackpadGesture(const QString &gesture);
private:
QPointF lastPosition;
QPointF startPosition;
QDateTime lastEvent;
bool isTracking;
// Gesture detection
void detectSwipeGesture(const QPointF ¤t, const QPointF &start);
void detectPinchGesture(const QPointF &point1, const QPointF &point2);
void detectTapGesture(const QPointF &position);
void detectDoubleTapGesture(const QPointF &position);
// Gesture actions
void handleSwipeLeft();
void handleSwipeRight();
void handleSwipeUp();
void handleSwipeDown();
void handlePinchIn();
void handlePinchOut();
void handleTap();
void handleDoubleTap();
};
// Gesture detection implementation
void Q20TrackpadManager::detectSwipeGesture(const QPointF ¤t, const QPointF &start)
{
QPointF delta = current - start;
qreal distance = QLineF(start, current).length();
qreal angle = QLineF(start, current).angle();
// Minimum swipe distance
if (distance < 50) {
return;
}
// Determine swipe direction
if (angle >= 315 || angle < 45) {
handleSwipeRight();
} else if (angle >= 45 && angle < 135) {
handleSwipeUp();
} else if (angle >= 135 && angle < 225) {
handleSwipeLeft();
} else if (angle >= 225 && angle < 315) {
handleSwipeDown();
}
}
4.5.2 Cursor Management
Cursor System:
// Cursor manager
class Q20CursorManager : public QObject
{
Q_OBJECT
public:
Q20CursorManager(QObject *parent = nullptr);
void setCursorPosition(const QPointF &position);
void setCursorVisible(bool visible);
void setCursorShape(Qt::CursorShape shape);
void animateCursor();
private:
QPointF currentPosition;
QPointF targetPosition;
bool isVisible;
Qt::CursorShape currentShape;
// Cursor animation
QTimer *animationTimer;
qreal animationProgress;
void updateCursorPosition();
void drawCursor();
void handleAnimation();
};
// Cursor animation
void Q20CursorManager::animateCursor()
{
if (currentPosition != targetPosition) {
QPointF delta = targetPosition - currentPosition;
currentPosition += delta * 0.1; // Smooth interpolation
if (QLineF(currentPosition, targetPosition).length() < 1) {
currentPosition = targetPosition;
}
updateCursorPosition();
}
}
📊 Deliverables
4.6 Complete UI System
Requirements:
- Functional display server
- Core applications working
- Keyboard navigation system
- Trackpad optimization
- Settings and customization
4.7 Application Framework
Components:
- Qt-based application framework
- Window management system
- Input handling system
- Theme and styling system
- Plugin architecture
4.8 User Experience
Features:
- Intuitive keyboard navigation
- Efficient trackpad usage
- Consistent UI design
- Responsive interface
- Accessibility support
⏱️ Timeline
Week 1-2: Display server development Week 3-4: Application framework Week 5-6: Core applications Week 7-8: Keyboard navigation Week 9-10: Trackpad optimization Week 11-12: Testing and refinement
Total Duration: 12 weeks (3 months)
🎯 Success Criteria
Phase 4 is successful when:
- Complete UI system is functional
- Core applications are working
- Keyboard navigation is intuitive
- Trackpad gestures are responsive
- User experience is polished
🚨 Risk Mitigation
High-Risk Scenarios:
- Performance issues → Optimize rendering and input handling
- UI framework complexity → Simplify and modularize
- Keyboard navigation problems → Improve focus management
- Trackpad issues → Enhance gesture recognition
- Application bugs → Implement comprehensive testing