I am trying to figure out how to detect which Taskbar button was clicked. Specifically, I want to write a script that makes it possible to maximize a window by double-clicking its Taskbar button. That requires knowing which Taskbar button was clicked, which I am having a difficult time finding any leads on.
Does anyone know how this can be accomplished?
That's a though one I have to admit. I can't offer you a best practice solution, but here is a little work around, maybe that enough for your purposes:
CoordMode, Mouse, Screen
~LButton::
If (A_TimeSincePriorHotkey<400) and (A_PriorHotkey="~LButton") {
WinGetPos, taskBarX, taskBarY, taskBarW, taskBarH, ahk_class Shell_TrayWnd
MouseGetPos, mouseX, mouseY
If (mouseX >= taskBarX && mouseY >= taskBarY && mouseX <= taskBarX+taskBarW && mouseY <= taskBarY+taskBarH)
OnDoubleClickTaskbar()
}
Return
OnDoubleClickTaskbar() {
;WinWaitNotActive, ahk_class Shell_TrayWnd
Sleep, 200
WinMaximize, A
}
Tested on Windows 8.1.
Related
I meet two problems, I searched, but they seems not so easy as I think.
I'm working on ubuntu-18.04 with qt-5.15.x. And my two problems are:
cannot restore my window after maximizing it.
cannot move my window out of my screen with mouse dragging
Can not restore
Firstly, I set my window frameless, and then using a button standing for maximize or restoreoperations to trigger maximization or normal
// set fremeless in contruction
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
// maximaization slot or restore
void WindowTitle::onButtonMaxClicked()
{
QWidget *pWin = window();
if(pWin->isMaximized())
{
pWin->showNormal();
}
else
{
pWin->showMaximized();
}
}
What I expected is when I click button ,window will maximized, and that is true indeed. Then clicking on button again, window will return original position and size again, but that doesn't happen, instead, window's height is correct, but its width is equal screen(getting rid of applications docker bar), x-axis value is wrong too. And I have tried setGeometry after I have stored its value, but failed.
Can not move outside
I can make sure that I have set correct position with
void WindowTitle::mouseMoveEvent(QMouseEvent *event)
{
if (m_isPressed)
{
QPoint movePoint = event->globalPos() - m_startMovePos;
QPoint widgetPos = QApplication::activeWindow()->pos();
m_startMovePos = event->globalPos();
QApplication::activeWindow()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
}
return QWidget::mouseMoveEvent(event);
}
function, but the result shows something wrong.
I have searched above two questions. But get nothing. And I'm curious that other applications can do just right both restore and move, suchlike Firefox web browser(which I'm typing on). So, there must be some way to make it work.
Pressing on Qml Button with mouse or finger(on touch enabled device) and moving too much will not emit pressAndHold() signal.
pressAndHold()
This signal is emitted when the button is interactively pressed and
held down by the user via touch or mouse.
Moving very few pixels would emit pressAndHold() signal but it seems the threshold is very small and it is very apparent problem on touch enabled device where finger naturally moves a little when pressing on button. Therefore pressAndHold() signal would not be emitted reliably.
Solution:
Set startDragDistance property to higher than default value(10)
QGuiApplication::styleHints()->setStartDragDistance(100);
Explanation:
Looking at the QQuickAbstractButton source code one can find method:
void QQuickAbstractButtonPrivate::handleMove(const QPointF &point)
void QQuickAbstractButtonPrivate::handleMove(const QPointF &point)
{
Q_Q(QQuickAbstractButton);
QQuickControlPrivate::handleMove(point);
setMovePoint(point);
q->setPressed(keepPressed || q->contains(point));
if (!pressed && autoRepeat)
stopPressRepeat();
else if (holdTimer > 0 && (!pressed || QLineF(pressPoint, point).length() > QGuiApplication::styleHints()->startDragDistance()))
stopPressAndHold();
}
When distance from starting point to moved point is greater than QGuiApplication::styleHints()->startDragDistance() threshold stopPressAndHold() is called cancelling press and hold action.
there is a question confuse me a few days, that is how can I limit mouse cursor into a rectangle in Qt environment? And my OS is ubuntu 12.04, so Windows API ClipCursor() doesn't work. thank you very much.
this involving QGraphicsItem::itemChange(). If you have an item which you want to restrict to a certain area then reimplement itemChange() for that item and monitor QGraphicsItem::ItemPositionHasChanged changes to see whether the items wants to be placed outside your area of interest and prevent that by returning a position from inside that area. for example:
QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
switch (change) {
case ItemPositionHasChanged:
if(x() < -200 || y() < -200 || x() > 200 || y() > 200)
setPos(0, 0);
graph->itemMoved();
break;
default:
break;
};
return QGraphicsItem::itemChange(change, value);
}
If you don't have an item but rather want to force a user to click within the area then hide the mouse pointer (by setting it to a blank shape), create a dedicated item that will serve as a cursor, optionally grab the mouse to that shape and then use itemChange() like I described earlier.
first, sorry for my poor english !
I want to make the cursor on the screen become invisible after it has stopped moving for 10s. I think this problem can be solved easily if there is a signal like positionChanged(QPoint lastPos , QPoint currentPos) existed,lastPos means the last position of the cursor (hot spot) of the primary screen in global screen coordinates, currentPos means the current position, this signal should be emitted once the cursor stopped moving .Note the Mouse move events here should occur even when a mouse button is not pressed down, i.e. there is mouse tracking with cursor.In Qt, mouse tracking could be enabled with QWidget::setMouseTracking(), however my problem is not restricted to Qt, it is system wide, I want to do this on Windows now ,anyone knows how to enable mouse tracking here ?
any other solution is also welcome !
You can use an event filter to see if a mouse moved:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
qDebug() << (QString("Moved! (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
}
return false;
}
and install it in your MainWindow or so:
qApp->installEventFilter(this);
Then, make a 10 second timer which gets reset when the mouse moves (and makes the cursor visible again). To make the mouse cursor vanish, you can call this when your timer runs out:
QApplication::setOverrideCursor(Qt::BlankCursor);
To make the cursor visible again, call:
QApplication::restoreOverrideCursor()
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
mouseOver="scroller_mouseOver(event)"
height="308" width="110">
As seen above, I have a Spark List with the MouseOver event:
protected function scroller_mouseOver(e:MouseEvent):void {
CursorManager.removeAllCursors(); // Remove all previous Cursors
if (mouseX > 24 && mouseX < 143) {
if (mouseY > 220) {
CursorManager.setCursor(downCursorSymbol); // Down Cursor
} else if (mouseY < 87) {
CursorManager.setCursor(upCursorSymbol); // Up Cursor
}
// Scroll as its Mouse Overed
this.addEventListener(Event.ENTER_FRAME, scrollViaY);
}
}
private function scrollViaY(e:Event):void {
if (mouseX > 24 && mouseX < 143) {
if (mouseY > 220) {
this.layout.verticalScrollPosition += (mouseY - 220)*0.5;
}
else if (mouseY < 87) {
this.layout.verticalScrollPosition += (mouseY -86)*0.5;
}
}
}
The following picture describes the area I would like to track hovering.
The Problem: When I hover the upper (red) part of the List (I would like to have the List scroll downward, the higher the mouse position is, the faster it should scroll). Similarly, If the mouse hovers over the bottom (red) part, the List scrolls upwards, and the lower the mouse is hovered, the faster the list would scroll. The current code does work - Though, the trace outs make it obvious that:
this.layout.verticalScrollPosition += (mouseY - 220)*0.5;
or
this.layout.verticalScrollPosition += (mouseY -86)*0.5;
...are giving jumping effects, is there a way to make these values change more linearly or smoother?
I created an AnimateProperty, but that works well only if I would like to scroll to a selectedIndex, In this case, I would like the scroller to keep scrolling linearly as the mouse is hovered to a particular red area, and increase in speed when I scroll to either extremity.
The Objective: While the mouse is over the Bottom (red part )of the List, the verticalScrollPosition scrolls faster as it gets farther than the center of the ticket list... yet there is jumping effect going on, I suppose due to the EnterFrame. the Same with Upper Part... the higher the cursor is, the faster the List should scroll.
I feel this is a common problem to Flash CSx developers.
I have implemented something similar, except it was a horizontal scrolling list, and also I used a scroll left/right buttons on the sides of the list, the mouse_over effect is triggered by the buttons, not the list (but this shouldn't be an impediment when adapting the code).
To do the actual scrolling, I used an animate effect which targeted the list's layout, and more specifically, the layout's horizontalScrollPosition. This it what the MXML code looks like:
<s:Animate id="scrollAnimation" target="{listLayout}">
<s:easer>
<s:Linear easeInFraction="0" easeOutFraction="0" />
</s:easer>
<s:SimpleMotionPath id="scrollMotionPath" property="horizontalScrollPosition" />
</s:Animate>
That easer is necessary because animate effect usually have 3 motion stages (acceleration, uniform motion and deceleration), so by default you would get a wavy scrolling motion.
I used RobotLeft for that project, so the view is mediated like this:
When the mediator is registered, add the scroll button listeners:
viewComponent.scrollLeft.addEventListener(MouseEvent.MOUSE_OVER, onScrollLeft);
viewComponent.scrollRight.addEventListener(MouseEvent.MOUSE_OVER, onScrollRight);
viewComponent.scrollLeft.addEventListener(MouseEvent.MOUSE_OUT, onScrollOut);
viewComponent.scrollRight.addEventListener(MouseEvent.MOUSE_OUT, onScrollOut);
We also need to add a listener so we can tell when the scrolling effect finished, because we might need to replay it:
viewComponent.scrollEffect.addEventListener(EffectEvent.EFFECT_END, onScrollEnd);
We can now implement the scrolling method. Since the view is mediated, we have access to the scroll effect, we can reference it here (and also the path). This what the method looks like:
private function scrollOnlineFriendsList(scrollBy:int):void
{
// Set the scrollBy value and play the scrolling effect
viewComponent.scrollMotionPath.valueBy = scrollBy;
viewComponent.scrollEffect.play();
// Store the scrollBy value in case the effect will need to be replayed,
// if the mouse over event is still over the scrolling button/area
this.scrollBy = scrollBy;
canKeepScrolling = true;
}
Finally, the handlers:
private function onScrollLeft(event:MouseEvent):void
{
scrollOnlineFriendsList(-33);
}
private function onScrollRight(event:MouseEvent):void
{
scrollOnlineFriendsList(33);
}
private function onScrollOut(event:MouseEvent):void
{
canKeepScrolling = false;
// If you would like the effect to continue playing
// until it finishes the current scrolling operation,
// once the mouse is no longer over a scroll button,
// just comment this line
viewComponent.scrollEffect.stop();
}
private function onScrollEnd(event:EffectEvent):void
{
// When the scroll effect has finished playing,
// if the mouse is still over the scroll button/area,
// replay the effect
if (canKeepScrolling)
scrollOnlineFriendsList(scrollBy);
}