Skip to content
This repository was archived by the owner on Oct 10, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.kdev4
build
ScreenRotator.kdev4
aur/src/**
aur/pkg/**
aur/screenrotator-modified-git/**
aur/*.tar.zst
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ Similar to the current solution implemented in Gnome, but works on all other des
- Qt5 (with modules x11extras, sensors)
- xrandr
- XInput (Xi)

On ubuntu, run the following command to install dependencies:
```
sudo apt install -y git cmake build-essential qtbase5-dev libxrandr-dev libxi-dev libqt5x11extras5-dev libqt5sensors5-dev
sudo apt install -y git cmake build-essential qtbase5-dev libxrandr-dev libxi-dev libqt5x11extras5-dev libqt5sensors5-dev
```

## Building
```
git clone https://github.com/GuLinux/ScreenRotator
git clone https://github.com/pakro/ScreenRotator
mkdir ScreenRotator/build
cd ScreenRotator/build
cmake ..
Expand All @@ -31,5 +31,4 @@ sudo make install

## Links

Main icon: https://www.iconfinder.com/icons/326583/orientation_rotation_screen_icon#size=256

Main icon from https://www.onlinewebfonts.com/icon/310563
1 change: 0 additions & 1 deletion aur/.gitignore

This file was deleted.

30 changes: 14 additions & 16 deletions aur/PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
# Maintainer: Marco Gulino <marco.gulino@gmail.com>

pkgname=screenrotator-git
pkgver=r23.1a78a4b
pkgname=screenrotator-modified-git
pkgver=r45.767fa46
pkgrel=1
epoch=1
pkgdesc='Automatic screen rotation daemon for X11'
arch=('i686' 'x86_64')
url='https://github.com/GuLinux/ScreenRotator'
url='https://github.com/pakro/ScreenRotator'
license=('GPL3')
depends=('qt5-base' 'qt5-x11extras' 'libxi' 'libxrandr' 'qt5-sensors')
makedepends=('git' 'cmake' 'qt5-tools')
source=("${pkgname}::git+${url}")
sha256sums=('SKIP')

pkgver() {
cd "$pkgname"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
cd "$pkgname"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}

prepare() {
cd "$srcdir/$pkgname"
install -d build
cd "$srcdir/$pkgname"
install -d build
}

build() {
cd "$srcdir/$pkgname/build"
cmake ..\
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release
make
cd "$srcdir/$pkgname/build"
cmake ..\
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release
make
}

package() {
cd "$srcdir/$pkgname/build"
make DESTDIR="$pkgdir" install
cd "$srcdir/$pkgname/build"
make DESTDIR="$pkgdir" install
}
2 changes: 0 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
set(screenrotator_SRCS displaymanager.cpp orientationsensor.cpp trayicon.cpp rotateinput.cpp)
add_executable(screenrotator main.cpp ${screenrotator_SRCS})
configure_file(screenrotator-autostart.desktop.in screenrotator-autostart.desktop)
target_link_libraries(screenrotator Qt5::Gui Qt5::X11Extras Qt5::Sensors Qt5::Widgets Qt5::DBus Xrandr Xi X11)

install(TARGETS screenrotator RUNTIME DESTINATION bin)
install(FILES screenrotator.desktop DESTINATION share/applications)
file(GLOB ICON_DIRECTORIES resources/*x*)
install(DIRECTORY ${ICON_DIRECTORIES} resources/scalable DESTINATION share/icons/hicolor/)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/screenrotator-autostart.desktop DESTINATION /etc/xdg/autostart/)
8 changes: 3 additions & 5 deletions src/displaymanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct DisplayManagerX11Mediator {
XRRScreenConfiguration *screenConfiguration;
Rotation rotation;
SizeID configurationId;

DisplayManagerX11Mediator();
~DisplayManagerX11Mediator();
bool setRotation(Rotation rotation);
Expand Down Expand Up @@ -75,7 +75,7 @@ Orientation DisplayManager::Private::to_orientation(Rotation rotation)
if(orientation2rotation[key] == rotation)
return key;
// TODO: fallback value?
return Orientation::LeftUp;
return Orientation::TopUp;
}


Expand All @@ -84,7 +84,6 @@ DisplayManager::DisplayManager(QObject* parent) : QObject{parent}, d{new Private
{
DisplayManagerX11Mediator mediator;
d->currentOrientation = d->to_orientation(mediator.rotation);
qDebug() << "Current orientation: " << d->currentOrientation << ", rotation: " << mediator.rotation;
}

DisplayManager::~DisplayManager()
Expand All @@ -95,8 +94,7 @@ void DisplayManager::setOrientation(Orientation orientation)
{
DisplayManagerX11Mediator mediator;
auto rotation = orientation2rotation[orientation];
if(mediator.rotation == rotation)
return;
mediator.setRotation(rotation);
d->currentOrientation = orientation;
qDebug() << "Current orientation: " << d->currentOrientation << ", rotation: " << mediator.rotation;
}
6 changes: 4 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ int main(int argc, char *argv[])
TrayIcon tray;
OrientationSensor sensor;
RotateInput rotateInput;
QObject::connect(&sensor, &OrientationSensor::reading, &displayManager, &DisplayManager::setOrientation);
QObject::connect(&sensor, &OrientationSensor::reading, &rotateInput, &RotateInput::rotate);
QObject::connect(&sensor, &OrientationSensor::reading, &tray, &TrayIcon::orientationUpdated);
QObject::connect(&tray, &TrayIcon::emitRotation, &displayManager, &DisplayManager::setOrientation);
QObject::connect(&tray, &TrayIcon::emitRotation, &rotateInput, &RotateInput::rotate);

return app.exec();
}
Binary file added src/resources/1024x1024/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/128x128/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/16x16/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/192x192/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/20x20/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/22x22/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/24x24/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/256x256/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/resources/28x28/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/32x32/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/36x36/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/384x384/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/40x40/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/48x48/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/512x512/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/64x64/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/72x72/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/80x80/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/8x8/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/resources/96x96/apps/screenrotator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/resources/create_icons
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ for size in $( ls /usr/share/icons/hicolor | grep x | grep -v index ); do
size_x="${size%%x*}"
size_y="${size##*x}"
mkdir -p "$size"/apps
inkscape -z -e "$size/apps/screenrotator.png" -w $size_x -h "$size_y" scalable/apps/screenrotator.svg
inkscape --export-filename="$size/apps/screenrotator.png" -w $size_x -h "$size_y" scalable/apps/screenrotator.svg
done
50 changes: 49 additions & 1 deletion src/resources/scalable/apps/screenrotator.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 21 additions & 15 deletions src/rotateinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct InputProperty {
Atom type;
int format;
QString name;

bool isRotationMatrix() const;
void setRotationMatrix(const vector<float> &matrix);
};
Expand All @@ -56,7 +56,7 @@ InputDevice::InputDevice(XIDeviceInfo* info, Display *display) : display{display
id = info->deviceid;
for(int j=0; j<info->num_classes; j++) {
if(info->classes[j]->type == XITouchClass) {
qDebug() << "Device" << info->name << "seems to be a touchscreen device";
qDebug() << "Device" << info->name << "has touchscreen functionality";
isTouchScreen = true;
}
}
Expand Down Expand Up @@ -90,7 +90,7 @@ InputProperty::InputProperty(int deviceId, Display* display, Atom atom) : device
if(XIGetProperty(display, deviceId, atom, 0, 0, False, AnyPropertyType, &property_type, &property_format, &items_count, &bytes_after, &data) == Success) {
type = property_type;
format = property_format;
qDebug() << "Property name=" << name << ", atom=" << atom << ", format=" << format << ", type=" << type;
//qDebug() << "Property name=" << name << ", atom=" << atom << ", format=" << format << ", type=" << type;
XFree(data);
} else {
qDebug() << "Unable to get data for property " << name;
Expand Down Expand Up @@ -128,27 +128,34 @@ class RotateInput::Private {
RotateInput::RotateInput(QObject* parent) : QObject{parent}, d{new Private}
{
d->display = QX11Info::display();
this->scanForTouchDevices();
//for(auto device: d->devices) {
// for(auto property: device.properties()) {
// qDebug() << "Device" << device.name << ", property:" << property.name << ", atom=" << property.atom << ", type: " << property.type;
// }
//}
}
RotateInput::~RotateInput()
{
}

void RotateInput::scanForTouchDevices()
{
d->devices.clear();
int devices;
XIDeviceInfo *deviceInfo = XIQueryDevice(d->display, XIAllDevices, &devices);
for(int i=0; i<devices; i++) {
InputDevice device{&deviceInfo[i], d->display};
if(device.hasRotationMatrix)
d->devices.push_back(device);
if(device.name.startsWith("Wacom Pen") || device.name.startsWith("Goodix Capacitive"))
d->devices.push_back(device);
}
XIFreeDeviceInfo(deviceInfo);

for(auto device: d->devices) {
for(auto property: device.properties()) {
qDebug() << "Device" << device.name << ", property:" << property.name << ", atom=" << property.atom << ", type: " << property.type;
}
}
}
RotateInput::~RotateInput()
{
}

void RotateInput::rotate(Orientation orientation)
{
this->scanForTouchDevices();
#ifdef USE_XINPUT
static QHash<Orientation, QStringList> orientation_matrix_map {
{TopUp, {"1", "0", "0", "0", "1", "0", "0", "0", "1"}},
Expand All @@ -168,11 +175,10 @@ void RotateInput::rotate(Orientation orientation)
{RightUp, {0, 1, 0, -1, 0, 1, 0, 0, 1}},
};
auto orientation_matrix = orientation_matrix_map[orientation];
qDebug() << "Setting rotation matrix: " << orientation_matrix;
for(auto device: d->devices) {
for(auto property: device.properties()) {
if(property.isRotationMatrix()) {
qDebug() << "Changing orientation matrix for device " << device.name << ", property " << property.name;
qDebug() << "Changing orientation matrix for device" << device.name << "using matrix" << orientation_matrix;
property.setRotationMatrix(orientation_matrix);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/rotateinput.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public slots:
private:
class Private;
std::unique_ptr<Private> d;
void scanForTouchDevices();
};

#endif // ROTATEINPUT_H
6 changes: 0 additions & 6 deletions src/screenrotator-autostart.desktop.in

This file was deleted.

67 changes: 65 additions & 2 deletions src/trayicon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,88 @@
#include <QTimer>
#include <QMenu>
#include <QApplication>
#include <QDebug>
#include <QProcessEnvironment>

using namespace std;
class TrayIcon::Private {
public:
QSystemTrayIcon tray;
unique_ptr<QMenu> menu;
Orientation lastOrientation;
bool hasLastOrientation;
bool autoRotating;
};

#define APP_NAME tr("Screen Rotator")
#define APP_ICON QIcon::fromTheme("screenrotator")

TrayIcon::TrayIcon(QObject* parent) : QObject{parent}, d{new Private}
{
d->tray.setIcon(QIcon::fromTheme("screenrotator"));
d->tray.setIcon(APP_ICON);
d->menu.reset(new QMenu());
d->tray.setToolTip(tr("Screen Rotator"));
d->tray.setToolTip(APP_NAME);

connect(&d->tray, &QSystemTrayIcon::activated, this, &TrayIcon::activated);
connect(&d->tray, &QSystemTrayIcon::messageClicked, this, &TrayIcon::messageClicked);

d->tray.setContextMenu(d->menu.get());
d->menu->addAction(tr("Rotate"), this, &TrayIcon::emitRotationIfHas);
d->menu->addAction(tr("Toggle auto-rotation"), this, &TrayIcon::toggleAutoRotating);
d->menu->addAction(tr("Quit"), qApp, &QApplication::quit);
d->hasLastOrientation = false;

QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
d->autoRotating = !env.contains("DEFAULT_AUTO_ROTATION_OFF");
QTimer::singleShot(100, &d->tray, &QSystemTrayIcon::show);
}

TrayIcon::~TrayIcon()
{
}

void TrayIcon::setAutoRotating(bool autoRotating)
{
d->autoRotating = autoRotating;
if (d->autoRotating) {
d->tray.showMessage(APP_NAME, tr("Auto-rotation enabled"), APP_ICON, 3000);
} else {
d->tray.showMessage(APP_NAME, tr("Auto-rotation disabled"), APP_ICON, 3000);
}
}

void TrayIcon::toggleAutoRotating()
{
this->setAutoRotating(!d->autoRotating);
}

void TrayIcon::orientationUpdated(Orientation orientation)
{
d->lastOrientation = orientation;
d->hasLastOrientation = true;
if (d->autoRotating) {
this->emitRotationIfHas();
} else {
d->tray.showMessage(APP_NAME, tr("Orientaion change detected, click tray icon to rotate"), APP_ICON, 3000);
qApp->processEvents();
}
}

void TrayIcon::activated(QSystemTrayIcon::ActivationReason reason)
{
this->emitRotationIfHas();
}

void TrayIcon::messageClicked()
{
this->emitRotationIfHas();
}

void TrayIcon::emitRotationIfHas()
{
if (d->hasLastOrientation) {
emit this->emitRotation(d->lastOrientation);
} else {
d->tray.showMessage(APP_NAME, tr("No orientaion change detected, try rotate the devise again"), APP_ICON, 5000);
}
}
Loading