aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarstrom <john@ankarstrom.se>2021-06-29 22:32:29 +0200
committerJohn Ankarstrom <john@ankarstrom.se>2021-06-29 23:51:47 +0200
commit78002152b346b17d268df4d4a6b2ca1c669f21f9 (patch)
tree5774c180d32afda111a71c9efef7af43dbe89ad8
parent98a074417fb9ac157c32d637123b6eaae19239f9 (diff)
downloadjwm-78002152b346b17d268df4d4a6b2ca1c669f21f9.tar.gz
Place new windows at cursor position
I guess it would be better if there were an option that controlled this.
-rw-r--r--src/move.c75
-rw-r--r--src/move.h5
-rw-r--r--src/place.c101
3 files changed, 128 insertions, 53 deletions
diff --git a/src/move.c b/src/move.c
index 882ac90..7370f06 100644
--- a/src/move.c
+++ b/src/move.c
@@ -530,6 +530,81 @@ void DoSnapBorder(ClientNode *np, int north, int west) {
/****************************************************************************
****************************************************************************/
+void ReturnToBorder(ClientNode *np, int north, int west) {
+
+ const ScreenType *screen;
+ const TrayType *tray;
+ int layer;
+ RectangleType bottom = { 0 };
+ RectangleType client, other;
+ RectangleType left = { 0 };
+ RectangleType right = { 0 };
+ RectangleType top = { 0 };
+
+ GetClientRectangle(np, &client);
+ screen = GetCurrentScreen(client.left, client.top);
+
+ /* Check screen boundaries. */
+ if(client.right > (screen->width - screen->x))
+ np->x = screen->x + screen->width - west - np->width;
+ if(client.left < screen->x)
+ np->x = screen->x + west;
+ if(client.bottom > (screen->height - screen->y)) {
+ np->y = screen->y + screen->height - west;
+ if(!(np->state.status & STAT_SHADED))
+ np->y -= np->height;
+ }
+ if(client.top < screen->y)
+ np->y = north + screen->y;
+
+ GetClientRectangle(np, &client);
+ other.valid = 1;
+
+ /* Work from the bottom of the window stack to the top. */
+ for(layer = 0; layer < LAYER_COUNT; layer++) {
+
+ /* Check tray windows. */
+ for(tray = GetTrays(); tray; tray = tray->next) {
+
+ if(tray->hidden)
+ continue;
+
+ other.left = tray->x;
+ other.right = tray->x + tray->width;
+ other.top = tray->y;
+ other.bottom = tray->y + tray->height;
+
+ left.valid = CheckLeftValid(&client, &other, &left);
+ right.valid = CheckRightValid(&client, &other, &right);
+ top.valid = CheckTopValid(&client, &other, &top);
+ bottom.valid = CheckBottomValid(&client, &other, &bottom);
+
+ if(other.top == screen->y
+ && client.top < other.bottom)
+ top = other;
+ if(other.bottom == screen->height
+ && client.bottom > other.top)
+ bottom = other;
+ }
+
+ }
+
+ if(right.valid)
+ np->x = right.left - np->width - west;
+ if(left.valid)
+ np->x = left.right + west;
+ if(bottom.valid) {
+ np->y = bottom.top - west;
+ if(!(np->state.status & STAT_SHADED))
+ np->y -= np->height;
+ }
+ if(top.valid)
+ np->y = top.bottom + north;
+
+}
+
+/****************************************************************************
+ ****************************************************************************/
int ShouldSnap(const ClientNode *np) {
if(np->state.status & STAT_HIDDEN) {
return 0;
diff --git a/src/move.h b/src/move.h
index 8a737ff..0922a07 100644
--- a/src/move.h
+++ b/src/move.h
@@ -57,5 +57,10 @@ void SetDefaultSnapDistance();
*/
void SetMoveMode(MoveModeType mode);
+/** Make the client return to the screen/tray bounds.
+ * @param mode The client node to affect.
+ */
+void ReturnToBorder(struct ClientNode *np, int north, int west);
+
#endif
diff --git a/src/place.c b/src/place.c
index f70ce73..cad5d96 100644
--- a/src/place.c
+++ b/src/place.c
@@ -8,6 +8,7 @@
#include "client.h"
#include "screen.h"
#include "border.h"
+#include "move.h"
#include "tray.h"
#include "main.h"
@@ -26,9 +27,12 @@ typedef struct Strut {
static Strut *struts = NULL;
static Strut *strutsTail = NULL;
+static int prevx = -1;
+static int prevy = -1;
+static int offset = 0;
+
/* desktopCount x screenCount */
/* Note that we assume x and y are 0 based for all screens here. */
-static int *cascadeOffsets = NULL;
static void GetScreenBounds(const ScreenType *sp, BoundingBox *box);
static void UpdateTrayBounds(BoundingBox *box, unsigned int layer);
@@ -43,17 +47,6 @@ void InitializePlacement() {
/****************************************************************************
****************************************************************************/
void StartupPlacement() {
-
- int count;
- int x;
-
- count = desktopCount * GetScreenCount();
- cascadeOffsets = Allocate(count * sizeof(int));
-
- for(x = 0; x < count; x++) {
- cascadeOffsets[x] = borderWidth + titleHeight;
- }
-
}
/****************************************************************************
@@ -62,8 +55,6 @@ void ShutdownPlacement() {
Strut *sp;
- Release(cascadeOffsets);
-
while(struts) {
sp = struts->next;
Release(struts);
@@ -374,10 +365,11 @@ void UpdateStrutBounds(BoundingBox *box) {
void PlaceClient(ClientNode *np, int alreadyMapped) {
BoundingBox box;
- int north, south, east, west;
const ScreenType *sp;
- int cascadeIndex;
- int overflow;
+ int height, overflow, width, winx, winy, x, y;
+ int north, south, east, west;
+ unsigned int mask;
+ Window rootReturn, childReturn;
Assert(np);
@@ -403,47 +395,50 @@ void PlaceClient(ClientNode *np, int alreadyMapped) {
UpdateTrayBounds(&box, np->state.layer);
UpdateStrutBounds(&box);
- cascadeIndex = sp->index * desktopCount + currentDesktop;
-
- /* Set the cascaded location. */
- np->x = box.x + west + cascadeOffsets[cascadeIndex];
- np->y = box.y + north + cascadeOffsets[cascadeIndex];
- cascadeOffsets[cascadeIndex] += borderWidth + titleHeight;
-
- /* Check for cascade overflow. */
- overflow = 0;
- if(np->x + np->width - box.x > box.width) {
- overflow = 1;
- } else if(np->y + np->height - box.y > box.height) {
- overflow = 1;
+ /* Check cursor location. */
+ JXQueryPointer(display, rootWindow, &rootReturn, &childReturn,
+ &x, &y, &winx, &winy, &mask);
+
+ if(prevx > -1
+ && prevy > -1
+ && (abs(x - prevx) <= borderWidth
+ || abs(y - prevy) <= borderWidth)) {
+ offset += borderWidth + titleHeight;
+ } else {
+ offset = 0;
+ prevx = x;
+ prevy = y;
}
- if(overflow) {
-
- cascadeOffsets[cascadeIndex] = borderWidth + titleHeight;
- np->x = box.x + west + cascadeOffsets[cascadeIndex];
- np->y = box.y + north + cascadeOffsets[cascadeIndex];
-
- /* Check for client overflow. */
- overflow = 0;
- if(np->x + np->width - box.x > box.width) {
- overflow = 1;
- } else if(np->y + np->height - box.y > box.height) {
- overflow = 1;
- }
-
- /* Update cascade position or position client. */
- if(overflow) {
- np->x = box.x + west;
- np->y = box.y + north;
- } else {
- cascadeOffsets[cascadeIndex] += borderWidth + titleHeight;
- }
-
+ /* Show window at cursor. */
+ width = np->width;
+ height = np->height;
+ if(np->state.border & BORDER_OUTLINE) {
+ x += borderWidth;
+ y += borderWidth;
+ width += borderWidth * 2;
+ height += borderWidth * 2;
}
-
+ if(np->state.border & BORDER_TITLE) {
+ y += titleHeight;
+ height += titleHeight;
+ }
+ x -= width / 2;
+ y -= height / 2;
+ np->x = x + offset;
+ np->y = y + offset;
+
+ /* Correct for overflow. */
+ /*
+ if(np->x + np->width - box.x > box.width)
+ np->x = box.width - (np->width - box.x);
+ if(np->y + np->height - box.y > box.height)
+ np->y = box.height - (np->height - box.y);
+ */
+ ReturnToBorder(np, north, west);
}
+
if(np->state.status & STAT_FULLSCREEN) {
JXMoveWindow(display, np->parent, sp->x, sp->y);
} else {