mirror of
https://github.com/gryf/wmaker.git
synced 2026-03-26 15:03:34 +01:00
Compare commits
12 Commits
a383074c99
...
038a3588d6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
038a3588d6 | ||
|
|
0b2fd6a8c8 | ||
|
|
3e991badf7 | ||
|
|
ac6d284269 | ||
|
|
83b94b1616 | ||
|
|
d045ffcf7d | ||
|
|
6c69dc32a0 | ||
|
|
3b1c00ad06 | ||
|
|
dd6fe27858 | ||
|
|
45f3f5d0ae | ||
|
|
7185af15cf | ||
|
|
80e8dd43f7 |
28
NEWS
28
NEWS
@@ -1,7 +1,32 @@
|
||||
NEWS for veteran Window Maker users
|
||||
-----------------------------------
|
||||
|
||||
-- 0.95.10
|
||||
-- 0.96.0
|
||||
|
||||
Screenshot capture feature
|
||||
--------------------------
|
||||
|
||||
In WPrefs "Keyboard Shortcut Preferences" tab, three new actions can
|
||||
be configured: "Capture a portion of the screen", "Capture a window",
|
||||
"Capture the entire screen". The file is saved in
|
||||
~/GNUstep/Library/WindowMaker/Screenshots directory under a filename
|
||||
format "screenshot_%Y-%m-%d_at_%H:%M:%S" followed by the extension.
|
||||
Which can be png or jpg based on WRaster dependencies.
|
||||
|
||||
|
||||
libXRes is now an optional dependency
|
||||
-------------------------------------
|
||||
|
||||
XRes the resource extension for the X protocol is used to find the
|
||||
underlying processes (and PIDs) responsible for displaying the windows.
|
||||
|
||||
|
||||
Support for _NET_WM_FULLSCREEN_MONITORS hint
|
||||
--------------------------------------------
|
||||
|
||||
That hint allows applications that support it to be set as fullscreen on multiple heads.
|
||||
It depends on Xinerama extension support.
|
||||
|
||||
|
||||
Keep dock on primary head
|
||||
-------------------------
|
||||
@@ -10,6 +35,7 @@ To keep the dock on the primary head in a multi-head setup, set the option
|
||||
"KeepDockOnPrimaryHead" in ~/GNUstep/Defaults/WindowMaker to "YES" or click
|
||||
"Keep dock on primary head" under the WPrefs "Expert User Preferences" tab.
|
||||
|
||||
|
||||
-- 0.95.9
|
||||
|
||||
Configurable SwitchPanel
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Changes since wmaker 0.95.10:
|
||||
Changes since wmaker 0.96.0:
|
||||
............................
|
||||
|
||||
- added W_KeycodeToKeysym to replace XKeycodeToKeysym/XkbKeycodeToKeysym calls
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
** API and ABI modifications since wmaker 0.95.10
|
||||
** API and ABI modifications since wmaker 0.96.0
|
||||
----------------------------------------------------
|
||||
|
||||
** libWINGs **
|
||||
|
||||
@@ -17,4 +17,5 @@ wtest_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.la
|
||||
EXTRA_DIST = logo.xpm upbtn.xpm wm.html wm.png
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/WINGs -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \
|
||||
-DRESOURCE_PATH=\"$(datadir)/WINGs\" @XFT_CFLAGS@ @HEADER_SEARCH_PATH@
|
||||
-DRESOURCE_PATH=\"$(datadir)/WINGs\" @XFT_CFLAGS@ @HEADER_SEARCH_PATH@ \
|
||||
@PANGO_CFLAGS@
|
||||
|
||||
@@ -64,6 +64,7 @@ static W_Class myWidgetClass = 0;
|
||||
*/
|
||||
W_Class InitMyWidget(WMScreen * scr)
|
||||
{
|
||||
(void)scr;
|
||||
/* register our widget with WINGs and get our widget class ID */
|
||||
if (!myWidgetClass) {
|
||||
myWidgetClass = W_RegisterUserWidget();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "mywidget.h"
|
||||
|
||||
void wAbort()
|
||||
_Noreturn void wAbort(void)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
#include "logo.xpm"
|
||||
|
||||
void wAbort()
|
||||
_Noreturn void wAbort(void)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *ProgName;
|
||||
|
||||
void usage(void)
|
||||
_Noreturn void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage:\n"
|
||||
@@ -53,13 +53,10 @@ int main(int argc, char **argv)
|
||||
WMPixmap *pixmap;
|
||||
WMOpenPanel *oPanel;
|
||||
WMSavePanel *sPanel;
|
||||
/* RImage *image; */
|
||||
char *title = NULL;
|
||||
char *initial = "/";
|
||||
int ch;
|
||||
int panelType = OPEN_PANEL_TYPE;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
if (!dpy) {
|
||||
puts("could not open display");
|
||||
@@ -96,14 +93,14 @@ int main(int argc, char **argv)
|
||||
if (panelType == SAVE_PANEL_TYPE) {
|
||||
sPanel = WMGetSavePanel(scr);
|
||||
if (WMRunModalFilePanelForDirectory(sPanel, NULL, initial,
|
||||
/*title */ NULL, NULL) == True)
|
||||
title, NULL) == True)
|
||||
printf("%s\n", WMGetFilePanelFileName(sPanel));
|
||||
else
|
||||
printf("\n");
|
||||
} else {
|
||||
oPanel = WMGetOpenPanel(scr);
|
||||
if (WMRunModalFilePanelForDirectory(oPanel, NULL, initial,
|
||||
/*title */ NULL, NULL) == True)
|
||||
title, NULL) == True)
|
||||
printf("%s\n", WMGetFilePanelFileName(oPanel));
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
#include "logo.xpm"
|
||||
|
||||
void wAbort()
|
||||
_Noreturn void wAbort(void)
|
||||
{
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *ProgName;
|
||||
|
||||
void usage(void)
|
||||
_Noreturn void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage:\n"
|
||||
@@ -45,8 +45,6 @@ int main(int argc, char **argv)
|
||||
char *initial = NULL;
|
||||
char *result = NULL;
|
||||
int ch;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
WMInitializeApplication("WMQuery", &argc, argv);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* This will be called when the application will be terminated because
|
||||
* of a fatal error (only for memory allocation failures ATM).
|
||||
*/
|
||||
void wAbort()
|
||||
_Noreturn void wAbort(void)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ int windowCount = 0;
|
||||
|
||||
void closeAction(WMWidget * self, void *data)
|
||||
{
|
||||
(void)data;
|
||||
WMDestroyWidget(self);
|
||||
windowCount--;
|
||||
printf("window closed, window count = %d\n", windowCount);
|
||||
@@ -165,10 +166,13 @@ void testBox(WMScreen * scr)
|
||||
|
||||
static void singleClick(WMWidget * self, void *data)
|
||||
{
|
||||
(void)self;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void doubleClick(WMWidget * self, void *data)
|
||||
{
|
||||
(void)data;
|
||||
WMSelectAllListItems((WMList *) self);
|
||||
}
|
||||
|
||||
@@ -480,6 +484,7 @@ void testColorPanel(WMScreen * scr)
|
||||
|
||||
void sliderCallback(WMWidget * w, void *data)
|
||||
{
|
||||
(void)data;
|
||||
printf("SLIDER == %i\n", WMGetSliderValue(w));
|
||||
}
|
||||
|
||||
@@ -749,6 +754,8 @@ void testTabView(WMScreen * scr)
|
||||
|
||||
void splitViewConstrainProc(WMSplitView * sPtr, int indView, int *minSize, int *maxSize)
|
||||
{
|
||||
(void)sPtr;
|
||||
|
||||
switch (indView) {
|
||||
case 0:
|
||||
*minSize = 20;
|
||||
@@ -782,6 +789,7 @@ static void resizeSplitView(XEvent * event, void *data)
|
||||
|
||||
void appendSubviewButtonAction(WMWidget * self, void *data)
|
||||
{
|
||||
(void)self;
|
||||
WMSplitView *sPtr = (WMSplitView *) data;
|
||||
char buf[64];
|
||||
WMLabel *label = WMCreateLabel(sPtr);
|
||||
@@ -796,6 +804,7 @@ void appendSubviewButtonAction(WMWidget * self, void *data)
|
||||
|
||||
void removeSubviewButtonAction(WMWidget * self, void *data)
|
||||
{
|
||||
(void)self;
|
||||
WMSplitView *sPtr = (WMSplitView *) data;
|
||||
int count = WMGetSplitViewSubviewsCount(sPtr);
|
||||
|
||||
@@ -808,12 +817,14 @@ void removeSubviewButtonAction(WMWidget * self, void *data)
|
||||
|
||||
void orientationButtonAction(WMWidget * self, void *data)
|
||||
{
|
||||
(void)self;
|
||||
WMSplitView *sPtr = (WMSplitView *) data;
|
||||
WMSetSplitViewVertical(sPtr, !WMGetSplitViewVertical(sPtr));
|
||||
}
|
||||
|
||||
void adjustSubviewsButtonAction(WMWidget * self, void *data)
|
||||
{
|
||||
(void)self;
|
||||
WMAdjustSplitViewSubviews((WMSplitView *) data);
|
||||
}
|
||||
|
||||
@@ -902,7 +913,7 @@ void testSplitView(WMScreen * scr)
|
||||
WMMapWidget(win);
|
||||
}
|
||||
|
||||
void testUD()
|
||||
void testUD(void)
|
||||
{
|
||||
WMUserDefaults *defs;
|
||||
char str[32];
|
||||
|
||||
@@ -226,10 +226,7 @@ KeySym W_KeycodeToKeysym(Display *display, KeyCode keycode, int index)
|
||||
KeySym *key_syms;
|
||||
KeySym ks;
|
||||
|
||||
if (min_kc == -1) {
|
||||
(void) XDisplayKeycodes(display, &min_kc, &max_kc);
|
||||
}
|
||||
|
||||
XDisplayKeycodes(display, &min_kc, &max_kc);
|
||||
if (keycode < min_kc || keycode > max_kc || index < 0) {
|
||||
return NoSymbol;
|
||||
}
|
||||
|
||||
@@ -166,12 +166,15 @@ typedef struct W_Text {
|
||||
WMArray *xdndDestinationTypes;
|
||||
} Text;
|
||||
|
||||
/* not used */
|
||||
#if 0
|
||||
#define NOTIFY(T,C,N,A) {\
|
||||
WMNotification *notif = WMCreateNotification(N,T,A);\
|
||||
if ((T)->delegate && (T)->delegate->C)\
|
||||
(*(T)->delegate->C)((T)->delegate,notif);\
|
||||
WMPostNotification(notif);\
|
||||
WMReleaseNotification(notif);}
|
||||
#endif
|
||||
|
||||
#define TYPETEXT 0
|
||||
|
||||
|
||||
@@ -395,7 +395,11 @@ static void setWindowMakerHints(WMWindow * win)
|
||||
|
||||
memset(&attribs, 0, sizeof(GNUstepWMAttributes));
|
||||
attribs.flags = GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr;
|
||||
|
||||
if (win->minSize.width == win->maxSize.width && win->minSize.height == win->maxSize.height)
|
||||
win->flags.style &= ~WMResizableWindowMask;
|
||||
attribs.window_style = win->flags.style;
|
||||
|
||||
attribs.window_level = win->level;
|
||||
if (win->flags.documentEdited)
|
||||
attribs.extra_flags = GSDocumentEditedFlag;
|
||||
|
||||
@@ -158,7 +158,10 @@ static struct keyOption {
|
||||
{ "RunKey", N_("Run application") },
|
||||
{ "ExitKey", N_("Exit Window Maker") },
|
||||
{ "DockRaiseLowerKey", N_("Raise/Lower Dock") },
|
||||
{ "ClipRaiseLowerKey", N_("Raise/Lower Clip") }
|
||||
{ "ClipRaiseLowerKey", N_("Raise/Lower Clip") },
|
||||
{ "ScreenCaptureKey", N_("Capture the entire screen") },
|
||||
{ "WindowCaptureKey", N_("Capture a window") },
|
||||
{ "PartialCaptureKey", N_("Capture a portion of the screen") }
|
||||
#ifdef XKB_MODELOCK
|
||||
,{ "ToggleKbdModeKey", N_("Toggle keyboard language") }
|
||||
#endif /* XKB_MODELOCK */
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
static char *magick[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"50 40 95 2",
|
||||
" c Gray0",
|
||||
" c #000000",
|
||||
". c #010101",
|
||||
"X c Gray2",
|
||||
"X c #050505",
|
||||
"o c #040406",
|
||||
"O c #070707",
|
||||
"+ c #0a0a0d",
|
||||
@@ -20,14 +20,14 @@ static char *magick[] = {
|
||||
": c #4e4e4e",
|
||||
"> c #505055",
|
||||
", c #585858",
|
||||
"< c Gray37",
|
||||
"< c #5e5e5e",
|
||||
"1 c #494d62",
|
||||
"2 c #545066",
|
||||
"3 c #57556f",
|
||||
"4 c #5d627c",
|
||||
"5 c #604e42",
|
||||
"6 c Gray39",
|
||||
"7 c Gray41",
|
||||
"6 c #636363",
|
||||
"7 c #696969",
|
||||
"8 c #646475",
|
||||
"9 c #7e6a63",
|
||||
"0 c #75746d",
|
||||
@@ -67,36 +67,36 @@ static char *magick[] = {
|
||||
"D c #989799",
|
||||
"F c #9b9b9b",
|
||||
"G c #999e98",
|
||||
"H c Gray62",
|
||||
"H c #9e9e9e",
|
||||
"J c #9e9f9f",
|
||||
"K c #8d8cba",
|
||||
"L c #9995a0",
|
||||
"P c #a2a2a3",
|
||||
"I c #a7a7a8",
|
||||
"U c Gray66",
|
||||
"U c #a8a8a8",
|
||||
"Y c #acacac",
|
||||
"T c Gray68",
|
||||
"R c Gray69",
|
||||
"T c #adadad",
|
||||
"R c #b0b0b0",
|
||||
"E c #b2b2b2",
|
||||
"W c #b4b4b4",
|
||||
"Q c Gray71",
|
||||
"Q c #b5b5b5",
|
||||
"! c #b9b9b9",
|
||||
"~ c Gray73",
|
||||
"~ c #bababa",
|
||||
"^ c #bbbbbb",
|
||||
"/ c #a7a7c5",
|
||||
"( c #acadcf",
|
||||
") c #c0c0c0",
|
||||
"_ c #c3c3c3",
|
||||
"` c #c8c8c8",
|
||||
"' c Gray79",
|
||||
"] c Gray80",
|
||||
"' c #c9c9c9",
|
||||
"] c #cccccc",
|
||||
"[ c #dfdfdf",
|
||||
"{ c #e2e2e2",
|
||||
"} c Gray91",
|
||||
"} c #e8e8e8",
|
||||
"| c #e9e9e9",
|
||||
" . c Gray95",
|
||||
" . c #f2f2f2",
|
||||
".. c #fbfbfb",
|
||||
"X. c Gray100",
|
||||
"X. c #ffffff",
|
||||
/* pixels */
|
||||
"$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } ",
|
||||
"$ 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 } } } } } } } } ",
|
||||
|
||||
@@ -233,6 +233,9 @@
|
||||
ScreenSwitchKey = None;
|
||||
RunKey = None;
|
||||
ExitKey = None;
|
||||
ScreenCaptureKey = Print;
|
||||
WindowCaptureKey = None;
|
||||
PartialCaptureKey = None;
|
||||
NormalCursor = (builtin, left_ptr);
|
||||
ArrowCursor = (builtin, top_left_arrow);
|
||||
MoveCursor = (builtin, fleur);
|
||||
|
||||
@@ -6,9 +6,9 @@ static char *magick[] = {
|
||||
". c #ededee",
|
||||
"X c #e7e7e7",
|
||||
"o c #e2e2e2",
|
||||
"O c gray87",
|
||||
"+ c gray85",
|
||||
"@ c gray76",
|
||||
"O c #dedede",
|
||||
"+ c #d9d9d9",
|
||||
"@ c #c2c2c2",
|
||||
"# c #010101",
|
||||
"$ c #4d505a",
|
||||
"% c #e0e0e6",
|
||||
|
||||
@@ -119,6 +119,7 @@ typedef enum {
|
||||
WCUR_QUESTION,
|
||||
WCUR_TEXT,
|
||||
WCUR_SELECT,
|
||||
WCUR_CAPTURE,
|
||||
WCUR_ROOT,
|
||||
WCUR_EMPTY,
|
||||
|
||||
|
||||
@@ -790,6 +790,12 @@ WDefaultEntry optionList[] = {
|
||||
NULL, getKeybind, setKeyGrab, NULL, NULL},
|
||||
{"ExitKey", "None", (void *)WKBD_EXIT,
|
||||
NULL, getKeybind, setKeyGrab, NULL, NULL},
|
||||
{"ScreenCaptureKey", "None", (void *)WKBD_PRINTS,
|
||||
NULL, getKeybind, setKeyGrab, NULL, NULL},
|
||||
{"WindowCaptureKey", "None", (void *)WKBD_PRINTW,
|
||||
NULL, getKeybind, setKeyGrab, NULL, NULL},
|
||||
{"PartialCaptureKey", "None", (void *)WKBD_PRINTP,
|
||||
NULL, getKeybind, setKeyGrab, NULL, NULL},
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
{"ToggleKbdModeKey", "None", (void *)WKBD_TOGGLE,
|
||||
@@ -826,6 +832,8 @@ WDefaultEntry optionList[] = {
|
||||
NULL, getCursor, setCursor, NULL, NULL},
|
||||
{"SelectCursor", "(builtin, cross)", (void *)WCUR_SELECT,
|
||||
NULL, getCursor, setCursor, NULL, NULL},
|
||||
{"CaptureCursor", "(builtin, crosshair)", (void *)WCUR_CAPTURE,
|
||||
NULL, getCursor, setCursor, NULL, NULL},
|
||||
{"DialogHistoryLines", "500", NULL,
|
||||
&wPreferences.history_lines, getInt, NULL, NULL, NULL},
|
||||
{"CycleActiveHeadOnly", "NO", NULL,
|
||||
|
||||
18
src/event.c
18
src/event.c
@@ -1863,6 +1863,24 @@ static void handleKeyPress(XEvent * event)
|
||||
break;
|
||||
}
|
||||
|
||||
case WKBD_PRINTS:
|
||||
{
|
||||
ScreenCapture(scr, PRINT_SCREEN);
|
||||
break;
|
||||
}
|
||||
|
||||
case WKBD_PRINTW:
|
||||
{
|
||||
ScreenCapture(scr, PRINT_WINDOW);
|
||||
break;
|
||||
}
|
||||
|
||||
case WKBD_PRINTP:
|
||||
{
|
||||
ScreenCapture(scr, PRINT_PARTIAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case WKBD_NEXTWSLAYER:
|
||||
case WKBD_PREVWSLAYER:
|
||||
{
|
||||
|
||||
@@ -148,6 +148,15 @@ enum {
|
||||
/* open "exit" dialog */
|
||||
WKBD_EXIT,
|
||||
|
||||
/* screen print */
|
||||
WKBD_PRINTS,
|
||||
|
||||
/* window print */
|
||||
WKBD_PRINTW,
|
||||
|
||||
/* partial print */
|
||||
WKBD_PRINTP,
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
WKBD_TOGGLE,
|
||||
#endif
|
||||
|
||||
@@ -393,7 +393,7 @@ Bool RelaunchWindow(WWindow *wwin)
|
||||
} else if (pid < 0) {
|
||||
werror("cannot fork a new process");
|
||||
|
||||
wfree(argv);
|
||||
wtokenfree(argv, argc);
|
||||
wfree(command);
|
||||
return False;
|
||||
} else {
|
||||
@@ -405,7 +405,7 @@ Bool RelaunchWindow(WWindow *wwin)
|
||||
/* not actually a shell command */
|
||||
wAddDeathHandler(pid, shellCommandHandler, data);
|
||||
|
||||
wfree(argv);
|
||||
wtokenfree(argv, argc);
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
250
src/screen.c
250
src/screen.c
@@ -24,6 +24,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
@@ -54,10 +58,12 @@
|
||||
#include "geomview.h"
|
||||
#include "wmspec.h"
|
||||
#include "rootmenu.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "xinerama.h"
|
||||
|
||||
#include <WINGs/WUtil.h>
|
||||
#include <WINGs/WINGsP.h>
|
||||
|
||||
#include "defaults.h"
|
||||
|
||||
@@ -593,6 +599,7 @@ static void createInternalWindows(WScreen * scr)
|
||||
scr->workspace_name =
|
||||
XCreateWindow(dpy, scr->root_win, 0, 0, 10, 10, 0, scr->w_depth,
|
||||
CopyFromParent, scr->w_visual, vmask, &attribs);
|
||||
scr->mini_screenshot_timeout = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1126,3 +1133,246 @@ int wScreenKeepInside(WScreen * scr, int *x, int *y, int width, int height)
|
||||
|
||||
return moved;
|
||||
}
|
||||
|
||||
static XImage *imageCaptureArea(WScreen *scr)
|
||||
{
|
||||
XEvent event;
|
||||
int quit = 0;
|
||||
int xp = -1;
|
||||
int yp = -1;
|
||||
int w = 0, h = 0;
|
||||
int x = xp, y = yp;
|
||||
|
||||
if (XGrabPointer(dpy, scr->root_win, False, ButtonMotionMask
|
||||
| ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
|
||||
GrabModeAsync, None, wPreferences.cursor[WCUR_CAPTURE], CurrentTime) != Success) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XGrabServer(dpy);
|
||||
|
||||
while (!quit) {
|
||||
WMMaskEvent(dpy, ButtonReleaseMask | PointerMotionMask | ButtonPressMask | KeyPressMask, &event);
|
||||
|
||||
switch (event.type) {
|
||||
case ButtonPress:
|
||||
if (event.xbutton.button == Button1) {
|
||||
xp = event.xbutton.x_root;
|
||||
yp = event.xbutton.y_root;
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (event.xbutton.button == Button1) {
|
||||
quit = 1;
|
||||
if (w > 0 && h > 0) {
|
||||
XDrawRectangle(dpy, scr->root_win, scr->frame_gc, x, y, w, h);
|
||||
XUngrabServer(dpy);
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
return XGetImage(dpy, scr->root_win, x, y, w, h, AllPlanes, ZPixmap);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionNotify:
|
||||
XDrawRectangle(dpy, scr->root_win, scr->frame_gc, x, y, w, h);
|
||||
x = event.xmotion.x_root;
|
||||
if (x < xp) {
|
||||
w = xp - x;
|
||||
} else {
|
||||
w = x - xp;
|
||||
x = xp;
|
||||
}
|
||||
y = event.xmotion.y_root;
|
||||
if (y < yp) {
|
||||
h = yp - y;
|
||||
} else {
|
||||
h = y - yp;
|
||||
y = yp;
|
||||
}
|
||||
XDrawRectangle(dpy, scr->root_win, scr->frame_gc, x, y, w, h);
|
||||
break;
|
||||
case KeyPress:
|
||||
if (W_KeycodeToKeysym(dpy, event.xkey.keycode, 0) == XK_Escape)
|
||||
quit = 1;
|
||||
break;
|
||||
default:
|
||||
WMHandleEvent(&event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XUngrabServer(dpy);
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hideMiniScreenshot(void *data)
|
||||
{
|
||||
WScreen *scr = (WScreen *) data;
|
||||
|
||||
if (time(NULL) < scr->mini_screenshot_timeout) {
|
||||
scr->mini_screenshot_timer = WMAddTimerHandler(WORKSPACE_NAME_FADE_DELAY, hideMiniScreenshot, scr);
|
||||
} else {
|
||||
XWindowAttributes attr;
|
||||
|
||||
WMDeleteTimerHandler(scr->mini_screenshot_timer);
|
||||
if (XGetWindowAttributes(dpy, scr->mini_screenshot, &attr))
|
||||
slide_window(scr->mini_screenshot, attr.x, attr.y, attr.x + attr.width, attr.y);
|
||||
XUnmapWindow(dpy, scr->mini_screenshot);
|
||||
XDestroyWindow(dpy, scr->mini_screenshot);
|
||||
scr->mini_screenshot_timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void showMiniScreenshot(WScreen *scr, RImage *img)
|
||||
{
|
||||
Pixmap pix;
|
||||
int x = scr->scr_width - img->width - 20;
|
||||
int y = scr->scr_height - img->height - 20;
|
||||
|
||||
if (!scr->mini_screenshot_timeout) {
|
||||
Window win;
|
||||
|
||||
win = XCreateSimpleWindow(dpy, scr->root_win, x, y,
|
||||
img->width, img->height, scr->frame_border_width, 0, 0);
|
||||
scr->mini_screenshot = win;
|
||||
}
|
||||
RConvertImage(scr->rcontext, img, &pix);
|
||||
XMapWindow(dpy, scr->mini_screenshot);
|
||||
XCopyArea(dpy, pix, scr->mini_screenshot, scr->rcontext->copy_gc, 0, 0, img->width, img->height, 0, 0);
|
||||
XFlush(dpy);
|
||||
|
||||
scr->mini_screenshot_timeout = time(NULL) + 2;
|
||||
scr->mini_screenshot_timer = WMAddTimerHandler(WORKSPACE_NAME_FADE_DELAY, hideMiniScreenshot, scr);
|
||||
}
|
||||
|
||||
void ScreenCapture(WScreen *scr, int mode)
|
||||
{
|
||||
time_t s;
|
||||
short i = 0;
|
||||
struct tm *tm_info;
|
||||
char index_str[12] = "";
|
||||
char filename_date_part[60];
|
||||
char filename[60];
|
||||
char *filepath;
|
||||
char *screenshot_dir;
|
||||
RImage *img = NULL;
|
||||
RImage *scale_img = NULL;
|
||||
|
||||
#ifdef USE_PNG
|
||||
char *filetype = ".png";
|
||||
#else
|
||||
#ifdef USE_JPEG
|
||||
char *filetype = ".jpg";
|
||||
#else
|
||||
char *filetype = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!filetype) {
|
||||
werror(_("Unable to find a proper screenshot image format"));
|
||||
return;
|
||||
}
|
||||
|
||||
screenshot_dir = wstrconcat(wusergnusteppath(), "/Library/WindowMaker/Screenshots/");
|
||||
if (-1 == mkdir(screenshot_dir, 0700) && errno != EEXIST) {
|
||||
wfree(screenshot_dir);
|
||||
werror(_("Unable to create screenshot directory: %s"), strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
s = time(NULL);
|
||||
tm_info = localtime(&s);
|
||||
strftime(filename_date_part, sizeof(filename_date_part), "screenshot_%Y-%m-%d_at_%H:%M:%S", tm_info);
|
||||
strcpy(filename, filename_date_part);
|
||||
|
||||
filepath = wstrconcat(screenshot_dir, strcat(filename, filetype));
|
||||
while (access(filepath, F_OK) == 0 && i < 600) {
|
||||
i++;
|
||||
strcpy(filename, filename_date_part);
|
||||
sprintf(index_str, "_%d", i);
|
||||
strncat(filename, index_str, sizeof(filename) - strlen(filename) - 1);
|
||||
wfree(filepath);
|
||||
filepath = wstrconcat(screenshot_dir, strcat(filename, filetype));
|
||||
}
|
||||
|
||||
/* cannot generate an available filename ?! */
|
||||
if (i == 600) {
|
||||
wfree(filepath);
|
||||
wfree(screenshot_dir);
|
||||
werror(_("Could not generate a free screenshot filename"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case PRINT_WINDOW:
|
||||
WWindow *wwin = scr->focused_window;
|
||||
if (wwin && !wwin->flags.shaded) {
|
||||
/*
|
||||
* check if hint WM_TAKE_FOCUS is set, if it's the case
|
||||
* we can take screenshot of the out of screen window
|
||||
*/
|
||||
if (wwin->focus_mode >= WFM_LOCALLY_ACTIVE) {
|
||||
img = RCreateImageFromDrawable(scr->rcontext, wwin->client_win, None);
|
||||
}
|
||||
else {
|
||||
/* we will only capture the visible window part */
|
||||
XImage *pimg;
|
||||
int x_crop = 0;
|
||||
int y_crop = 0;
|
||||
int w_crop = wwin->client.width;
|
||||
int h_crop = wwin->client.height;
|
||||
|
||||
if (wwin->client.x > 0)
|
||||
x_crop = wwin->client.x;
|
||||
if (wwin->client.y > 0)
|
||||
y_crop = wwin->client.y;
|
||||
|
||||
if (wwin->client.x + wwin->client.width > scr->scr_width)
|
||||
w_crop = scr->scr_width - wwin->client.x;
|
||||
if (wwin->client.y + wwin->client.height > scr->scr_height)
|
||||
h_crop = scr->scr_height - wwin->client.y;
|
||||
|
||||
pimg = XGetImage(dpy, scr->root_win, x_crop, y_crop,
|
||||
(wwin->client.x > 0)?w_crop:w_crop + wwin->client.x,
|
||||
(wwin->client.y > 0)?h_crop:h_crop + wwin->client.y,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
if (pimg) {
|
||||
img = RCreateImageFromXImage(scr->rcontext, pimg, None);
|
||||
XDestroyImage(pimg);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PRINT_PARTIAL:
|
||||
XImage *pimg;
|
||||
|
||||
pimg = imageCaptureArea(scr);
|
||||
if (pimg) {
|
||||
img = RCreateImageFromXImage(scr->rcontext, pimg, None);
|
||||
XDestroyImage(pimg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* PRINT_SCREEN*/
|
||||
img = RCreateImageFromDrawable(scr->rcontext, scr->root_win, None);
|
||||
}
|
||||
|
||||
if (img) {
|
||||
#ifdef USE_PNG
|
||||
if (RSaveTitledImage(img, filepath, (char *)(filetype + 1), "Screenshot from Window Maker")) {
|
||||
#else
|
||||
if (RSaveTitledImage(img, filepath, (char *)(filetype + 1), "Screenshot from Window Maker")) {
|
||||
#endif
|
||||
scale_img = RSmoothScaleImage(img, scr->scr_width / 10, scr->scr_height / 10);
|
||||
showMiniScreenshot(scr, scale_img);
|
||||
RReleaseImage(scale_img);
|
||||
#ifdef DEBUG
|
||||
wmessage("screenshot filepath: %s", filepath);
|
||||
#endif
|
||||
}
|
||||
RReleaseImage(img);
|
||||
}
|
||||
wfree(filepath);
|
||||
wfree(screenshot_dir);
|
||||
}
|
||||
|
||||
10
src/screen.h
10
src/screen.h
@@ -27,6 +27,9 @@
|
||||
|
||||
#include <WINGs/WUtil.h>
|
||||
|
||||
#define PRINT_SCREEN 1
|
||||
#define PRINT_WINDOW 2
|
||||
#define PRINT_PARTIAL 3
|
||||
|
||||
typedef struct {
|
||||
WMRect *screens;
|
||||
@@ -271,6 +274,11 @@ typedef struct _WScreen {
|
||||
WMHandlerID *workspace_name_timer;
|
||||
struct WorkspaceNameData *workspace_name_data;
|
||||
|
||||
/* mini screenshot data */
|
||||
Window mini_screenshot;
|
||||
time_t mini_screenshot_timeout;
|
||||
WMHandlerID *mini_screenshot_timer;
|
||||
|
||||
/* for raise-delay */
|
||||
WMHandlerID *autoRaiseTimer;
|
||||
Window autoRaiseWindow; /* window that is scheduled to be
|
||||
@@ -314,7 +322,7 @@ void wScreenRestoreState(WScreen *scr);
|
||||
|
||||
int wScreenBringInside(WScreen *scr, int *x, int *y, int width, int height);
|
||||
int wScreenKeepInside(WScreen *scr, int *x, int *y, int width, int height);
|
||||
|
||||
void ScreenCapture(WScreen *scr, int mode);
|
||||
|
||||
/* in startup.c */
|
||||
WScreen *wScreenWithNumber(int i);
|
||||
|
||||
@@ -392,9 +392,7 @@ static pid_t execCommand(WScreen *scr, char *command)
|
||||
execvp(argv[0], args);
|
||||
exit(111);
|
||||
}
|
||||
while (argc > 0)
|
||||
wfree(argv[--argc]);
|
||||
wfree(argv);
|
||||
wtokenfree(argv, argc);
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -493,6 +493,7 @@ void StartUp(Bool defaultScreenOnly)
|
||||
wPreferences.cursor[WCUR_QUESTION] = XCreateFontCursor(dpy, XC_question_arrow);
|
||||
wPreferences.cursor[WCUR_TEXT] = XCreateFontCursor(dpy, XC_xterm); /* odd name??? */
|
||||
wPreferences.cursor[WCUR_SELECT] = XCreateFontCursor(dpy, XC_cross);
|
||||
wPreferences.cursor[WCUR_CAPTURE] = XCreateFontCursor(dpy, XC_crosshair);
|
||||
|
||||
Pixmap cur = XCreatePixmap(dpy, DefaultRootWindow(dpy), 16, 16, 1);
|
||||
GC gc = XCreateGC(dpy, cur, 0, NULL);
|
||||
|
||||
@@ -158,6 +158,7 @@ static void changeImage(WSwitchPanel *panel, int idecks, int selected, Bool dim,
|
||||
color.red = WMRedComponentOfColor(panel->gray) >> 8;
|
||||
color.green = WMGreenComponentOfColor(panel->gray) >> 8;
|
||||
color.blue = WMBlueComponentOfColor(panel->gray) >> 8;
|
||||
color.alpha = 255;
|
||||
RFillImage(back, &color);
|
||||
}
|
||||
|
||||
|
||||
@@ -379,8 +379,14 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
WMAddToPLArray(RMenu, L1Menu);
|
||||
|
||||
printf("%s", WMGetPropListDescription(RMenu, True));
|
||||
puts("");
|
||||
wfree(tmp);
|
||||
wfree(theme_paths);
|
||||
wfree(style_paths);
|
||||
wfree(icon_paths);
|
||||
|
||||
tmp = WMGetPropListDescription(RMenu, True);
|
||||
printf("%s\n", tmp);
|
||||
wfree(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -451,7 +457,7 @@ static void find_and_write(const char *group, char *list[][2], int this_is_termi
|
||||
WMAddToPLArray(L2Menu, L3Menu);
|
||||
wfree(t);
|
||||
}
|
||||
wfree(argv);
|
||||
wtokenfree(argv, argc);
|
||||
i++;
|
||||
}
|
||||
if (L2Menu)
|
||||
@@ -504,7 +510,7 @@ noreturn void print_help(int print_usage, int exitval)
|
||||
{
|
||||
printf("Usage: %s [-h] [-v]\n", prog_name);
|
||||
if (print_usage) {
|
||||
puts("Writes a menu structure usable as ~/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/WMRootMenu to stdout");
|
||||
puts("Writes a menu structure usable as ~/" GSUSER_SUBDIR "/" DEFAULTS_SUBDIR "/WMRootMenu to stdout");
|
||||
puts("");
|
||||
puts(" -h, --help display this help and exit");
|
||||
puts(" -v, --version output version information and exit");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
** API and ABI modifications
|
||||
----------------------------------------------------
|
||||
Since wmaker 0.96.0
|
||||
|
||||
Sat 25 Feb 2023
|
||||
|
||||
|
||||
Reference in New Issue
Block a user