diff options
author | Ken Moore <ken@ixsystems.com> | 2018-01-08 14:19:58 -0500 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2018-01-08 14:19:58 -0500 |
commit | 9fe1845f0e2d75dc8a6d3d49fac6780b394b0067 (patch) | |
tree | 606fbe23fe8d0cd7311b4fe6910f5136dc9bccc8 /src-qt5/core/lumina-desktop-unified/src-desktop | |
parent | Changed color and removed comments from Matrix screensaver (diff) | |
download | lumina-9fe1845f0e2d75dc8a6d3d49fac6780b394b0067.tar.gz lumina-9fe1845f0e2d75dc8a6d3d49fac6780b394b0067.tar.bz2 lumina-9fe1845f0e2d75dc8a6d3d49fac6780b394b0067.zip |
Another large update to Lumina 2:
Starting to hook up the new QML window frame with the C++ backend.
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified/src-desktop')
15 files changed, 171 insertions, 62 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp index d6d06be9..b9ea3078 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp @@ -76,7 +76,7 @@ void DesktopManager::updateWallpaper(QString screen_id, int wkspace){ } //Now go ahead and set the wallpaper in the screen object if(wpaper.isEmpty() || wpaper=="default"){ wpaper = LOS::LuminaShare()+"desktop-background.jpg"; } //failover image - qDebug() << "Updating Wallpaper:" << screen_id << wpaper; + //qDebug() << "Updating Wallpaper:" << screen_id << wpaper; RootDesktopObject::instance()->ChangeWallpaper(screen_id,QUrl::fromLocalFile(wpaper).toString() ); } @@ -91,7 +91,7 @@ void DesktopManager::updatePlugins(QString plugin_id){ // === PUBLIC SLOTS === void DesktopManager::workspaceChanged(int wknum){ qDebug() << "Got Workspace Changed:" << wknum; - + syncWindowList(); } void DesktopManager::settingsChanged(DesktopSettings::File type){ @@ -112,6 +112,35 @@ void DesktopManager::settingsChanged(DesktopSettings::File type){ } } +void DesktopManager::NewWindowAvailable(NativeWindowObject* win){ + //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncWindowList()) ); + syncWindowList(); +} + +void DesktopManager::NewTrayWindowAvailable(NativeWindowObject* win){ + //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncTrayWindowList()) ); + syncTrayWindowList(); +} + +void DesktopManager::syncWindowList(){ + QList<NativeWindowObject*> allWins = Lumina::NWS->currentWindows(); + //Filter out all the windows not in the current workspace + QList<NativeWindowObject*> current; + QList<NativeWindowObject*> currentStacked; + int wkspace = Lumina::NWS->currentWorkspace(); + for(int i=0; i<allWins.length(); i++){ + if(allWins[i]->isSticky() || (allWins[i]->workspace() == wkspace)){ + current << allWins[i]; + } + } + //qDebug() << "Synced Window List:" << current.length(); + RootDesktopObject::instance()->setWindows(current); +} + +void DesktopManager::syncTrayWindowList(){ + +} + // === PRIVATE SLOTS === void DesktopManager::updateDesktopSettings(){ qDebug() << "Update Desktop Settings..."; @@ -136,4 +165,3 @@ void DesktopManager::updateMenuSettings(){ void DesktopManager::updateAnimationSettings(){ } - diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h index df681afa..d4a0cf79 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h @@ -30,6 +30,12 @@ public slots: void workspaceChanged(int); void settingsChanged(DesktopSettings::File); + void NewWindowAvailable(NativeWindowObject*); + void NewTrayWindowAvailable(NativeWindowObject*); + + void syncWindowList(); + void syncTrayWindowList(); + private slots: void updateDesktopSettings(); void updatePanelSettings(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp index 47f0e3d7..47f0e3d7 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.cpp diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h index 78756e8c..78756e8c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/OldContextMenu.h diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h index ba489465..9cf42f3c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h @@ -7,6 +7,7 @@ #ifndef _LUMINA_DESKTOP_ROOT_WINDOW_H #define _LUMINA_DESKTOP_ROOT_WINDOW_H #include <global-includes.h> +#include "src-cpp/RootDesktopObject.h" class RootWindow : public QObject{ Q_OBJECT diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp index a1b8dbbb..dcfd23b0 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.cpp @@ -7,6 +7,7 @@ #include "NativeWindowObject.h" #include <QQmlEngine> #include <QDebug> +#include <QBuffer> // == QML Type Registration == void NativeWindowObject::RegisterType(){ @@ -60,6 +61,16 @@ QVariant NativeWindowObject::property(NativeWindowObject::Property prop){ void NativeWindowObject::setProperty(NativeWindowObject::Property prop, QVariant val, bool force){ if(prop == NativeWindowObject::RelatedWindows){ relatedTo = val.value< QList<WId> >(); } else if(prop == NativeWindowObject::None || (!force && hash.value(prop)==val)){ return; } + else if(prop == NativeWindowObject::WinImage){ + //special case - QImage is passed in, but QString is passed out (needed for QML) + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + val.value<QImage>().save(&buffer, "PNG"); + QString img("data:image/png:base64,"); + img.append(QString::fromLatin1(ba.toBase64().data())); + hash.insert(prop, img); //save the string instead + } else{ hash.insert(prop, val); } emitSinglePropChanged(prop); emit PropertiesChanged(QList<NativeWindowObject::Property>() << prop, QList<QVariant>() << val); @@ -68,8 +79,20 @@ void NativeWindowObject::setProperty(NativeWindowObject::Property prop, QVariant void NativeWindowObject::setProperties(QList<NativeWindowObject::Property> props, QList<QVariant> vals, bool force){ for(int i=0; i<props.length(); i++){ if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property - if(props[i] == NativeWindowObject::None || (!force && (hash.value(props[i]) == vals[i])) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value - hash.insert(props[i], vals[i]); + if(props[i] == NativeWindowObject::None || (!force && (hash.value(props[i]) == vals[i])) ){ + props.removeAt(i); vals.removeAt(i); i--; continue; //Invalid property or identical value + }else if(props[i] == NativeWindowObject::WinImage){ + //special case - QImage is passed in, but QString is passed out (needed for QML) + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + vals[i].value<QImage>().save(&buffer, "PNG"); + QString img("data:image/png:base64,"); + img.append(QString::fromLatin1(ba.toBase64().data())); + hash.insert(props[i], img); //save the string instead + }else{ + hash.insert(props[i], vals[i]); + } emitSinglePropChanged(props[i]); } emit PropertiesChanged(props, vals); @@ -117,8 +140,8 @@ QRect NativeWindowObject::geometry(){ } // QML ACCESS FUNCTIONS (shortcuts for particular properties in a format QML can use) -QImage NativeWindowObject::winImage(){ - return this->property(NativeWindowObject::WinImage).value<QImage>(); +QString NativeWindowObject::winImage(){ + return this->property(NativeWindowObject::WinImage).toString(); } QString NativeWindowObject::name(){ @@ -130,7 +153,10 @@ QString NativeWindowObject::title(){ } QString NativeWindowObject::shortTitle(){ - return this->property(NativeWindowObject::ShortTitle).toString(); + QString tmp = this->property(NativeWindowObject::ShortTitle).toString(); + if(tmp.isEmpty()){ tmp = title(); } + if(tmp.isEmpty()){ tmp = name(); } + return tmp; } QIcon NativeWindowObject::icon(){ @@ -215,6 +241,10 @@ bool NativeWindowObject::isSticky(){ return (this->property(NativeWindowObject::Workspace).toInt()<0 || this->property(NativeWindowObject::States).value<QList<NativeWindowObject::State> >().contains(NativeWindowObject::S_STICKY) ); } +int NativeWindowObject::workspace(){ + return this->property(NativeWindowObject::Workspace).toInt(); +} + //QML Geometry reporting QRect NativeWindowObject::frameGeometry(){ return geometry(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h index 8a8504aa..e4f9d41e 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/NativeWindowObject.h @@ -17,7 +17,7 @@ class NativeWindowObject : public QObject{ Q_OBJECT // QML-ACCESSIBLE PROPERTIES - Q_PROPERTY( QImage winImage READ winImage NOTIFY winImageChanged) + Q_PROPERTY( QString winImage READ winImage NOTIFY winImageChanged) Q_PROPERTY( QString name READ name NOTIFY nameChanged) Q_PROPERTY( QString title READ title NOTIFY titleChanged) Q_PROPERTY( QString shortTitle READ shortTitle NOTIFY shortTitleChanged) @@ -92,7 +92,7 @@ public: Q_INVOKABLE QRect geometry(); //this returns the "full" geometry of the window (window + frame) // QML ACCESS FUNCTIONS (shortcuts for particular properties in a format QML can use) - Q_INVOKABLE QImage winImage(); + Q_INVOKABLE QString winImage(); Q_INVOKABLE QString name(); Q_INVOKABLE QString title(); Q_INVOKABLE QString shortTitle(); @@ -106,6 +106,7 @@ public: Q_INVOKABLE bool showWindowFrame(); //QML Window States Q_INVOKABLE bool isSticky(); + Q_INVOKABLE int workspace(); //QML Geometry reporting Q_INVOKABLE QRect frameGeometry(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp index 4b01fa0d..39dc30c1 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -27,6 +27,7 @@ void RootDesktopObject::RegisterType(){ qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject"); //Also register any types that are needed by this class ScreenObject::RegisterType(); + NativeWindowObject::RegisterType(); } RootDesktopObject* RootDesktopObject::instance(){ @@ -36,14 +37,14 @@ RootDesktopObject* RootDesktopObject::instance(){ //QML Read Functions QStringList RootDesktopObject::screens(){ - qDebug() << "Request Screens:" << s_objects.length(); + //qDebug() << "Request Screens:" << s_objects.length(); QStringList names; for(int i=0; i<s_objects.length(); i++){ names << s_objects[i]->name(); } return names; } ScreenObject* RootDesktopObject::screen(QString id){ - qDebug() << "Got Screen Request:" << id; + //qDebug() << "Got Screen Request:" << id; for(int i=0; i<s_objects.length(); i++){ if(s_objects[i]->name()==id){ return s_objects[i]; } } @@ -72,7 +73,7 @@ QStringList RootDesktopObject::windows(){ return names; } -NativeWindow* RootDesktopObject::window(QString id){ +NativeWindowObject* RootDesktopObject::window(QString id){ //qDebug() << "Got Panel Request:" << id; WId chk = id.toInt(); //numerical ID's in this case for(int i=0; i<window_objects.length(); i++){ @@ -86,7 +87,7 @@ void RootDesktopObject::setPanels(QList<PanelObject*> list){ emit panelsChanged(); } -void RootDesktopObject::setWindows(QList<NativeWindow*> list){ +void RootDesktopObject::setWindows(QList<NativeWindowObject*> list){ window_objects = list; emit windowsChanged(); } @@ -103,6 +104,10 @@ void RootDesktopObject::mousePositionChanged(){ emit mouseMoved(); } +void RootDesktopObject::launchApp(QString appOrPath){ + emit launchApplication(appOrPath); +} + // === PUBLIC SLOTS === void RootDesktopObject::updateScreens(){ QList<QScreen*> scrns = QApplication::screens(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h index 7d5182c4..a4236596 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -8,11 +8,8 @@ //=========================================== #ifndef _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H #define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H -#include <QObject> -#include <QList> #include <global-includes.h> - -#include "ScreenObject.h" +#include <ScreenObject.h> class RootDesktopObject : public QObject{ Q_OBJECT @@ -37,26 +34,27 @@ public: Q_INVOKABLE QStringList panels(); Q_INVOKABLE PanelObject* panel(QString id); Q_INVOKABLE QStringList windows(); - Q_INVOKABLE NativeWindow* window(QString id); - - void setPanels(QList<PanelObject*> list); - void setWindows(QList<NativeWindow*> list); + Q_INVOKABLE NativeWindowObject* window(QString id); //QML Access Functions Q_INVOKABLE void logout(); Q_INVOKABLE void lockscreen(); Q_INVOKABLE void mousePositionChanged(); + Q_INVOKABLE void launchApp(QString appOrPath); private: QList<ScreenObject*> s_objects; QList<PanelObject*> panel_objects; - QList<NativeWindow*> window_objects; + QList<NativeWindowObject*> window_objects; public slots: void updateScreens(); //rescan/update screen objects void ChangeWallpaper(QString screen, QString); QString CurrentWallpaper(QString screen); + void setPanels(QList<PanelObject*> list); + void setWindows(QList<NativeWindowObject*> list); + private slots: signals: @@ -67,6 +65,6 @@ signals: void startLogout(); void mouseMoved(); void lockScreen(); - + void launchApplication(QString); }; #endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp index 82622403..1b22c450 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -22,7 +22,7 @@ void ScreenObject::RegisterType(){ } QString ScreenObject::name(){ return bg_screen->name(); } -QString ScreenObject::background(){ qDebug() << "Got Background:" << bg_screen->name() << bg << bg_screen->geometry(); return bg; } +QString ScreenObject::background(){ return bg; } int ScreenObject::x(){ return bg_screen->geometry().x(); } int ScreenObject::y(){ return bg_screen->geometry().y(); } int ScreenObject::width(){ return bg_screen->geometry().width(); } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml index 4ab8e156..778d7568 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml @@ -13,6 +13,21 @@ import Lumina.Backend.RootDesktopObject 2.0 Menu { id: contextMenu MenuItem { + text: "Launch Terminal" + iconName: "utilities-terminal" + onTriggered: { + RootObject.launchApp("application/terminal") + } + } + MenuItem { + text: "Launch File Browser" + iconName: "user-home" + onTriggered: { + RootObject.launchApp("inode/directory") + } + } + + MenuItem { text: "Lock Screen" iconName: "system-lock-screen" onTriggered: { diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WindowFrame.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/NativeWindow.qml index b1765001..90818ca8 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WindowFrame.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/NativeWindow.qml @@ -4,17 +4,20 @@ import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -Rectangle { - id: background - color: "grey" +import Lumina.Backend.NativeWindowObject 2.0 Rectangle { + property NativeWindowObject object + property string window_id + id: windowFrame border.width: 5 - border.color: "black" - color: "white" - width: 400 - height: 300 + border.color: palette.window + color: palette.window + x: object.frameGeometry.x + y: object.frameGeometry.y + width: object.frameGeometry.width + height: object.frameGeometry.height MouseArea { id: resizeArea @@ -98,7 +101,7 @@ Rectangle { Rectangle { id: titleBar border.width: 2 - color: "black" + color: palette.window height: 25 anchors.top: windowFrame.top anchors.right: windowFrame.right @@ -107,49 +110,59 @@ Rectangle { width: parent.width RowLayout { - anchors.right: parent.right + anchors.fill: titleBar spacing: 0 + Button { + id: otherButton + anchors.left: parent.left + Layout.fillHeight: true + iconSource: windowFrame.object.icon + + } + Text { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: palette.windowText + text: windowFrame.object.shortTitle + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + //onClicked: contextMenu.open() + } + } + Button { + id: minButton + Layout.fillHeight: true iconName: "window-minimize" - //action: + onClicked: { windowFrame.object.toggleVisibility() } } Button { + id: maxButton + Layout.fillHeight: true iconName: "window-maximize" - //action: + //onClicked: { windowFrame.object.toggleMaximize() } } Button { + id: closeButton + Layout.fillHeight: true iconName: "document-close" - //action: + onClicked: { windowFrame.object.requestClose() } } } - - Button { - iconName: "emblem-synchronized" - anchors.left: parent.left - } - - Text { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - color: "white" - text: "zwelch@trueos~8905:~/lumina/src-qt5/src-qml/test" - font.pixelSize: 10 - } - - MouseArea { - acceptedButtons: Qt.RightButton - anchors.fill: parent - //onClicked: contextMenu.open() - } } Image { id: frameContents -// source: "balloon.png" + source: windowFrame.object.winImage anchors.top: titleBar.bottom anchors.bottom: parent.bottom anchors.left: windowFrame.left @@ -161,12 +174,11 @@ Rectangle { height: parent.height MouseArea { - width: parent.width; - height: parent.height; - anchors.fill: frameContents; + width: parent.width; + height: parent.height + anchors.fill: frameContents onClicked: { console.log(parent.mapToGlobal(mouse.x, mouse.y)); } } } } -} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml index c564ee42..9122ce5b 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml @@ -23,6 +23,7 @@ import "." as QML import Lumina.Backend.RootDesktopObject 2.0 import Lumina.Backend.ScreenObject 2.0 +import Lumina.Backend.NativeWindowObject 2.0 Rectangle { id: rootCanvas @@ -55,4 +56,14 @@ Rectangle { z: 0+index } } + + //Setup the windows + Repeater{ + model: RootObject.windows + QML.NativeWindow{ + window_id: modelData + object: RootObject.window(modelData) + z: 100+index + } + } } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri index ad07902a..79941b82 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri @@ -3,7 +3,8 @@ lupdate_only{ SOURCES *= $${PWD}/RootDesktop.qml \ $${PWD}/ContextMenu.qml \ $${PWD}/Screen.qml \ - $${PWD}/Panel.qml + $${PWD}/Panel.qml \ + $${PWD}/NativeWindow.qml } RESOURCES *= $${PWD}/src-qml.qrc diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc index b0c66e20..a4dc414f 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc @@ -4,5 +4,6 @@ <file>ContextMenu.qml</file> <file>Screen.qml</file> <file>Panel.qml</file> + <file>NativeWindow.qml</file> </qresource> </RCC> |